How to use 3rd party library in Java9 module? - java

I have some java9 module that uses 3rd party library that is not Java9 module, just a simple utility jar.
However, the compiler complains that it can't find a package from my utility.
What should I do in module-info.java to enable usage of my 3rd party library?

You can use your library as an automatic module. An automatic module is a module that doesn't have a module descriptor (i.e. module-info.class).
But what name do you need to specify to refer to an automatic module? The name of the automatic module is derived from the JAR name (unless this JAR contains an Automatic-Module-Name attribute). The full rule is quite long (see Javadoc for ModuleFinder.of), so for simplicity, you just have to drop the version from its name and then replace all non-alphanumeric characters with dots (.).
For example, if you want to use foo-bar-1.2.3-SNAPSHOT.jar, you need to add the following line to module-info.java:
module <name> {
requires foo.bar;
}

To put it in simple steps, to use a 3rd party jar (e.g. log4j-api-2.9.1.jar below) in your module:-
Execute the descriptor command of jar tool
jar --file=/path/to/your/jar/log4j-api-2.9.1.jar --describe-module
This would provide you an output similar to
No module descriptor found. Derived automatic module.
log4j.api#2.9.1 automatic
In your module descriptor file, declare a requires to that module name as:-
module your.module {
requires log4j.api;
}
That's it.

Related

Use of Java module java.smartcardio

I have trouble to use the module java.smartcardio. In my understanding I just just create a module-info.java and add
module apdu {
requires java.smartcardio;
}
I placed this file directly in the package. But this does not resolve my ``... cannot be resolved to a type`. Also
module com.test.bla.xxx.apdu {
requires java.smartcardio;
}
did not work.
Am I missing a setup step or something? Before now we did not use the module system yet.

How to publish a android library with java module?

My Project
- moduleA
- moduleAPT
- moduleJ
Above is my project structure. The moduleA is a shared library module, and moduleJ is a java module that contains some annotation classes, and moduleAPT is an annotation processing tool module that handles moduleJ's annotation classes.
Both moduleA and moduleAPT have a dependence line in their build.gradle file like this:
api project(':moduleJ')
Now i want to publish the moduleA to jcenter. The problem is the generated aar file do not contains source files in moduleJ.
How to merge moduleJ's classes to moduleA's aar file when compiling.
You can use this library to package aar
fat-aar-android
I'm using it, it can merge multiple module

StreamSource - which module for module-info?

Using javax.xml.transform.stream.StreamSource in a very simple program.
Using Eclipse and Java 13.
Configured Java Build Path Modulepath to contain JRE SystemLibrary [JavaSE-13] .
I have added requires java.base; to module-info.java.
But still: Eclipse cannot compile that class:
The type javax.xml.transform.stream.StreamSource is not accessible
What do I miss?
As documented by StreamSource, that class is in the java.xml module:
Which means to use StreamSource in your module you need the following module-info:
module <your-module-name> {
requires java.xml;
// other requires, exports, opens, uses, and provides directives (as needed)
}
Note you don't need to include requires java.base; as that module is implicitly required by every module, similar to how you don't need to import classes from the java.lang package.

module-info.java compile fail with maven-compiler-plugin and automatic modules

I'm using v3.7.0 of the plugin as required and JDK 9.0.1. I have added two requires statements, each referring to a jar in the class path (automatic module). The module-info.java compiles successfully in Eclipse after I moved the jars to Modulepath. However, Maven gives me a compiler error saying one of them is missing (strangely, not the first one which is just one line before). I tried to check the automatic module name but I get an error from the commands just for this jar. What does this error mean and how do I fix it so that I can discover the proper module name?
I replaced my username in the output below. The jar in question does use a ServiceLoader but is not compiled with Java 9.
computerName:Commander-java username$ jar --file=/Users/username/.m2/repository/com/username/rcf/1.0/rcf-1.0.jar --describe-module
Unable to derive module descriptor for: /Users/username/.m2/repository/com/username/rcf/1.0/rcf-1.0.jar
Provider class com.username.rcf.server.TestCmdChain not in module
computerName:Commander-java username$ java -p /Users/username/.m2/repository/com/username/rcf/1.0/rcf-1.0.jar --list-modules
Error occurred during initialization of boot layer
java.lang.module.FindException: Unable to derive module descriptor for /Users/username/.m2/repository/com/username/rcf/1.0/rcf-1.0.jar
Caused by: java.lang.module.InvalidModuleDescriptorException: Provider class com.username.rcf.server.TestCmdChain not in module
The answer in How to deal with java keywords in auto generated module names in Java 9? has a different error related to using a Java identifier in the module name. The automatic jar name for my module should just be rcf since the jar name is rcf-1.0.jar. The error I'm getting is different also.
While deriving module description the contents of any
META-INF/services configuration files are mapped to provides
declarations.
The packages scanned for the services are the ones containing class files.
Also, the package name for individual classes is derived from their fully qualified name. From the shared logs com.username.rcf.server shall be the expected package name for the service to be provided and this shall turn into
provides x.y.z.TestCmdChainInterface with com.username.rcf.server.TestCmdChain
Seems like there is no such package com.username.rcf.server existing in your module.

Unable to compile the com.google.gwt.thirdparty.guava.common.base.Optional package of gwt-dev jar

I would like to use the Optional class of guava jar. I am able to use it in my project.But, in the gwt-dev jar the Optional class has already been there in the package com.google.gwt.thirdparty.guava.common.base.Optional. So, I don't want to use the guava jar for just using the Optional class. So, I am trying to use the Optional class of gwt-dev jar.
Steps which I have done:
I have created com.google.gwt.thirdparty.guava.common.base package in my project
In that package I have created the Base.gwt.xml file.
<?xml version="1.0" encoding="utf-8"?>
<!-- semi-autogenerated module descriptor -->
<module>
<source path="">
</source>
</module>
I have included the Base.gwt.xml file in my gwt.xml file.
Though I have done the above steps I was not able to compile the code. I am getting the below exception:
No source code is available for type com.google.gwt.thirdparty.guava.common.base.Optional; did you forget to inherit a required module?
Any suggestions would be appretiated.
You shouldn't be using com.google.gwt.thirdparty.* - those are internally repackaged jars. There's no guarantee they'll be there in the next version of GWT - in fact, I'd expect them (at least the Guava part) to be removed in favor of "vanilla" Guava, as suggested in this thread. To further reinforce this there's no source attached for them in the gwt-dev.jar (as you've experienced), so you can't use them in your client-side code.
Please use the normal dependency on Google Guava - the GWT compiler will only compile in the parts of Guava that you are using (especially if you just inherit com.google.common.base.Base) and prune out the rest.

Categories