Maven run class before test phase: exec-maven-plugin exec:java not executing class
Asked Answered
C

3

5

I am running jUnit4 tests, built with Maven, on a Jenkins box. My goal is to restore a test database before executing the tests.

It looks like exec-maven-plugin is the way to go, but I cannot get it running. Any pointers? Although there are lots of examples, the doc on the mojo site is pretty thin.

The class I need to run currently lives at:

MyProject.src.test.java._tools.BuildTestEnvironment.java

My pom.xml includes:

<pluginManagement>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
        <plugin>            
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.3</version>
            <executions>
                <execution>
                    <id>build-test-environment</id>
                    <phase>generate-test-resources</phase>            
                    <goals>
                        <goal>java</goal>            
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>src.test.java._tools.BuildTestEnvironment</mainClass>
            </configuration>
        </plugin>
    </plugins>
</pluginManagement>

Run this in Jenkins, nothing really happens. If I run it locally, I get

Things I have tried, without success:

  1. Run the build in Jenkins: Nothing really happens. The project builds and starts running tests, but my class is not run.

  2. Run the build locally: Same result as in Jenkins. No surprise there.

  3. Run generate-test-resources locally: ClassNotFoundException. ie:

    mvn exec:java generate-test-resources
    java.lang.ClassNotFoundException: src.test.java._tools.BuildTestEnvironment

  4. Compile the class into a jar, and add that to my pom.

Update:

After reading @ppuskar's comments, I tried moving my buildxxx class around a bit. After moving it to src.main.java._tools.BuildTestEnvironment, I still get a similar message. Here is my build log, in case that helps:

[DEBUG] Invoking : test.java._tools.BuildTestEnvironment.main()
[DEBUG] Plugin Dependencies will be excluded.
[DEBUG] Project Dependencies will be included.
[DEBUG] Collected project artifacts [joda-time:joda-time:jar:2.3:compile, net.sf.jt400:jt400:jar:6.7:compile, junit:junit:jar:4.11:compile, org.hamcrest:hamcrest-core:jar:1.3:compile, com.fasterxml.jackson.core:jackson-core:jar:2.3.0:compile, com.fasterxml.jackson.core:jackson-databind:jar:2.3.0:compile, com.fasterxml.jackson.core:jackson-annotations:jar:2.3.0:compile, org.hamcrest:hamcrest-all:jar:1.3:compile, org.apache.logging.log4j:log4j-api:jar:2.0-rc1:compile, org.apache.logging.log4j:log4j-core:jar:2.0-rc1:compile]
[DEBUG] Collected project classpath [C:\workspace\VSP_UnitTest\target\classes]
[DEBUG] Adding to classpath : file:/C:/workspace/VSP_UnitTest/target/classes/
[DEBUG] Adding project dependency artifact: joda-time to classpath
[DEBUG] Adding project dependency artifact: jt400 to classpath
[DEBUG] Adding project dependency artifact: junit to classpath
[DEBUG] Adding project dependency artifact: hamcrest-core to classpath
[DEBUG] Adding project dependency artifact: jackson-core to classpath
[DEBUG] Adding project dependency artifact: jackson-databind to classpath
[DEBUG] Adding project dependency artifact: jackson-annotations to classpath
[DEBUG] Adding project dependency artifact: hamcrest-all to classpath
[DEBUG] Adding project dependency artifact: log4j-api to classpath
[DEBUG] Adding project dependency artifact: log4j-core to classpath
[DEBUG] joining on thread Thread[test.java._tools.BuildTestEnvironment.main(),5,test.java._tools.BuildTestEnvironment]
[WARNING] java.lang.ClassNotFoundException: test.java._tools.BuildTestEnvironment
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:281)
at java.lang.Thread.run(Thread.java:724)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.602 s
[INFO] Finished at: 2014-05-15T14:38:50-05:00
[INFO] Final Memory: 12M/152M
[INFO] ------------------------------------------------------------------------

Carman answered 14/5, 2014 at 16:7 Comment(1)
if using jenkins, make sure that the POM and the class changes has been committed to repository, and check if jenkins is getting updated source code from source code repository.Spate
S
4

try moving BuildTestEnvironment.java from src.test.java._tools to src.main.java._tools i.e. your class will be src.main.java._tools.BuildTestEnvironment

i tried running the scenario you provided. it failed like you said, however i move the java file to main from test .... it RAN :)

CHEERS :)

Spate answered 14/5, 2014 at 17:10 Comment(2)
But then you have test configuration in your main configurationMulry
I see what you're saying, @LouisaBuchanan. In my case, the whole project is test (ie, no deployable code) and we keep non-test helpers (data getters for test values, mainly) in 'main'. So moving the build script over there was fine.Carman
A
12

I wanted to leave this as a comment to address Rebzie's comment, but I haven't the reputation.

But then you have test configuration in your main configuration

The Exec Maven plugin supports changing the classpath scope so that you can use test-scoped resources without moving them out of the test package, like so:

<configuration>
    <mainClass>src.test.java._tools.BuildTestEnvironment</mainClass>
    <classpathScope>test</classpathScope>
</configuration>

This provides a clean solution where your test setup code remains in your test resources.

Anhydride answered 9/7, 2015 at 13:7 Comment(0)
S
5

I was trying something very similar, and I just leave my findings here if somebody stumbles upon that. I was planning to have a class in test that created some test resources and then run the actual tests.

The core problem is that the maven phase test-compile runs after generate-test-resources. Code in the test branch is not compiled yet when this is executed, therefore the exec-plugin didn't find the compiled class.

My temporary solution is to attach the exec-plugin to the phase process-test-classes.

Sabinasabine answered 22/3, 2018 at 11:39 Comment(1)
Thank you! This was causing me so much frustration before I read this answer.Nevil
S
4

try moving BuildTestEnvironment.java from src.test.java._tools to src.main.java._tools i.e. your class will be src.main.java._tools.BuildTestEnvironment

i tried running the scenario you provided. it failed like you said, however i move the java file to main from test .... it RAN :)

CHEERS :)

Spate answered 14/5, 2014 at 17:10 Comment(2)
But then you have test configuration in your main configurationMulry
I see what you're saying, @LouisaBuchanan. In my case, the whole project is test (ie, no deployable code) and we keep non-test helpers (data getters for test values, mainly) in 'main'. So moving the build script over there was fine.Carman

© 2022 - 2024 — McMap. All rights reserved.