StreamSource - which module for module-info? - java

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.

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.

hibernate.cfg.xml not found (intellij/maven)

So I am running a hibernate Project in intellij but since I added a module-info hibernate isn't finding the config.
enter image description here
As you can see above the config is in resources where it's supposed to be in a maven project.
Removing the module-info doesnt change anything.
This is my module-info:
module ProjektRechnungsprogramm {
requires java.persistence;
requires java.sql;
requires org.hibernate.orm.core;
requires java.naming;
requires net.bytebuddy;
requires org.hibernate.commons.annotations;}
Even if I try getClass.getResource("hibernate.cfg.xml") it is returning null.
You have placed your config in utils directory so get resource using
getClass.getResource("Utils/hibernate.cfg.xml")

Java 9: run legacy jar

I have a jar built before Java 9. I'm trying to run a class that is in that jar using Java 9.
From all I read about automatic modules, this should work:
java -p lib/Legacy-1.3.0.jar -m Legacy/com.blah.MyClass
But instead I get this:
Error: Unable to initialize main class com.blah.MyClass in module module Legacy
Caused by: module Legacy: java.lang.NoClassDefFoundError
Yes, com.blah.MyClass is in Legacy. Can I run a class from an automatic module? Why is the word module repeated twice in that error message above?
If I run java --list-modules -p lib/Legacy-1.3.0.jar I see:
Legacy#1.3.0 file://path/to/jar/Legacy-1.3.0.jar automatic
If I run jdeps --generate-module-info . lib/Legacy-1.3.0.jar, I get:
module Legacy {
requires java.logging;
requires transitive java.activation;
requires transitive java.xml;
requires transitive java.xml.bind;
requires transitive java.xml.ws;
exports com.blah;
}

How to use 3rd party library in Java9 module?

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.

How many unnamed modules are created in Java 9?

I am trying to understand how JPMS works.
From here
The classpath is not completely gone yet. All JARs (modular or not)
and classes on the classpath will be contained in the Unnamed Module.
Similar to automatic modules, it exports all packages and reads all
other modules. But it does not have a name, obviously. For that
reason, it cannot be required and read by named application modules.
The unnamed module in turn can access all other modules.
Please, note ...on the classpath will be contained in the Unnamed Module. Module is singular.
From here
For compatibility, all code on the classpath is packaged up as a
special unnamed module, with no hidden packages and full access to the
whole JDK.
Again unnamed module. Module is singular.
Do I understand right that there is always only one unnamed module in JPMS? Does it mean that applications that were developed before Java9 and not updated for Java9 will be loaded as one unnamed module?
Do I understand right that there is always only one unnamed module in JPMS?
In short
Generally speaking, no. But let's put it this way: If you place some or even all JARs on the class path and your application does not create class loaders to load any additional content, then there is only one unnamed module you need to care about.
In more detail
Every ClassLoader has its own unnamed module that it uses to represent classes that it loaded from the class path. This is necessary because the module system requires everything to be in a module.
As nullpointer's answer explains in detail, an application will by default use three separate class loaders. It is possible that it might spin up its own class loaders, for example to load plugins. If it doesn't do that, though, all application code will end up in the system/application class loader and hence in the same unnamed module. That's why there is typically only one you need to care about.
Does it mean that applications that were developed before Java9 and not updated for Java9 will be loaded as one unnamed module?
This has nothing to do with whether code (application, frameworks, libraries) targets Java 9 - it only depends on which path you place a JAR, on the class path or the module path.
If it's on the class path, it ends up in the unnamed module together with other class path content. This is true for plain JARs without module descriptor but also for modular JARs that contain one.
If it's on the module path, it gets its own module. If it's a modular JAR, it gets an explicit module as those described throughout the State of the Module System - plain JARs get turned into automatic modules (note the plural: one automatic module per JAR).
Do I understand right that there is always only one unnamed module in JPMS?
Yes, there is one unnamed module. The unnamed module is very similar to the existing concept of the unnamed package.
In implementations of the Java SE platform that use a hierarchical file system for storing packages, one typical strategy is to associate an unnamed package with each directory; only one unnamed package is observable at a time, namely the one that is associated with the "current working directory". The precise meaning of "current working directory" depends on the host system.
Does it mean that applications that were developed before Java9 and not updated for Java9 will be loaded as one unnamed module?
Yes, for those jars placed on the classpath would be treated as a single unnamed module. The bottom up migration with the concept of unnamed modules illustrates this with a similar example as:
Suppose, e.g., that the application shown above had originally been
built for Java SE 8, as a set of similarly-named JAR files placed on
the class path. If we run it as-is on Java SE 9 then the types in the
JAR files will be defined in the unnamed module.
The actual question that can arise here is
Which class loader is the unnamed module associated?
The State of Module System about unnamed module states a clarification instead about this.
Every class loader, it turns out, has its own unique unnamed module,
which is returned by the new ClassLoader::getUnnamedModule method.
If a class loader loads a type that is not defined in a named module then
that type is considered to be in that loader’s unnamed module, i.e.,
the getModule method of the type’s Class object will return its
loader’s unnamed module. The module colloquially referred to as “the
unnamed module” is, then, simply the unnamed module of the application
class loader, which loads types from the classpath when they are in
packages not defined by any known module.
The ClassLoader as revised in Java-9 states that:
The Java run-time has the following built-in class loaders:
Bootstrap class loader: The virtual machine's built-in class loader...
Platform class loader: ...
To allow for upgrading/overriding of modules defined to the platform
class loader, and where upgraded modules read modules defined to class
loaders other than the platform class loader and its ancestors, then
the platform class loader may have to delegate to other class loaders,
the application class loader for example. In other words, classes in
named modules defined to class loaders other than the platform class
loader and its ancestors may be visible to the platform class loader.
System class loader: It is also known as application class loader and is distinct from the platform class loader. The system
class loader is typically used to define classes on the application
class path, module path, and JDK-specific tools. The platform class
loader is a parent or an ancestor of the system class loader that all
platform classes are visible to it.

Categories