Exclude Maven Dependency during Eclipse Application Runtime

1.4k Views Asked by At

When I try to run a Java Application on Eclipse, a conflict between two dependencies is causing the application to fail.

I am trying to upgrade my project Java version from OracleJDK 8 to OpenJDK 11. As a result, I also had to also needed to update a GWT dependency from 2.6.0 to 2.8.2, as well as switch from MOJO gwt-maven-plugin to the tboyer version as well. Additionally, the build is done on Maven 4.0.0 on Eclipse IDE 4.9.0.

Snippet of the pom.xml

<properties>
  <gwt.version>2.8.2</gwt.version>
  ...
</properties>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.google.gwt</groupId>
      <artifactId>gwt</artifactId>
      <version>${gwt.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt-dev</artifactId>
    <scope>provided</scope>
  </dependency>    
  ...

<build>
  <plugins>
    <plugin>
      <groupId>net.ltgt.gwt.maven</groupId>
      <artifactId>gwt-maven-plugin</artifactId>
      <version>1.0-rc-10</version>
      <executions>
        <execution>
          <id>compile-common</id>
          <goals>
            <goal>compile</goal>
            <goal>test</goal>
          </goals>
          <configuration>
            <moduleName>XXXXModule</moduleName>
          </configuration>
       </execution>
       <execution>
         <id>XXXX</id>
         <goals>
           <goal>compile</goal>
           <goal>test</goal>
         </goals>
         <configuration>
           <moduleName>XXXXModule</moduleName>
         </configuration>
       </execution>
       <execution>
         <id>XXXX</id>
         <goals>
           <goal>compile</goal>
           <goal>test</goal>
         </goals>
         <configuration>
           <moduleName>XXXXModule</moduleName>
         </configuration>
       </execution>
       <execution>
          <id>XXXX</id>
          <goals>
            <goal>compile</goal>
            <goal>test</goal>
          </goals>
          <configuration>
            <moduleName>XXXXModule</moduleName>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

So when I run the application on Eclipse, I get the following error:

SEVERE: Application encountered an exception during Start.
XXXX.ApplicationException: Failed to reflect on start method.
at XXXX.ApplicationLauncher.startApplication(ApplicationLauncher.java:471)
    at XXXX.ApplicationLauncher.doRun(ApplicationLauncher.java:185)
    at XXXX.ApplicationLauncher.main(ApplicationLauncher.java:67)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at XXXX.ApplicationLauncher.startApplication(ApplicationLauncher.java:469)
    ... 2 more
Caused by: java.lang.NoSuchMethodError: org.apache.tomcat.util.ExceptionUtils.preload()V
    at org.apache.catalina.startup.Tomcat.<init>(Tomcat.java:181)
....

After investigating, I discovered that two of my dependencies tomcat-embed-core-7.0.91 & apache-jsp-8.0.9.M3 both contain ExceptionUtils with several difference, hence the Exception. Furthermore, the apache-jsp is being pulled by the gwt-dev dependency which is only required during the Maven build to run the gwt-maven-plugin.

gwt-dev:2.8.2
    apache-jsp:9.2.14.v20151106
         apache-jsp:8.0.9.M3

But for some reason, Eclipse is including gwt-dev and it's dependency as part of the runtime path even though I have the 'provided' scope tag in the pom.xml.

I have tried excluding the apache-jsp dependency, but a compile issue occurs because apparently gwt-dev is still being added which depends on apache-jsp.

Summary

  • The TBroyer GWT-Maven-Plugin requires the pom file to include gwt-dev as a dependency in order to run correctly during a build.
  • However, when running the application on Eclipse, a NoSuchMethodException occurs on org.apache.tomcat.util.ExceptionUtils.preload()V
  • The issue is there are two ExceptionUtil classes with same package from different jars and methods.
  • One of the jars is apache-jsp which is a dependency of gwt-dev. Gwt-dev and it's dependencies should not be part of the runtime classpath.

Question: Is there a way to ensure the gwt-dev is only used during the Maven build and not part of the Eclipse Java Application runtime classpath?

1

There are 1 best solutions below

5
Ignacio Baca On

Yes, you can ensure isolated classpath for client and server sides. You need to apply the multimodule layout. This is also the main difference between the old MOJO gwt maven plugin and the new generation tbroyer gwt maven plugin, the new one support multimodule correctly. Check this archetype as a reference for the multimodule layout. Also, use the packaging:gwt-app to configure the gwt maven plugin executions automatically.

Making it work with eclipse run action (tomcat or gwt) is a bit more difficult. Until you correctly apply the tbroyer gwt maven plugin and the multimodule layout, you will be able to use mvn tomcat7:run and mvn gwt:codeserver in the terminal. Then, the recommended strategy to use it in your IDE is to configure this maven goal and run it using the maven tooling of your IDE. This makes it work exactly the same in all your environments (terminal, CI, eclipse, intellij, etc).