开篇
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()的时候,设置部分参数;
图二
下面我来仔细看看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 源码分析 (二)