1 package org.apache.maven.plugin.surefire.booterclient;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
23 import org.apache.maven.surefire.booter.Classpath;
24 import org.apache.maven.surefire.booter.ForkedBooter;
25 import org.apache.maven.surefire.booter.SurefireBooterForkException;
26 import org.apache.maven.surefire.util.Relocator;
27 import org.apache.maven.surefire.util.UrlUtils;
28 import org.codehaus.plexus.util.StringUtils;
29 import org.codehaus.plexus.util.cli.Commandline;
30
31 import java.io.File;
32 import java.io.FileOutputStream;
33 import java.io.IOException;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Properties;
39 import java.util.jar.JarEntry;
40 import java.util.jar.JarOutputStream;
41 import java.util.jar.Manifest;
42
43
44
45
46
47
48
49
50 public class ForkConfiguration
51 {
52 public static final String FORK_ONCE = "once";
53
54 public static final String FORK_ALWAYS = "always";
55
56 public static final String FORK_NEVER = "never";
57
58 private final Classpath bootClasspathConfiguration;
59
60 private final String forkMode;
61
62 private Properties systemProperties;
63
64 private String jvmExecutable;
65
66 private String argLine;
67
68 private Map environmentVariables;
69
70 private File workingDirectory;
71
72 private File tempDirectory;
73
74 private boolean debug;
75
76 private String debugLine;
77
78 public ForkConfiguration( Classpath bootClasspathConfiguration, String forkMode, File tmpDir )
79 {
80 this.bootClasspathConfiguration = bootClasspathConfiguration;
81 this.forkMode = getForkMode( forkMode );
82 this.tempDirectory = tmpDir;
83 }
84
85 public Classpath getBootClasspath()
86 {
87 return bootClasspathConfiguration;
88 }
89
90 private static String getForkMode( String forkMode )
91 {
92 if ( "pertest".equalsIgnoreCase( forkMode ) )
93 {
94 return FORK_ALWAYS;
95 }
96 else if ( "none".equalsIgnoreCase( forkMode ) )
97 {
98 return FORK_NEVER;
99 }
100 else if ( forkMode.equals( FORK_NEVER ) || forkMode.equals( FORK_ONCE ) || forkMode.equals( FORK_ALWAYS ) )
101 {
102 return forkMode;
103 }
104 else
105 {
106 throw new IllegalArgumentException( "Fork mode " + forkMode + " is not a legal value" );
107 }
108 }
109
110 public boolean isForking()
111 {
112 return !FORK_NEVER.equals( forkMode );
113 }
114
115 public void setSystemProperties( Properties systemProperties )
116 {
117 this.systemProperties = (Properties) systemProperties.clone();
118 }
119
120 public void setJvmExecutable( String jvmExecutable )
121 {
122 this.jvmExecutable = jvmExecutable;
123 }
124
125 public void setArgLine( String argLine )
126 {
127 this.argLine = argLine;
128 }
129
130 public void setDebugLine( String debugLine )
131 {
132 this.debugLine = debugLine;
133 }
134
135 public void setEnvironmentVariables( Map environmentVariables )
136 {
137 this.environmentVariables = new HashMap( environmentVariables );
138 }
139
140 public void setWorkingDirectory( File workingDirectory )
141 {
142 this.workingDirectory = workingDirectory;
143 }
144
145 public void setTempDirectory( File tempDirectory )
146 {
147 this.tempDirectory = tempDirectory;
148 }
149
150 public String getForkMode()
151 {
152 return forkMode;
153 }
154
155 public Properties getSystemProperties()
156 {
157 return systemProperties;
158 }
159
160
161
162
163
164
165
166
167
168 public Commandline createCommandLine( List classPath, ClassLoaderConfiguration classpathConfiguration,
169 boolean shadefire )
170 throws SurefireBooterForkException
171 {
172 return createCommandLine( classPath, classpathConfiguration.isManifestOnlyJarRequestedAndUsable(), shadefire );
173 }
174
175 public Commandline createCommandLine( List classPath, boolean useJar, boolean shadefire )
176 throws SurefireBooterForkException
177 {
178 Commandline cli = new Commandline();
179
180 cli.setExecutable( jvmExecutable );
181
182 if ( argLine != null )
183 {
184 cli.createArg().setLine( stripNewLines( argLine ) );
185 }
186
187 if ( environmentVariables != null )
188 {
189 Iterator iter = environmentVariables.keySet().iterator();
190
191 while ( iter.hasNext() )
192 {
193 String key = (String) iter.next();
194
195 String value = (String) environmentVariables.get( key );
196
197 cli.addEnvironment( key, value );
198 }
199 }
200
201 if ( getDebugLine() != null && !"".equals( getDebugLine() ) )
202 {
203 cli.createArg().setLine( getDebugLine() );
204 }
205
206 if ( useJar )
207 {
208 File jarFile;
209 try
210 {
211 jarFile = createJar( classPath );
212 }
213 catch ( IOException e )
214 {
215 throw new SurefireBooterForkException( "Error creating archive file", e );
216 }
217
218 cli.createArg().setValue( "-jar" );
219
220 cli.createArg().setValue( jarFile.getAbsolutePath() );
221 }
222 else
223 {
224 cli.createArg().setValue( "-classpath" );
225
226 cli.createArg().setValue( StringUtils.join( classPath.iterator(), File.pathSeparator ) );
227
228 final String forkedBooter = ForkedBooter.class.getName();
229
230 cli.createArg().setValue( shadefire ? new Relocator( ).relocate( forkedBooter ) : forkedBooter);
231 }
232
233 cli.setWorkingDirectory( workingDirectory.getAbsolutePath() );
234
235 return cli;
236 }
237
238
239
240
241
242
243
244
245
246 public File createJar( List classPath )
247 throws IOException
248 {
249 File file = File.createTempFile( "surefirebooter", ".jar", tempDirectory );
250 if ( !debug )
251 {
252 file.deleteOnExit();
253 }
254 FileOutputStream fos = new FileOutputStream( file );
255 JarOutputStream jos = new JarOutputStream( fos );
256 jos.setLevel( JarOutputStream.STORED );
257 JarEntry je = new JarEntry( "META-INF/MANIFEST.MF" );
258 jos.putNextEntry( je );
259
260 Manifest man = new Manifest();
261
262
263
264 String cp = "";
265 for ( Iterator it = classPath.iterator(); it.hasNext(); )
266 {
267 String el = (String) it.next();
268
269 cp += UrlUtils.getURL( new File( el ) ).toExternalForm() + " ";
270 }
271
272 man.getMainAttributes().putValue( "Manifest-Version", "1.0" );
273 man.getMainAttributes().putValue( "Class-Path", cp.trim() );
274 man.getMainAttributes().putValue( "Main-Class", ForkedBooter.class.getName() );
275
276 man.write( jos );
277 jos.close();
278
279 return file;
280 }
281
282 public void setDebug( boolean debug )
283 {
284 this.debug = debug;
285 }
286
287 public boolean isDebug()
288 {
289 return debug;
290 }
291
292 public String stripNewLines( String argline )
293 {
294 return argline.replace( "\n", " " ).replace( "\r", " " );
295 }
296
297 public String getDebugLine()
298 {
299 return debugLine;
300 }
301
302
303 public File getTempDirectory()
304 {
305 return tempDirectory;
306 }
307 }