19

I created two small projects de.app1 and de.app2, where App from de.app1 uses Test from de.app2.

├── de.app1
│   ├── de
│   │   └── app
│   │       └── App.java
│   └── module-info.java
└── de.app2
    └── de
        └── test
            └── Test.java

module-info.java in the first project just contains module de.app1 {}

I compiled the second project and created a jar file:

javac de/test/Test.java
jar cf app2.jar de/test/Test.class

and then tried to compile the first project like this:

javac -cp ../de.app2/app2.jar de/app/App.java module-info.java

which failed because Test could not be found. When I compile the project without module-info.java, everything is working as usual.

Is it somehow possible to use classes from a jar that is not a Java 9 module within a Java 9 module? Especially for projects that depend on 3rd-party projects (e.g. apache-commons,...), I think something like this would be required.

1 Answer 1

16

Yes, it is possible. What you are looking for are automatic modules.

To create one you simply put a regular JAR into a folder that you mention on the module path (e.g. guava-19.0.jar in a folder libs - see my example project). This tells the JVM to create a module from it. This module will get a name based on the file name (in this case guava), will read all other modules, and export all of its packages.

You can then require it with the name it was given (e.g. require guava; - see here).

Sign up to request clarification or add additional context in comments.

8 Comments

Nice, thanks! So in order for me to get this straight: When I'm working with modules, I should basically always use module path instead of classpath?
It's not that simple. The JVM will only load modules from the module path that are required by another module. Dependencies of automatic modules are not required by anyone (because they have no module-info), so they won't be loaded. They have to go on the class path, where they get bunched into the unnamed module.
If one automatic module depends upon another automatic module (i.e., both are on the module path but only the first is required by an explicit module) then you can cause the second automatic module to be loaded via the --add-modules option. This option accepts various special tokens denoting useful collections of modules. ALL-MODULE-PATH, in particular, will load all observable modules found on the module path.
The key difference is that automatic modules are subject to sanity checks, such as those for split and duplicate packages. If you're migrating an existing set of JAR files to modules then loading them as automatic modules via ALL-MODULE-PATH can be a useful step along the way.
Great answer, thanks. However, how does this work if I let Maven manage my dependencies and would try to avoid to manually place a JAR in my project?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.