Spring Boot 2.6.3 and Java Modules - java

I'm trying to build a spring boot (2.6.3) application with java modules (java 17) and gradle(7.4).
right now my folder structure looks like this:
|- build.gradle.kts
|- settings.gradle.kts
|- src
|- main
|- java
|- com.my.package
|- Application.java
|- module-info.java
my module:
module com.my.package {
requires spring.boot;
requires spring.boot.autoconfigure;
requires spring.boot.actuator.autoconfigure;
opens com.my.package;
}
The application class:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I already found out that I had to use opens with my package instead of just using exports. If I where to use exports I would get this error:
java.lang.IllegalAccessException-->module com.my.package does not open com.my.package to unnamed module #1a482e36
Now when I run this with the opens I'll get this error here:
java.lang.IllegalAccessError-->superinterface check failed: class com.my.package.Application$$EnhancerBySpringCGLIB$$917dba7a (in module com.my.package) cannot access class org.springframework.context.annotation.ConfigurationClassEnhancer$EnhancedConfiguration (in unnamed module #0x1623b78d) because module com.my.package does not read unnamed module #0x1623b78d
I've read things about using the -classpath JVM argument. But I am not quite certain which path to put there. And to be frank I am trying to find a solution that works without any arguments that need to be passed. So that the experience is similar to spring without (java)modules.
It'd be great if someone could help me to understand what I am doing wrong here. I'm obviously new to java modules and trying to wrap my head around things.
Thanks in advance!
Cheers,
Daniel

As dan1st was pointing out --add-reads com.my.package=ALL-UNNAMED did the trick. A more verbose explanation can be found in the question dan1st was sharing
I didn't even think of the option that it could be IDE related. (I am using IntelliJ)

Related

Can not use JNA: com.sun.jna.Library is not accessible

I am trying to use JNA, because I want to work with a .dll that was written in c++ and the rest of my code is in Java. However, if I try to import the JNA classes Eclipse claims "The type com.sun.jna.Library is not accessible".
My IDE seems to see that JNA is somehow in my libraries because when I type "import com.sun.j" it proposes .jna and the other packages in the .jar files to me.
I have created a seperate Project to see if it works there, but it just doesnt work.
I have downloaded the latest .jar (jna-5.8.0.jar and jna-platform-5.8.0.jar) files from the jna Github (https://github.com/java-native-access/jna/blob/master/README.md ) and I have added them to the class path via project-> configure Buildpath -> add External JARs
I am using Eclipse with javaSE-13.
package Testtest;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
Package strcuture:
Test
|-- src
| |-- TestTest
| | |-- Main.java
| |-- module-info.java
|-- JRE System Library [JavaSE-13]
|-- Referenced Libraries
|-- jna-5.8.0.jar
|-- jna-platform-5.8.0.jar
As #greg-449 mentioned in the comments, you have a modular project, indicated by the presence of the module-info.java file in your src directory (package root).
You have three options here:
run on (or change your project compatibility level to) JRE 8 or earlier which ignores module-info.java
delete the module-info.java module descriptor in order to run your program without modules
edit your module descriptor (module-info.java) to add the directive requires com.sun.jna. If you're using jna-platform then also add requires com.sun.jna.platform.
In addition, if you extend any JNA classes like Structure or PointerType you will need to open any packages in your project containing those subclasses to com.sun.jna because they use reflection to access your subclasses. (There are multiple options here, but open TestTest to com.sun.jna is the closest to JDK8 behavior.). I am aware this is just a test setup, but consider a reverse-DNS-style package name and module descriptor.
If you are using JNA on the module path you may prefer to use the jna-jpms-5.8.0 and jna-platform-jpms-5.8.0 JARs as your dependencies, as they have their own module descriptors.

Making Maven and module-info work together

I have a project(Java 12) with several Maven dependencies, and now I'm trying to add module-info file like
module mymodule {
requires java.net.http;
}
But if I do this all Maven dependecies (in pom.xml) become invisible for code, and compiler throws errors like java: package org.openqa.selenium.safari is not visible
(package org.openqa.selenium.safari is declared in module selenium.safari.driver, but module mymodule does not read it)
Is it possible to make them work together?
The new module info ist not congruent with the information in the pom.xml. Robert wrote a good article about the differences of both systems:
https://www.sitepoint.com/maven-cannot-generate-module-declaration/

Calling a Non Module Class from a Module Class in java 9

I am trying to call a non-module class from a module class. I have created a folder structure
moduledemo > allclasses > moduleC > packageC > MyMethods.class
is the path to my module class file
moduledemo > moduleC > packageC > MyMethods.java
and
moduledemo > nomodule > packageD > DemoNoModule.class
is the no module class that I am calling from MyMethods.java
I am able to compile the DemoNoModule file. I am able to compile MyMethods.java into allclasses folder moduleC.
When I am running MyMethods I am getting error moduleC not found. Can anyone update? I am using the following command to run
java --module-path allclasses -m moduleC/packageC.MyMethods
Both files code -> Non-Module Class
package packageD;
public class DemoNoModule {
public void showD() {
System.out.println("this is show of D in No Module");
}
}
Module class calling class
package packageC;
import packageD.*;
public class MyMethods {
public static void main(String s[]) {
DemoNoModule d=new DemoNoModule();
d.showD();
}
}
Module info in module C
module moduleC {
exports packageC;
}
On one hand, the moduleC(mind improving naming?) is a named module.
While on another, the "no module class" termed by you is nothing but as stated by Alan a class present on the classpath. The classes present on the classpath during the execution are part of an unnamed module in JPMS.
Quoting the documentation further:-
The unnamed module exports all of its packages. This enables
flexible migration... It does not, however, mean
that code in a named module can access types in the unnamed module. A
named module cannot, in fact, even declare a dependence upon the
unnamed module.
This is intentional to preserve the reliable configuration in the module system. As stated further :
If a package is defined in both a named module and the unnamed module
then the package in the unnamed module is ignored. This preserves
reliable configuration even in the face of the chaos of the class
path, ensuring that every module still reads at most one module
defining a given package.
Still, to make use of a class from the unnamed module in your named module moduleC, you can follow the suggestion of making use of the flag to add ALL-UNNAMED module to be read by modules on the module path using the
following command:
--add-reads <source-module>=<target-module> // moduleC=ALL-UNNAMED
As a special case, if the <target-module> is ALL-UNNAMED then
readability edges will be added from the source module to all present
and future unnamed modules, including that corresponding to the class
path.
PS: Do take into consideration the highlighted portion(above) of the documentation as you do so.
Also note the long-term solution would be to revise your design here, for which you can plan to move your code in the class DemoNoModule into an explicit module or package it separately to be converted into an automatic module.
Java 9 programs are supposed to be modular. That is how I understood jigsaw in JDK-9. So, IMHO, you'll have to 'wrap' your packageD in another module and in the module-info for moduleC write requires moduleD. Also moduleD should export packageD.
ALL-UNNAMED is added for backward compatibility, and I suppose it will be removed in some point of Java evolution.

Method getModule returning unnamed module for class in named module

I just started to have a look at the Java 9 module system and I was wondering whether it is possible for a class to know in which module it is located.
Therefor I created the following module
module de.test {
exports de.test.myexport;
}
and compiled a jar file that looks like
> jar --print-module-descriptor --file=Java9Test-1.0-SNAPSHOT.jar
de.test
requires mandated java.base
exports de.test.myexport
In package de.test, I have a class called Overview where I'm calling
Module module = Overview.class.getModule();
However, the returned module object is unnamed and has no ModuleDescriptor.
Am I using getModule() correctly here, or is there any other way to load the module of a class?
I'm using JDK 9 build 120 on OS X.
All JARs on the class path (with java --class-path ...) get bundled into the same so-called unnamed module, regardless of whether they are "a real module" or "just a JAR". When you ask a class from such a JAR for its module, you get the result you describe.
Try putting the JAR on the module path (with java --module-path ...) and Class::getModule should return what you expect.

Cannot find main class to run .jar, from Sbt-Assembly

MyProject/build.sbt
mainClass in assembly := Some("Boot")
MyProject/Boot.scala
package src.main.myproject
object Boot extends App { ... }
Other Project Files:
MyProject/src/main/scala/myproject/someFile.scala
Running the jar returns the error:
Error: Could not find or load main class Boot
Is there a problem with my project structure?
Your Boot is in src.main.myproject, so the mainClass should be src.main.myproject.Boot
Off topic in terms of the question, but it doesn't seem conventional that src.main is part of your package structure though, normally scala src directory of sbt is set to src/main/scala

Categories

Resources