View Javadoc

1   package org.apache.maven.surefire.booter;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.surefire.util.UrlUtils;
23  import org.codehaus.plexus.util.StringUtils;
24  import org.codehaus.plexus.util.cli.Commandline;
25  
26  import java.io.File;
27  import java.io.FileOutputStream;
28  import java.io.IOException;
29  import java.util.HashMap;
30  import java.util.Iterator;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Properties;
34  import java.util.jar.JarEntry;
35  import java.util.jar.JarOutputStream;
36  import java.util.jar.Manifest;
37  
38  /**
39   * Configuration for forking tests.
40   *
41   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
42   * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
43   */
44  public class ForkConfiguration
45  {
46      public static final String FORK_ONCE = "once";
47  
48      public static final String FORK_ALWAYS = "always";
49  
50      public static final String FORK_NEVER = "never";
51  
52      private String forkMode;
53  
54      private boolean useSystemClassLoader;
55      private boolean useManifestOnlyJar;
56  
57      private Properties systemProperties;
58  
59      private String jvmExecutable;
60  
61      private String argLine;
62  
63      private Map environmentVariables;
64  
65      private File workingDirectory;
66  
67      private boolean debug;
68      
69      private String debugLine;
70  
71      public void setForkMode( String forkMode )
72      {
73          if ( "pertest".equalsIgnoreCase( forkMode ) )
74          {
75              this.forkMode = FORK_ALWAYS;
76          }
77          else if ( "none".equalsIgnoreCase( forkMode ) )
78          {
79              this.forkMode = FORK_NEVER;
80          }
81          else if ( forkMode.equals( FORK_NEVER ) || forkMode.equals( FORK_ONCE ) || forkMode.equals( FORK_ALWAYS ) )
82          {
83              this.forkMode = forkMode;
84          }
85          else
86          {
87              throw new IllegalArgumentException( "Fork mode " + forkMode + " is not a legal value" );
88          }
89      }
90  
91      public boolean isForking()
92      {
93          return !FORK_NEVER.equals( forkMode );
94      }
95  
96      public void setUseSystemClassLoader( boolean useSystemClassLoader )
97      {
98          this.useSystemClassLoader = useSystemClassLoader;
99      }
100 
101     public boolean isUseSystemClassLoader()
102     {
103         return useSystemClassLoader;
104     }
105 
106     public void setSystemProperties( Properties systemProperties )
107     {
108         this.systemProperties = (Properties) systemProperties.clone();
109     }
110 
111     public void setJvmExecutable( String jvmExecutable )
112     {
113         this.jvmExecutable = jvmExecutable;
114     }
115 
116     public void setArgLine( String argLine )
117     {
118         this.argLine = argLine;
119     }
120     
121     public void setDebugLine( String debugLine )
122     {
123         this.debugLine = debugLine;
124     }
125 
126     public void setEnvironmentVariables( Map environmentVariables )
127     {
128         this.environmentVariables = new HashMap( environmentVariables );
129     }
130 
131     public void setWorkingDirectory( File workingDirectory )
132     {
133         this.workingDirectory = workingDirectory;
134     }
135 
136     public String getForkMode()
137     {
138         return forkMode;
139     }
140 
141     public Properties getSystemProperties()
142     {
143         return systemProperties;
144     }
145 
146     /**
147      * @throws SurefireBooterForkException
148      * @deprecated use the 2-arg alternative.
149      */
150     public Commandline createCommandLine( List classPath )
151         throws SurefireBooterForkException
152     {
153         return createCommandLine( classPath, false );
154     }
155 
156     public Commandline createCommandLine( List classPath, boolean useJar )
157         throws SurefireBooterForkException
158     {
159         Commandline cli = new Commandline();
160 
161         cli.setExecutable( jvmExecutable );
162 
163         if ( argLine != null )
164         {
165             cli.createArg().setLine( argLine );
166         }
167 
168         if ( environmentVariables != null )
169         {
170             Iterator iter = environmentVariables.keySet().iterator();
171 
172             while ( iter.hasNext() )
173             {
174                 String key = (String) iter.next();
175 
176                 String value = (String) environmentVariables.get( key );
177 
178                 cli.addEnvironment( key, value );
179             }
180         }
181 
182         if ( debugLine != null && !"".equals( debugLine ) )
183         {
184             cli.createArg().setLine( debugLine );
185         }
186 
187         if ( useJar )
188         {
189             File jarFile;
190             try
191             {
192                 jarFile = createJar( classPath );
193             }
194             catch ( IOException e )
195             {
196                 throw new SurefireBooterForkException( "Error creating archive file", e );
197             }
198 
199             cli.createArg().setValue( "-jar" );
200 
201             cli.createArg().setValue( jarFile.getAbsolutePath() );
202         }
203         else
204         {
205             cli.createArg().setValue( "-classpath" );
206 
207             cli.createArg().setValue( StringUtils.join( classPath.iterator(), File.pathSeparator ) );
208 
209             cli.createArg().setValue( SurefireBooter.class.getName() );
210         }
211 
212         cli.setWorkingDirectory( workingDirectory.getAbsolutePath() );
213 
214         return cli;
215     }
216 
217     /**
218      * Create a jar with just a manifest containing a Main-Class entry for SurefireBooter and a Class-Path entry
219      * for all classpath elements.
220      *
221      * @param classPath List&lt;String> of all classpath elements.
222      * @return
223      * @throws IOException
224      */
225     private File createJar( List classPath )
226         throws IOException
227     {
228         File file = File.createTempFile( "surefirebooter", ".jar" );
229         if ( !debug )
230         {
231             file.deleteOnExit();
232         }
233         FileOutputStream fos = new FileOutputStream( file );
234         JarOutputStream jos = new JarOutputStream( fos );
235         jos.setLevel( JarOutputStream.STORED );
236         JarEntry je = new JarEntry( "META-INF/MANIFEST.MF" );
237         jos.putNextEntry( je );
238 
239         Manifest man = new Manifest();
240 
241         // we can't use StringUtils.join here since we need to add a '/' to
242         // the end of directory entries - otherwise the jvm will ignore them.
243         String cp = "";
244         for ( Iterator it = classPath.iterator(); it.hasNext(); )
245         {
246             String el = (String) it.next();
247             // NOTE: if File points to a directory, this entry MUST end in '/'.
248             cp += UrlUtils.getURL( new File( el ) ).toExternalForm() + " ";
249         }
250 
251         man.getMainAttributes().putValue( "Manifest-Version", "1.0" );
252         man.getMainAttributes().putValue( "Class-Path", cp.trim() );
253         man.getMainAttributes().putValue( "Main-Class", SurefireBooter.class.getName() );
254 
255         man.write( jos );
256         jos.close();
257 
258         return file;
259     }
260 
261     public void setDebug( boolean debug )
262     {
263         this.debug = debug;
264     }
265 
266     public boolean isDebug()
267     {
268         return debug;
269     }
270 
271     public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
272     {
273         this.useManifestOnlyJar = useManifestOnlyJar;
274     }
275     
276     public boolean isUseManifestOnlyJar()
277     {
278         return useManifestOnlyJar;
279     }
280 }