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.NestedRuntimeException;
23  
24  import java.lang.reflect.InvocationTargetException;
25  import java.lang.reflect.Method;
26  import java.net.MalformedURLException;
27  import java.net.URL;
28  import java.util.Iterator;
29  import java.util.List;
30  
31  /**
32   * Represents the classpaths for the BooterConfiguration.
33   * <p/>
34   * 
35   * @author Jason van Zyl
36   * @author Emmanuel Venisse
37   * @author Kristian Rosenvold
38   * @version $Id$
39   */
40  public class ClasspathConfiguration
41  {
42      private static final String CHILD_DELEGATION = "childDelegation";
43  
44      private static final String ENABLE_ASSERTIONS = "enableAssertions";
45  
46      private static final String CLASSPATH = "classPathUrl.";
47  
48      private static final String SUREFIRE_CLASSPATH = "surefireClassPathUrl.";
49  
50      private final Classpath classpathUrls;
51  
52      private final Classpath surefireClasspathUrls;
53  
54      /**
55       * Whether to enable assertions or not (can be affected by the fork arguments, and the ability to do so based on the
56       * JVM).
57       */
58      private final boolean enableAssertions;
59  
60      // todo: @deprecated because the IsolatedClassLoader is really isolated - no parent.
61      private final boolean childDelegation;
62  
63      public ClasspathConfiguration( boolean enableAssertions, boolean childDelegation )
64      {
65          this( new Classpath(), new Classpath(), enableAssertions, childDelegation );
66      }
67  
68  
69      ClasspathConfiguration( PropertiesWrapper properties )
70      {
71          this( properties.getClasspath( CLASSPATH ),
72                properties.getClasspath( SUREFIRE_CLASSPATH ),
73                properties.getBooleanProperty( ENABLE_ASSERTIONS ), properties.getBooleanProperty( CHILD_DELEGATION ) );
74      }
75  
76      public ClasspathConfiguration( Classpath testClasspath, Classpath surefireClassPathUrls, boolean enableAssertions,
77                                      boolean childDelegation )
78      {
79          this.enableAssertions = enableAssertions;
80          this.childDelegation = childDelegation;
81          this.classpathUrls = testClasspath;
82          this.surefireClasspathUrls = surefireClassPathUrls;
83      }
84  
85      public void setForkProperties( PropertiesWrapper properties )
86      {
87          properties.setClasspath( CLASSPATH, classpathUrls );
88          properties.setClasspath( SUREFIRE_CLASSPATH, surefireClasspathUrls );
89          properties.setProperty( ENABLE_ASSERTIONS, String.valueOf( enableAssertions ) );
90          properties.setProperty( CHILD_DELEGATION, String.valueOf( childDelegation ) );
91      }
92  
93      private static Method assertionStatusMethod;
94  
95      static
96      {
97          try
98          {
99              assertionStatusMethod =
100                 ClassLoader.class.getMethod( "setDefaultAssertionStatus", new Class[]{ boolean.class } );
101         }
102         catch ( NoSuchMethodException e )
103         {
104             assertionStatusMethod = null;
105         }
106     }
107 
108     public ClassLoader createTestClassLoaderConditionallySystem( boolean useSystemClassLoader )
109         throws SurefireExecutionException
110     {
111         return useSystemClassLoader
112             ? ClassLoader.getSystemClassLoader()
113             : createTestClassLoader( this.childDelegation );
114     }
115 
116     public ClassLoader createTestClassLoader( boolean childDelegation )
117         throws SurefireExecutionException
118     {
119         return createClassLoaderSEE( classpathUrls, null, childDelegation );
120     }
121 
122     public ClassLoader createTestClassLoader()
123         throws SurefireExecutionException
124     {
125         return createClassLoaderSEE( classpathUrls, null, this.childDelegation );
126     }
127 
128     public ClassLoader createSurefireClassLoader( ClassLoader parent )
129         throws SurefireExecutionException
130     {
131         return createClassLoaderSEE( surefireClasspathUrls, parent, false );
132     }
133 
134     private ClassLoader createClassLoaderSEE( Classpath classPathUrls, ClassLoader parent, boolean childDelegation )
135         throws SurefireExecutionException
136     {
137         try
138         {
139             return createClassLoader( classPathUrls, parent, childDelegation );
140         }
141         catch ( MalformedURLException e )
142         {
143             throw new SurefireExecutionException( "When creating classloader", e );
144         }
145 
146     }
147 
148     private ClassLoader createClassLoader( Classpath classPathUrls, ClassLoader parent, boolean childDelegation )
149         throws MalformedURLException
150     {
151         List urls = classPathUrls.getAsUrlList();
152         IsolatedClassLoader classLoader = new IsolatedClassLoader( parent, childDelegation );
153         if ( assertionStatusMethod != null )
154         {
155             try
156             {
157                 Object[] args = new Object[]{ enableAssertions ? Boolean.TRUE : Boolean.FALSE };
158                 if ( parent != null )
159                 {
160                     assertionStatusMethod.invoke( parent, args );
161                 }
162                 assertionStatusMethod.invoke( classLoader, args );
163             }
164             catch ( IllegalAccessException e )
165             {
166                 throw new NestedRuntimeException( "Unable to access the assertion enablement method", e );
167             }
168             catch ( InvocationTargetException e )
169             {
170                 throw new NestedRuntimeException( "Unable to invoke the assertion enablement method", e );
171             }
172         }
173         for ( Iterator iter = urls.iterator(); iter.hasNext(); )
174         {
175             URL url = (URL) iter.next();
176             classLoader.addURL( url );
177         }
178         return classLoader;
179     }
180 
181     public Classpath getTestClasspath()
182     {
183         return classpathUrls;
184     }
185 
186     public void addClasspathUrl( String path )
187     {
188         classpathUrls.addClassPathElementUrl( path );
189     }
190 
191     public void addSurefireClasspathUrl( String path )
192     {
193         surefireClasspathUrls.addClassPathElementUrl( path );
194     }
195 }