4

I have a maven project using the JAXWS plugin to generate some code based on a WSDL using wsimport. If I run mvn generate-sources this code gets generated.

In addition I have JUnit unit tests that reference generated classes.

According to the docs on a default install the tests should run after the generate-sources so it should work. However, if I run a build on a clean workspace in eclipse I get NoClassDefFound for one of the generated classes. If you then run the install a second time it works.

This was a bit strange so I exited eclipse and went back to basics on the command line. If I do this sequence I get the NoClassDefFound error:

  1. mvn clean
  2. mvn install

However, if I do the following it works without the error:

  1. mvn clean
  2. mvn clean install

How can this be? I would have thought mvn clean install would be equivalent to mvn clean + mvn install?

Also, when it errors I can see in the console output that the code generation phase has actually run before it does the tests. The class is there but the classloader apparently can't see it.

I don't see any other errors in the console output. Just a few warnings about specifying plugin version numbers and that source files are encoded in cp1252. Nothing exciting.

I did read this question but it didn't help me. I'm using the Java 8 jdk so I'm wondering if there's a bug here.

Edit

I'm not sure if the code helps much in this case since you can't run a test build without the full codebase. However, it might help to see the complexity of the pom and the build steps so here is an edited version. I've just renamed a few things to make it more anonymous but functionally it is the same.

