mojohaus / mojohaus/exec-maven-plugin

ClassNotFoundException when dynamically loading a Java class executed by exec-maven-plugin

Open
#327 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
191
Forks
111
Avg merge
1d 21h
Merged PRs (30d)
4

Description

Minimal reproducer project: https://github.com/Kirchoffs/exec-plugin-issue

What I am trying to do, is to create a java class (PrimitiveServlet.class) file by javac, and then use URLClassLoader to load this class file dynamically.

To reproduce the bug using exec-maven-plugin, run the following command:

>> javac -cp webroot/javax.servlet-api-4.0.1.jar webroot/PrimitiveServlet.java
>> mvn clean install
>> mvn exec:java

The first command is to create the class file, the third command is to run the whole program.

Error Information:

java.lang.NoClassDefFoundError: javax/servlet/Servlet
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:1016)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:174)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:550)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:458)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:452)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:451)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:588)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:521)
    at org.syh.demo.App.main (App.java:25)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:279)
    at java.lang.Thread.run (Thread.java:834)
Caused by: java.lang.ClassNotFoundException: javax.servlet.Servlet
    at java.net.URLClassLoader.findClass (URLClassLoader.java:471)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:588)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:521)
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:1016)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:174)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:550)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:458)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:452)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:451)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:588)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:521)
    at org.syh.demo.App.main (App.java:25)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:279)
    at java.lang.Thread.run (Thread.java:834)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.111 s
[INFO] Finished at: 2022-08-01T21:21:09-07:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.1.0:java (default-cli) on project exec-plugin-issue: An exception occurred while executing the Java class. javax/servlet/Servlet: javax.servlet.Servlet

However, if we use pure java command to run the program, the code can work without any error:

>> javac -cp webroot/javax.servlet-api-4.0.1.jar webroot/PrimitiveServlet.java
>> mvn clean install
>> java -cp webroot/javax.servlet-api-4.0.1.jar:target/exec-plugin-issue-1.0-SNAPSHOT.jar org.syh.demo.App

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with the listed javac, mvn clean install, and mvn exec:java commands, using the linked minimal project and org.syh.demo.App at App.java:25 as the entry point. Then inspect the exec-maven-plugin Java goal's classpath and class-loader behavior, comparing it with the working java command. Done means the dynamically loaded PrimitiveServlet resolves javax.servlet.Servlet under mvn exec:java.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
build-system, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.