Keep It Simple, Stupid

简单 快乐 追求

Maven 源码分析 (一)

| Comments

开篇


Main 函数在哪里?


我们先看看apache-maven-3.1.1下mvn脚本,源文件在mvn

看到该文件的最后

1
2
3
4
5
6
7
8
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher

exec "$JAVACMD" \
  $MAVEN_OPTS \
  -classpath "${M2_HOME}"/boot/plexus-classworlds-*.jar \
  "-Dclassworlds.conf=${M2_HOME}/bin/m2.conf" \
  "-Dmaven.home=${M2_HOME}"  \
  ${CLASSWORLDS_LAUNCHER} "$@"

可以看到这里用到了plexus-classworlds 类加载框架,启动maven的Laucher#main

源文件参考m2.conf

1
2
3
4
5
6
7
8
9
10
main is org.apache.maven.cli.MavenCli from plexus.core

// 注释掉 // set maven.home default ${user.home}/m2

set maven.home default /Users/yangtao/maven-tutorial/apache-maven-3.1.1

[plexus.core]
optionally ${maven.home}/lib/ext/*.jar
load       ${maven.home}/lib/*.jar
load       ${maven.home}/conf/logging

在这里,我们可以试着通过debug代码来逐步了解。 本文的案例是在intellij里面操作的,那么我们需要在启动Laucher.main()的时候,设置部分参数;

图二

Alt text

下面我来仔细看看Laucher.main()做了什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main( String[] args )
    {
        try
        {
           // 1
            int exitCode = mainWithExitCode( args );

            System.exit( exitCode );
        }
        catch ( Exception e )
        {
            e.printStackTrace();

            System.exit( 100 );
        }
    }

标记为1处,处理传入参数并返回退出代码,我们细致的来看下mainWithExitCode做了什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static int mainWithExitCode( String[] args )
        throws Exception
    {
        String classworldsConf = System.getProperty( CLASSWORLDS_CONF );
      
      // 此处省略读classworlds_conf参数的处理
        // 1
        launcher.configure( is );

        is.close();

        try
        {
            // 2
            launcher.launch( args );
        }
        catch ( InvocationTargetException e )
        {
            ClassRealm realm = launcher.getWorld().getRealm( launcher.getMainRealmName() );

            URL[] constituents = realm.getURLs();

            // 省略 异常处理细节
            // Else just toss the ITE
            throw e;
        }

        return launcher.getExitCode();
    }

标记1处,读m2.conf的配置文件,并进行解析。

标记2处,反射调用MavenCli.main(),去执行mvn相关的命令。

下一篇文章主要介绍plexus-classworlds是怎么来解析配置并调用指定主函数的?Maven 源码分析 (二)

Comments