You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by c_inconnu3 <c_...@yahoo.fr> on 2005/07/13 00:16:14 UTC

[M2] classpath problem with surefire

Hi,

I have this pom:



<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>mygroup</groupId>
    <artifactId>tests</artifactId>
    <version>0.20-SNAPSHOT</version>

    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <type>jar</type>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <testSourceDirectory>src/test/java</testSourceDirectory>

        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                </includes>
            </testResource>
        </testResources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0-alpha-3</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>



And 2 properties files in src/test/resources/ and src/test/resources/a/b/c/.
When I run "m2 test" the following always returns null:



InputStream inputStream =
ClassLoader.getSystemResourceAsStream("a/b/c/myTest.properties");
System.out.println("**** " + inputStream); // null
inputStream = ClassLoader.getSystemResourceAsStream("myTest.properties");
System.out.println("**** " + inputStream); // null



This works in eclipse and the properties files are indeed copied into
target/test-classes/ and target/test-classes/a/b/c/.

I cannot figure out what is wrong...

David DIDIER


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: [M2] classpath problem with surefire

Posted by Jason van Zyl <ja...@maven.org>.
On Wed, 2005-07-13 at 18:46 +0200, c_inconnu3 wrote:

> Thanks for this great help, i was going mad... :-)
> 
> This works :
> * 
> this.getClass().getClassLoader().getResourceAsStream("a/b/c/myTest.properties");
> 
> This DOES NOT works :
> * ClassLoader.getSystemResourceAsStream("a/b/c/myTest.properties");
> * 
> this.getClass().getClassLoader().getSystemResourceAsStream("a/b/c/myTest.properties");
> 
> <quote>
> If that works, I'll explain why. ;-)
> </quote>

As Joakim explained each plug-in runs inside its own ClassLoader so you
need to use the ClassLoader which loaded the plug-in in order to find
any resources packaged with the plug-in.

> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
> 
> 
-- 
jvz.

Jason van Zyl
jason at maven.org
http://maven.apache.org

We know what we are, but know not what we may be.

  -- Shakespeare


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: [M2] classpath problem with surefire

Posted by Joakim Erdfelt <jo...@erdfelt.net>.
c_inconnu3 wrote:

> Joakim Erdfelt a écrit :
>
> Thanks for this great help, i was going mad... :-)
>
> This works :
> * 
> this.getClass().getClassLoader().getResourceAsStream("a/b/c/myTest.properties"); 
>
>
> This DOES NOT works :
> * ClassLoader.getSystemResourceAsStream("a/b/c/myTest.properties");
> * 
> this.getClass().getClassLoader().getSystemResourceAsStream("a/b/c/myTest.properties"); 
>
>
> <quote>
> If that works, I'll explain why. ;-)
> </quote>

Jason has far more experience with Custom ClassLoaders than I do, but 
this is what I've learned ...

ClassLoaders are a way for the JVM to load a resource, the most 
traditional techniques being from a file system or from a jar file, and 
the most common resource being the raw bytes of a class file.

The call to ClassLoader.getSystemResourceAsString() will use the System 
ClassLoader, which is top level ClassLoader that gets populated with the 
classpath from the java command line, the CLASSPATH environment 
variable, and the contents of the extension folder. (Man, I'm really 
over-simplifying things here, there's more subtly then this when you get 
into the guts of it, but I don't think that's important for this 
explanation).

Maven manages what dependencies the Plugins and Projects can see by 
using a custom ClassLoader.

A custom ClassLoader, that is placed into the 
Thread.setContextClassLoader(), can isolate the dependencies required to 
exist only for the processes running within the life of that thread.

This is how the Maven Container (and J2EE Containers) can have multiple 
programs using incompatible dependencies operate with complete oblivion 
to each other.

In your example, you are actually running within 2 isolations of 
ClassLoaders.

      1) System ClassLoader (which maven core runs in)
    1.1) Plugin Isolated ClassLoader (which maven core spawned)
  1.1.1) Surefire Battery ClassLoader (which the surefire spawned)
1.1.1.a) Your tests.

When your original code running in the nested ClassLoader at 1.1.1.a 
asked the default System ClassLoader to obtain a resource, you 
essentially asked for a resource in the classpath all the way up at step 1.

When you changed your test to use 
this.getClass().getClassLoader().getResource... you stated that you want 
to use the same ClassLoader that started the tests. (which would be the 
one at 1.1.1).

That's why it worked.

BTW: I've gotten into the habit of always using the ClassLoader from the 
loaded class, this makes my libraries work everywhere.

Here's a snippet of code that I use to bootstrap a ClassLoader and kick 
of the 'public void main(String args[])' method in another class.

  URLClassLoader loader = new URLClassLoader(locator.getUrls());
  Thread.currentThread().setContextClassLoader(loader);
  Class mainClass = loader.loadClass("com.initech.vi.rus.Cli");
  Object objmain = mainClass.newInstance();
  Class argClass = Array.newInstance(String.class, 0).getClass();
  Method mainMethod = mainClass.getMethod("main", new Class[] { argClass });
  String arguments[] = (String[]) argList.toArray(new String[0]);
  mainMethod.invoke(objmain, new Object[] { arguments });

Hope that fulfills my promise. ;-)

/* Joakim Erdfelt */

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: [M2] classpath problem with surefire

Posted by c_inconnu3 <c_...@yahoo.fr>.
Joakim Erdfelt a écrit :

