Dave
Dave

Reputation: 19150

Why are tests failing in my Jenkins-Sonar plugin but not during the Jenkins-Maven run?

I'm running Jenkins 1.478 on CentOS, using Java 6, Maven 3.0.4, JUnit 4.8.1 (dependency within the Maven project), and Sonar 3.2.1. I have my Jenkins Maven 2/3 job setup to run Sonar after it completes (set with goals "clean package -Pdev"). The project is a multi-module project with WAR and EAR modules. However, when the Sonar portion of the plugin runs, many of the tests die with errors like below …

java.lang.NullPointerException
        at java.util.Properties$LineReader.readLine(Properties.java:418)
        at java.util.Properties.load0(Properties.java:337)
        at java.util.Properties.load(Properties.java:325)
        at org.parentco.myco.client.test.AbstractHibernateDaoTest.loadmyprojectProps(AbstractHibernateDaoTest.java:252)
        at org.parentco.myco.client.test.AbstractHibernateDaoTest.setupMockEjbContainer(AbstractHibernateDaoTest.java:235)
        at org.parentco.myco.client.test.AbstractHibernateDaoTest.setupBeforeClass(AbstractHibernateDaoTest.java:72)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:236)

The exception comes from the last line of this code block ...

    final InputStream in = AbstractHibernateDaoTest.class.getClassLoader().getResourceAsStream("myproject.properties");
    final Properties props = new Properties();
    props.load(in);

The test runs perfectly during the Maven portion of my job. The file in question is located at

./myclient-war/src/main/resources/myproject.properties

Anyone know how I can troubleshoot this further? I would prefer to configure something in Sonar as opposed to having to restructure my entire project to accommodate Sonar, but I'm open to suggestions.

Upvotes: 3

Views: 2663

Answers (3)

eis
eis

Reputation: 53462

One possibility is this issue:

Spring-based junit tests clash with Cobertura plugin Sonar uses. Workaround is to use JaCoCo or EMMA plugin instead of Cobertura.

Upvotes: 0

Kalpak Gadre
Kalpak Gadre

Reputation: 6475

It could be due to Sonar creating a separate class loader for running each test, although I am not quite sure.

I believe all the tests failing follow hierarchy?

YourTestClass extends AbstractHibernateDaoTest

Try loading the file using the classloader of the immediate test class that is YourTestClass instead of always trying to load it using class loader of AbstractHibernateDaoTest

Try changing your code to,

final InputStream in = this.getClass().getClassLoader()
                        .getResourceAsStream("myproject.properties");
final Properties props = new Properties();
props.load(in);

This will ensure that you are getting class object of your actual test class instead of the abstract one and also the class loader of the immediate class instead of one already loaded.

UPDATE: I I feel what is happening is that whatever class loader is being used in your code to load the resource, is not able to see the Maven's class loader. Note that Maven and particularly maven-surefire-plugin in your case is responsible for setting the right classpath. It will be adding the src/main/resources directory on the classpath.

Upvotes: 1

Andrzej Jozwik
Andrzej Jozwik

Reputation: 14649

Try "/myproject.properties".

ClassLoader cl = AbstractHibernateDaoTest.class.getClassLoader();  
InputStream inTmp = cl.getResourceAsStream("myproject.properties");
if(itTmp==null){
    itTmp=cl.getResourceAsStream("/myproject.properties");
}
final InputStream in = inTmp;

Upvotes: 0

Related Questions