Hopefully it will help resolve the questions being asked.

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.company</groupId>
    <artifactId>MyApp</artifactId>
     <version>1.0.0</version>
    <packaging>war</packaging>

    <name>MyApp</name>

    <properties>
        <java-version>1.6</java-version>
        <spring-version>4.1.4.RELEASE</spring-version>
        <hibernate-version>4.3.7.Final</hibernate-version>
        <org.slf4j-version>1.6.6</org.slf4j-version>
    </properties>

    <dependencies>  

        <!-- JAXWS web services -->
        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-rt</artifactId>
            <version>2.2.7</version>
        </dependency>

        <!-- Spring DI -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring-version}</version>
            <exclusions>
              <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
              </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring-version}</version>
        </dependency>   
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring-version}</version>
        </dependency>

        <!-- Spring integration with JAX-WS -->     
        <dependency>
            <groupId>org.jvnet.jax-ws-commons.spring</groupId>
            <artifactId>jaxws-spring</artifactId>
            <version>1.8</version>  
            <exclusions>
              <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring</artifactId>
              </exclusion>
            </exclusions>           
        </dependency>

        <!-- JPA Provider (Hibernate) -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate-version}</version>
        </dependency>       

        <!-- DataSource (HikariCP) -->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP-java6</artifactId>
            <version>2.3.2</version>
        </dependency>

        <!-- AS400 access -->
        <dependency>
            <groupId>net.sf.jt400</groupId>
            <artifactId>jt400</artifactId>
            <version>6.7</version>
        </dependency>

        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${org.slf4j-version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.mail</groupId>
                    <artifactId>mail</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.jms</groupId>
                    <artifactId>jms</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jdmk</groupId>
                    <artifactId>jmxtools</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jmx</groupId>
                    <artifactId>jmxri</artifactId>
                </exclusion>
            </exclusions>
            <scope>runtime</scope>
        </dependency>               

        <!-- Servlet - provided by container -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.sun.xml.parsers</groupId>
            <artifactId>jaxp-ri</artifactId>
            <version>1.4.5</version>
        </dependency>

        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>     
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring-version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>1.9.5</version>
            <scope>test</scope>
        </dependency>   
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>${java-version}</source>
                    <target>${java-version}</target>
                    <compilerArguments>
                  <endorseddirs>${project.build.directory}/endorsed</endorseddirs>               
                    </compilerArguments>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-dependency-plugin</artifactId>
              <version>2.3</version>
              <executions>
                <execution>
                  <phase>validate</phase>
                  <goals>
                    <goal>copy</goal>
                  </goals>
                  <configuration>
                    <outputDirectory>${project.build.directory}/endorsed</outputDirectory>
                    <silent>true</silent>
                    <artifactItems>
                      <artifactItem>
                        <groupId>javax.xml.bind</groupId>
                        <artifactId>jaxb-api</artifactId>
                        <version>2.2.4</version>
                        <type>jar</type>
                      </artifactItem>
                      <artifactItem>
                        <groupId>javax.xml.ws</groupId>
                        <artifactId>jaxws-api</artifactId>
                        <version>2.2.8</version>
                        <type>jar</type>
                      </artifactItem>
                      <artifactItem>
                        <groupId>javax.xml.bind</groupId>
                        <artifactId>jaxb-api</artifactId>
                        <version>2.2.4</version>
                        <type>jar</type>
                      </artifactItem>
                    </artifactItems>
                  </configuration>
                </execution>
              </executions>
            </plugin>
            <plugin>
              <groupId>org.jvnet.jax-ws-commons</groupId>
              <artifactId>jaxws-maven-plugin</artifactId>
              <version>2.2</version>
              <executions>
                <execution>
                  <goals>
                    <goal>wsimport</goal>
                  </goals>
                </execution>
              </executions>
              <configuration>
              <!-- Configuration for generating the jaxws code -->
                <wsdlDirectory>${basedir}/src/main/resources/wsdl</wsdlDirectory>
                <wsdlLocation>wsdl/mywsdl.wsdl</wsdlLocation>
                <packageName>com.company.generated</packageName>
                <keep>true</keep>
                <sourceDestDir>${basedir}/target/generated-sources/src/main/java</sourceDestDir> 
              </configuration>
            </plugin>           
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-source-plugin</artifactId>
              <executions>
                <execution>
                  <id>attach-sources</id>
                  <goals>
                    <goal>jar</goal>
                  </goals>
                </execution>
              </executions>
            </plugin>            
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <excludes>
                    <!-- Exclude these files from the build -->
                    <exclude>**/log4j.xml</exclude>
                </excludes>
            </resource>
        </resources>
    </build>
</project>
Community
  • 1
  • 1
Ben Thurley
  • 6,943
  • 4
  • 31
  • 54
  • 1
    Would the down voter care to comment why? I believe I've put some effort into the question and I think it can be answered. – Ben Thurley Dec 16 '15 at 22:15
  • can you put more information about your project? multi-module or not ? and if it is a multi-module: where are the tests, where is the generated code ... ? – ben75 Dec 17 '15 at 00:11
  • Sure. It's not multi-module. Just one standard war project with tests in the usual src/test/java. The generated code goes in a folder under the target directory. Obviously I have code in src/main/java that is also dependant on the generated code and this all compiles ok. Also, running a second time without cleaning the workspace means the tests pass so I think their location is probably ok. I could understand if the test failed every time but it's only if you do mvn clean then mvn install. But mvn clean install works? – Ben Thurley Dec 17 '15 at 00:24
  • Are you using any parent pom? Just to double check, did you check your mvn help:effective-pom -Doutput=effective-pom.xml? – A_Di-Matteo Dec 17 '15 at 09:00
  • I've looked at the effective pom, both on the command line as you suggest and using the M2Eclipse pom viewer and I am 100% certain that there is no parent pom. The generated source goes in /target/generated-sources/src/main/java. – Ben Thurley Dec 17 '15 at 10:45

2 Answers2

1

I've been revisiting this project and had another look at the problem. I went through the pom and scrutinized everything looking for things I could trim out or update. In the process I spotted the following plugin.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <configuration>
        <mainClass>org.test.int1.Main</mainClass>
    </configuration>
</plugin>

I think this must have been copied in from an example somewhere when we were just starting out with maven. The plugin is to execute Java programs during a build which I have no need for and that main class doesn't exist. I've not been getting any build warnings about this though.

Removing that plugin fixed the problem. This fixed it on the command line, for Eclipse I had to also right click the project and select Maven and then Update project.

Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Ben Thurley
  • 6,943
  • 4
  • 31
  • 54
0

I would configure target/generated-sources folder as a source folder in which ever IDE you are using. That may help.

Taf
  • 258
  • 2
  • 8
  • Thanks but I have already done this. The project wouldn't compile in eclipse if it weren't set as a source folder. Also, this would only effect eclipse. Maven should be able to build regardless from the command line. – Ben Thurley Dec 18 '15 at 11:44