> Johnny Ruiz wrote:
>
>> c_inconnu3 wrote:
>>
>>> And 2 properties files in src/test/resources/ and 
>>> src/test/resources/a/b/c/.
>>> When I run "m2 test" the following always returns null:
>>>
>>>
>>>
>>> InputStream inputStream =
>>> ClassLoader.getSystemResourceAsStream("a/b/c/myTest.properties");
>>> System.out.println("**** " + inputStream); // null
>>> inputStream = 
>>> ClassLoader.getSystemResourceAsStream("myTest.properties");
>>> System.out.println("**** " + inputStream); // null
>>>
> I had this problem before, I solved it by not relying on the System 
> ClassLoader.
> (BTW: Surefire Isolates the test's ClassLoaders from the Maven 
> ClassLoaders).
>
> Use the same ClassLoader that the TestCase was loaded via.
>
> Change it from ...
>  InputStream inputStream =
>  ClassLoader.getSystemResourceAsStream("a/b/c/myTest.properties");
> to ...
>  InputStream inputStream =
>  
> this.getClass().getClassLoader().getSystemResourceAsStream("a/b/c/myTest.properties"); 
>
>
> This subtle change helped me.
> If that works, I'll explain why. ;-)
>
> /* Joakim Erdfelt */
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>
>
Thanks for this great help, i was going mad... :-)

This works :
* 
this.getClass().getClassLoader().getResourceAsStream("a/b/c/myTest.properties");

This DOES NOT works :
* ClassLoader.getSystemResourceAsStream("a/b/c/myTest.properties");
* 
this.getClass().getClassLoader().getSystemResourceAsStream("a/b/c/myTest.properties");

<quote>
If that works, I'll explain why. ;-)
</quote>



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: [M2] classpath problem with surefire

Posted by Joakim Erdfelt <jo...@erdfelt.net>.
Johnny Ruiz wrote:

> c_inconnu3 wrote:
>
>> And 2 properties files in src/test/resources/ and 
>> src/test/resources/a/b/c/.
>> When I run "m2 test" the following always returns null:
>>
>>
>>
>> InputStream inputStream =
>> ClassLoader.getSystemResourceAsStream("a/b/c/myTest.properties");
>> System.out.println("**** " + inputStream); // null
>> inputStream = 
>> ClassLoader.getSystemResourceAsStream("myTest.properties");
>> System.out.println("**** " + inputStream); // null
>>
I had this problem before, I solved it by not relying on the System 
ClassLoader.
(BTW: Surefire Isolates the test's ClassLoaders from the Maven 
ClassLoaders).

Use the same ClassLoader that the TestCase was loaded via.

Change it from ...
  InputStream inputStream =
  ClassLoader.getSystemResourceAsStream("a/b/c/myTest.properties");
to ...
  InputStream inputStream =
  
this.getClass().getClassLoader().getSystemResourceAsStream("a/b/c/myTest.properties"); 

 
This subtle change helped me.
If that works, I'll explain why. ;-)

/* Joakim Erdfelt */

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: [M2] classpath problem with surefire

Posted by Johnny Ruiz <jr...@exist.com>.
c_inconnu3 wrote:

> Hi,
>
> I have this pom:
>
>
>
> <?xml version="1.0" encoding="UTF-8"?>
>
> <project xmlns="http://maven.apache.org/POM/4.0.0"
>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
> maven-v4_0_0.xsd">
>
>    <modelVersion>4.0.0</modelVersion>
>
>    <groupId>mygroup</groupId>
>    <artifactId>tests</artifactId>
>    <version>0.20-SNAPSHOT</version>
>
>    <packaging>jar</packaging>
>
>    <dependencies>
>        <dependency>
>            <groupId>junit</groupId>
>            <artifactId>junit</artifactId>
>            <version>3.8.1</version>
>            <type>jar</type>
>            <scope>test</scope>
>        </dependency>
>    </dependencies>
>
>    <build>
>        <sourceDirectory>src/main/java</sourceDirectory>
>        <testSourceDirectory>src/test/java</testSourceDirectory>
>
>        <testResources>
>            <testResource>
>                <directory>src/test/resources</directory>
>                <includes>
>                    <include>**/*.properties</include>
>                </includes>
>            </testResource>
>        </testResources>
>
>        <plugins>
>            <plugin>
>                <groupId>org.apache.maven.plugins</groupId>
>                <artifactId>maven-compiler-plugin</artifactId>
>                <version>2.0-alpha-3</version>
>                <configuration>
>                    <source>1.5</source>
>                    <target>1.5</target>
>                </configuration>
>            </plugin>
>        </plugins>
>    </build>
>
> </project>
>
>
>
> And 2 properties files in src/test/resources/ and 
> src/test/resources/a/b/c/.
> When I run "m2 test" the following always returns null:
>
>
>
> InputStream inputStream =
> ClassLoader.getSystemResourceAsStream("a/b/c/myTest.properties");
> System.out.println("**** " + inputStream); // null
> inputStream = ClassLoader.getSystemResourceAsStream("myTest.properties");
> System.out.println("**** " + inputStream); // null
>
>
>
> This works in eclipse and the properties files are indeed copied into
> target/test-classes/ and target/test-classes/a/b/c/.
>
> I cannot figure out what is wrong...
>
> David DIDIER
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
Hi DAVID,

I'm not sure if I understand ur problem correctly but this might help.  
Please try this code..

             try
            {
                inputStream = (InputStream) new 
FileInputStream("target/test-classes/a/b/c/myTest.properties");
                System.out.println("****"  + inputStream); //not null 
anymore :)
                File f = new 
File("target/test-classes/a/b/c/myTest.properties");
                System.out.println("File Exist = " + f.exists() + " :: 
Absolute Path =" + f.getAbsolutePath());
              }
              catch (Exception ex){    }


Johnny Ruiz