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