1 package org.apache.maven.it;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.PrintStream;
28 import java.lang.reflect.Constructor;
29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31 import java.net.MalformedURLException;
32 import java.net.URL;
33 import java.net.URLClassLoader;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Properties;
37
38
39
40
41
42
43 class Embedded3xLauncher
44 implements MavenLauncher
45 {
46
47 private final Object mavenCli;
48
49 private final Method doMain;
50
51 public Embedded3xLauncher( String mavenHome )
52 throws LauncherException
53 {
54 if ( mavenHome == null || mavenHome.length() <= 0 )
55 {
56 throw new LauncherException( "Invalid Maven home directory " + mavenHome );
57 }
58
59 System.setProperty( "maven.home", mavenHome );
60
61 File config = new File( mavenHome, "bin/m2.conf" );
62
63 ClassLoader bootLoader = getBootLoader( mavenHome );
64
65 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
66 Thread.currentThread().setContextClassLoader( bootLoader );
67 try
68 {
69 Class launcherClass = bootLoader.loadClass( "org.codehaus.plexus.classworlds.launcher.Launcher" );
70
71 Object launcher = launcherClass.newInstance();
72
73 Method configure = launcherClass.getMethod( "configure", new Class[]{ InputStream.class } );
74
75 configure.invoke( launcher, new Object[]{ new FileInputStream( config ) } );
76
77 Method getWorld = launcherClass.getMethod( "getWorld", null );
78 Object classWorld = getWorld.invoke( launcher, null );
79
80 Method getMainClass = launcherClass.getMethod( "getMainClass", null );
81 Class cliClass = (Class) getMainClass.invoke( launcher, null );
82
83 Constructor newMavenCli = cliClass.getConstructor( new Class[]{ classWorld.getClass() } );
84 mavenCli = newMavenCli.newInstance( new Object[]{ classWorld } );
85
86 Class[] parameterTypes = { String[].class, String.class, PrintStream.class, PrintStream.class };
87 doMain = cliClass.getMethod( "doMain", parameterTypes );
88 }
89 catch ( ClassNotFoundException e )
90 {
91 throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
92 }
93 catch ( InstantiationException e )
94 {
95 throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
96 }
97 catch ( IllegalAccessException e )
98 {
99 throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
100 }
101 catch ( NoSuchMethodException e )
102 {
103 throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
104 }
105 catch ( InvocationTargetException e )
106 {
107 throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
108 }
109 catch ( IOException e )
110 {
111 throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
112 }
113 finally
114 {
115 Thread.currentThread().setContextClassLoader( oldClassLoader );
116 }
117 }
118
119 private static ClassLoader getBootLoader( String mavenHome )
120 {
121 File bootDir = new File( mavenHome, "boot" );
122
123 List urls = new ArrayList();
124
125 addUrls( urls, bootDir );
126
127 if ( urls.isEmpty() )
128 {
129 throw new IllegalArgumentException( "Invalid Maven home directory " + mavenHome );
130 }
131
132 URL[] ucp = (URL[]) urls.toArray( new URL[urls.size()] );
133
134 return new URLClassLoader( ucp, ClassLoader.getSystemClassLoader().getParent() );
135 }
136
137 private static void addUrls( List urls, File directory )
138 {
139 File[] jars = directory.listFiles();
140
141 if ( jars != null )
142 {
143 for ( int i = 0; i < jars.length; i++ )
144 {
145 File jar = jars[i];
146
147 if ( jar.getName().endsWith( ".jar" ) )
148 {
149 try
150 {
151 urls.add( jar.toURI().toURL() );
152 }
153 catch ( MalformedURLException e )
154 {
155 throw (RuntimeException) new IllegalStateException().initCause( e );
156 }
157 }
158 }
159 }
160 }
161
162 public int run( String[] cliArgs, String workingDirectory, File logFile )
163 throws IOException, LauncherException
164 {
165 PrintStream out = ( logFile != null ) ? new PrintStream( new FileOutputStream( logFile ) ) : System.out;
166 try
167 {
168 Properties originalProperties = System.getProperties();
169 System.setProperties( null );
170 System.setProperty( "maven.home", originalProperties.getProperty( "maven.home", "" ) );
171 System.setProperty( "user.dir", new File( workingDirectory ).getAbsolutePath() );
172
173 ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
174 Thread.currentThread().setContextClassLoader( mavenCli.getClass().getClassLoader() );
175 try
176 {
177 Object result = doMain.invoke( mavenCli, new Object[]{ cliArgs, workingDirectory, out, out } );
178
179 return ( (Number) result ).intValue();
180 }
181 finally
182 {
183 Thread.currentThread().setContextClassLoader( originalClassLoader );
184
185 System.setProperties( originalProperties );
186 }
187 }
188 catch ( IllegalAccessException e )
189 {
190 throw new LauncherException( "Failed to run Maven: " + e.getMessage(), e );
191 }
192 catch ( InvocationTargetException e )
193 {
194 throw new LauncherException( "Failed to run Maven: " + e.getMessage(), e );
195 }
196 finally
197 {
198 if ( logFile != null )
199 {
200 out.close();
201 }
202 }
203 }
204
205 }