Using the Yoctopuce library with Java modules

Using the Yoctopuce library with Java modules

A customer recently asked us whether our Java library was compatible with Java 11. The answer is yes. We are always careful to remain compatible with current versions, while maintaining backward compatibility. In the present case, you can use our library with all Java versions starting with version 6. However, Java 9 introduces Java Platform Module System (JPMS or Project Jigsaw) and, as we are going to see, there are a few additional steps when using our library with Java modules.

Java is a relatively old programming language but which is still evolving. Most changes in the last few years maintained backward compatibility and added only minor features to the language which you could use or not. Since Java 9, you can use Java Platform Module System (JPMS), which is a feature which radically changes the way in which classes are distributed in a .jar file.

The aim of JPMS is to allow the generation of compiled libraries in the .jar format, but while controlling more finely the Java classes which must be loaded when executing the application. The idea is to generate more and smaller .jar files instead of one large monolithic file. In the end, it allows you to create smaller executables by including only what is required. But this also allows you to more finely control the classes which are published in a .jar file.

A Java module is composed of Java code and of a module-info.java file. This file enables you to define the name of the module, the classes and/or packages which are published by this module, and the modules from which it depends.

For example, here is the declaration of a helloworld module which publishes the com.mycompagny.mypackage package and requires the anothermodule module to work.

module helloworld {
    exports com.mycompany.mypackage;
    requires anothermodule;
}



If another module wants to use the com.mycompagny.mypackage package, it must add requires helloworld; in its module-info.java file.

module mainmodule {
    requires helloworld;
}



Thanks to this file, Java can resolve the dependency tree and immediately check that all the classes are available. The Java source code doesn't evolve, you must still import the packages that you want to use with the "import" keyword.

To sum up, Java Platform Module System allows you to control much more precisely which classes are loaded by the Java Virtual Machine (JVM).

In this post, we are going to concentrate on what this implies when using our libraries with modules. If you want to know more about Java Platform Module System, you can read the Wikipedia page or Internet .

Using the Yoctopuce library with Java >= 9

There are three ways to use our library in a Java application:

  1. Adding the source files
  2. Adding the compiled version of our library in the Classpath
  3. Adding the compiled version of our library in the Module-path


Option 1: Adding the source files


It's the simplest solution: you only have to copy all the Java files in your project.

This solution enables you to completely control how to use the library. You can put it in a separate module, or directly in your application. As the code doesn't use new features, you can use it with all the versions of Java since version 6. As a bonus, the symbols are available in your debugger/IDE.

We provide the source code our the Java library on our web site or on GitHub. We recommend this solution because, whatever your Java version or your build system, our library will work.

Option 2: Using the yoctoAPI.jar file without JPMS


Even if JPMS was introduced in Java 9, you can still use the Classpath, as in Java 6, 7 and 8. In this case, you must simply add the yoctoAPI.jar file in the Classpath.

The yoctoAPI.jar file is the precompiled version of our library. It is included in the Binaries subdirectory of our library.

To add this .jar file to the Classpath, you must use the -cp option and add the path of the .jar file.

Here is for example the commands to compile and run a Java application which uses the Yoctopuce library:

javac -d outDir -cp ../YoctoLib.java.40924/Binaries/yoctoAPI.jar src/com/mycompany/app/App.java java -cp ../YoctoLib.java.40924/Binaries/yoctoAPI.jar:outDir com.mycompany.app.App



For these two commands, we add the ../YoctoLib.java.40924/Binaries/yoctoAPI.jar file to the Classpath with the -cp option. Note that you can pass several paths by separating them with the : character under Unix or the ; character under Windows.

Option 3: Using the yoctoAPI.jar file with JPMS


To use the precompiled version of our library in a project using Java modules, it's somewhat more complex.

First of all, let's say that for backward compatibility reasons, our yoctoAPI.jar file is not a Java module. It's a traditional .jar file without module-info. There is however a way to use it in a JPMS project.

You must first add the yoctoAPI.jar file to the Module-path with the --module-path option. As it is not a true module, the JVM adds it as an "unnamed module" and assigns it a name based on the .jar file name following to the rules below:

  • the ".jar" extension is ignored
  • version numbers are removed (Ex: myjar-1.2.3 -> myjar)
  • Non alphanumerical characters are replaced by dots


In our case, our "yoctoAPI.jar" library becomes therefore the "yoctoAPI" module.

Finally, you must add the "require yoctoAPI;" line in the module-info.java file of the module using our library.

For example, for an application composed of two modules main.app and another.module in which the another.module module uses our library, you must add the "require" line only in the another.module module.

module another.module { requires yoctoAPI; }



When running, the JVM goes through the dependency tree and determines that it must load our library.

Here are the commands to compile and run these two modules.

javac -d outDir --module-source-path Sources Sources/main.app/com/mycompany/app/App.java javac -d outDir --module-source-path Sources --module-path ../YoctoLib.java.40924/Binaries/yoctoAPI.jar Sources/another.module/com/mycompany/module/MyModule.java java --module-path outDir:../YoctoLib.java.40924/Binaries/yoctoAPI.jar -m main.app/com.mycompany.app.App



As you can see, it's very similar to the use of Classpath. You must simply use the --module-path option instead of the-cp option. Note that you can also pass several paths to the --module-path option by separating them with the : character under Unix or the ; character under Windows.

GitHub


You can find the source code of these two examples on GitHub: https://github.com/yoctopuce-examples/JPMS_examples

The version of the application which doesn't use JPMS is in the my-app-classpath subdirectory. It's the same application but implemented with two Java module in the my-app-modulepath subdirectory.

Conclusion

Our library is therefore compatible with all the Java versions since Java 6. For Java versions which support it, you can use our library in projects using Java modules.

Add a comment No comment yet Back to blog












Yoctopuce, get your stuff connected.