Skip to content

[MJMOD-8] NullPointerException on create#2

Merged
rfscholte merged 1 commit intoapache:masterfrom
andretadeu:MJMOD-8
Jan 18, 2019
Merged

[MJMOD-8] NullPointerException on create#2
rfscholte merged 1 commit intoapache:masterfrom
andretadeu:MJMOD-8

Conversation

@andretadeu
Copy link
Contributor

Hi,

I created this pull request to fulfill to address the need to set --class-path parameter from jmod create, because it offers the possibility to create a JMOD artifact from a JAR created in another project, in a Maven multi-module context.

Commit comment:

NullPointerException happens when I am trying to create a JMOD from a JAR from another project. The plugin was not setting classPath when it should to run the following command: 'jmod create --class-path '.

Thanks,

André Tadeu de Carvalho

@khmarbaise
Copy link
Member

First thanks for your contribution but on the other hand I'm thinking about this use case which looks to me like a different goal in the Plugin instead of having a complex parameter setup ? Can you give examples for use cases here? Complete example projects?

@andretadeu
Copy link
Contributor Author

Of course, I have two working examples:

The first one I created a multi-module Maven project where I generated both JAR and JMOD files in each project that contains Java source code with module-info.java, which is in https://github.com/andretadeu/maven-jigsaw-examples/tree/master/multi-modules-jmod-jlink. The second project is the same project in the issue, but with fixes, where there is a separated project to generate the JMOD from JAR, which is in https://github.com/andretadeu/npe-on-alpha-2.

Thinking about the approach of each module generating only one artifact, the second example seems more suitable, in my humble view. What do you think of these examples?

@andretadeu
Copy link
Contributor Author

andretadeu commented Dec 15, 2018

Hi @khmarbaise ,

I am sorry! I forgot the integration test to explain how to reproduce the error correctly and to assert that the fix address this issue.

Thanks,

<artifactId>maven-jmod-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<classPath>${project.parent.basedir}/about-cli-app/target/about-cli-app-${project.version}.jar</classPath>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be no need for this classpath entry. about-cli-app is a dependency, so will be available as a pathElement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I made one mistake here: I should be filling pathElement. In JModCreateMojo:

else if ( classPath == null || classPath.trim().isEmpty() )
        {
            throw new MojoExecutionException( "You must either have a module in your project or the "
                    + "'classPath' configuration set in 'maven-jmod-plugin' configuration section." );
        }

I'll review this part and, in this case, I owe a better solution for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can replace this classPath entry with project.dependencyArtifacts. In the test case provided, pathElement is null because this Maven project just get a modular JAR and create a JMOD file from it. What ssems reasonable to do in this case is to fill classPath with project.dependencyArtifacts.

}

if ( !pathElements.isEmpty() )
if ( classPath != null && !classPath.trim().isEmpty() )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to detect if there are classpath elements by looping over all the pathElements.

Copy link
Contributor Author

@andretadeu andretadeu Jan 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one observation here: jmod create can receive both --module-path and --class-path. In this case, I think it is a better solution is to segregate JMOD artifacts and modular JARs from non-modular JARs. Fixing the previous explanation: --class-path must contain the artifact(s) or the folder(s) that should be inside JMOD file, i.e., you would expect that one modular JAR or target/classes folder would be enough. --module-path are the folders or files containing Java modules neede to compile. It's not clear how it should be used with jmod. In all examples I have, it is not used.

I am using Java 9 Modularity book and the official Oracle documentation for references.

@andretadeu
Copy link
Contributor Author

@rfscholte Another proposal for this bug fix.

@rfscholte
Copy link
Contributor

The original code needs a clean up. It clearly shows to me that this was written while trying to understand the modular system based on code from other plugins.
My suggestion: squash your commits, so we have at least a working IT. After that I'll clean up the code.

@andretadeu
Copy link
Contributor Author

My suggestion: squash your commits, so we have at least a working IT. After that I'll clean up the code.

Done. I look forward to see the final solution. Thank you for all the help!

@rfscholte rfscholte merged commit c4b910b into apache:master Jan 18, 2019
@rfscholte
Copy link
Contributor

Did you try to use the generated jmod? I would expect it to fail because it is missing picocli. IIUC --classpath will simply use the resources from these dirctories and jarfiles. After refactoring the project this IT fails with Error: java.util.zip.ZipException: duplicate entry: classes/META-INF/MANIFEST.MF because picocli ended up on the classpath too.

@andretadeu andretadeu deleted the MJMOD-8 branch January 19, 2019 00:21
@andretadeu andretadeu restored the MJMOD-8 branch January 19, 2019 00:25
@andretadeu
Copy link
Contributor Author

I tested before of my refactoring and I didn't test it because I was expecting to maintain the behavior, since I was just replacing the origin of the information to fill classPath. I'll test again. However, I've discover another thing about --module-path (please check: https://github.com/java-modularity-examples/jigsaw-examples, example 10-exploring-jmod). We shouldn't be using --module-path, unless we want to setup a module that requires this module we are packing to add a hash on it, requiring the --hash-module parameter.

@andretadeu
Copy link
Contributor Author

Did you try to use the generated jmod? I would expect it to fail because it is missing picocli. IIUC --classpath will simply use the resources from these dirctories and jarfiles.

I'll double check it. Check any number of times if needed.

@andretadeu
Copy link
Contributor Author

andretadeu commented Jan 19, 2019

I tested now with Java 9, 10, and 11, and Maven 3.6.0:

I ran the command: mvn clean verify -Prun-its, after that I removed the generated JMOD file, and executed the command:

jmod create --module-version 99.0 \
--class-path /home/andre/workspaces/oss/maven-jmod-plugin/target/it/mjmod-8-generate-jmod-in-other-project/about-cli-app/target/about-cli-app-99.0.jar \
--config /home/andre/workspaces/oss/maven-jmod-plugin/target/it/mjmod-8-generate-jmod-in-other-project/about-cli-distribution-jmod/src/main/configs \
--cmds /home/andre/workspaces/oss/maven-jmod-plugin/target/it/mjmod-8-generate-jmod-in-other-project/about-cli-distribution-jmod/src/main/cmds \
--module-path \
"/home/andre/.sdkman/candidates/java/11.0.1-open/jmods" \
/home/andre/workspaces/oss/maven-jmod-plugin/target/it/mjmod-8-generate-jmod-in-other-project/about-cli-distribution-jmod/target/jmods/about-cli-distribution-jmod.jmod

where the arguments were generated by maven-jmod-plugin and it's in jmodCreateArgs file. From the tests above, I didn't get the error you got. I confess I got this error, but it happened after I had made a mistake in my implementation.

@rfscholte
Copy link
Contributor

I've solved it in the refactor branch
Most important thing you need to change when working with static required modules is to mark them as optional dependencies.
Please review before I'll merge it back to master.

@andretadeu
Copy link
Contributor Author

Concerning to the question of filling in the --class-path parameter, it looks good to me.

@andretadeu
Copy link
Contributor Author

It would be nice if you removed the commented out code. Thanks for everything.

@MachineIntelligence6
Copy link

MachineIntelligence6 commented Jul 25, 2019

Did you try to use the generated jmod? I would expect it to fail because it is missing picocli. IIUC --classpath will simply use the resources from these dirctories and jarfiles. After refactoring the project this IT fails with Error: java.util.zip.ZipException: duplicate entry: classes/META-INF/MANIFEST.MF because picocli ended up on the classpath too.

I'm also getting the above error. This happen when added different jars in my example project.

@jira-importer
Copy link

Resolve #66

1 similar comment
@jira-importer
Copy link

Resolve #66

@slachiewicz slachiewicz added this to the 3.0.0 milestone Dec 22, 2025
@slachiewicz slachiewicz added the bug Something isn't working label Dec 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants