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.
Related
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)
Very simple use case, I am using Eclipse Oxygen 4.7.3a that includes support from Java 9. I have two projects that are Java 9 projects:
- projectOne
| - src
| - module-info.java
| - com
| - package1
| - first
| Classificator.java
- projectTwo
| - src
| - module-info.java
| - com
| - package2
| - second
| Classifiable.java
I want to use the Classifiable class inside the Classificator, so I try to import the second module into the first project.
module-info.java Project 1:
module projectOne {
requires projectTwo;
}
module-info.java Project 2:
module projectTwo {
}
Eclipse is giving me the error:
projectTwo cannot be resolved to a module
Do I have to gather all my Java projects under one "main project" in order to let Eclipse know that all those modules are usable inside it? Or have I missed something else?
No, you don't need them to be in the same directory. Ideally, your project-one module defines some uses, which are implements by your project-two module (or vice-versa). Get the runtime implementation of your used interfaces. For this, both jars/classes must be on the module path.
For further information on module build, multi module builds,... you can refer to this link. Even if you do not use gradle, its tutorial on java 9 module build is quite interesting and gives some insight.
While wiring as a service is certainly a viable approach (as described in the other answer), let me add that requires can be made to work, too, of course.
The thing that was probably missing from the first approach is: Eclipse still needs to know where to look for modules. In real world projects this will typically be mediated by your build tool of choice plus a plug-in like m2e or buildship.
If no such plug-in is used, a normal project dependency should be added to the Build Path of project projectOne in order to make project projectTwo visible. Once the project is on the Build Path the module defined by the project can be resolved in references in module-info.java.
I have to write a java project for a course and our professor requires us to use CMake as a build tool.
In my Entry Point (main class) I want to use a class located in another package. While trying to compile it I get the following error message (attached below).
Using this wildcard import in Foo.java
import xxx.util.*;
helped, but I'm sure that this isn't the most elegant to achieve my goal.
I'm not able to figure out how to solve this problem as I get no problems using another built tool (maven) or manually compiling it. But as I must use CMake I hope that anyone out there had similar problems using this kind of project setup and is able to help me.
I listed all the relevant project information (structure, affected classes, CMakeLists.txt, ...) below.
Feel free to ask questions in the comments section in order to clear off any ambiguities.
Thank You!
Relevant Project structure:
.
|-- CMakeLists.txt
|-- build
|-- resources
| |-- MANIFEST.MF
| \-- sqlite.jar
|-- src
| \-- xxx
| |-- gui
| | \-- Foo.java
| \-- util
| |-- Bar.java
Foo.java:
package xxx.gui;
import xxx.util.Bar;
public class Foo {
public static void main(String[] args) {
Bar bar = Bar.getBar(); //singleton
}
}
Bar.java:
package xxx.util;
public class Bar {
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(xxx LANGUAGES Java)
find_package(Java 1.8 REQUIRED COMPONENTS Development)
include(UseJava)
file(GLOB_RECURSE SOURCES "src/*.java")
file(GLOB_RECURSE JARS "resources/sqlite*.jar")
add_jar(DataFX ${SOURCES} MANIFEST ./resources/MANIFEST.MF INCLUDE_JARS ${JARS}
ENTRY_POINT xxx.gui.Foo)
MANIFEST.MF:
Class-Path: ../resources/sqlite.jar
Relevant Error message:
gui/Foo.java error: package xxx.util does not exist
import xxx.util.Bar;
^
gui/Foo.java error: cannot find symbol
Bar bar = Bar
^
symbol: class Bar
location: class Foo
...
Seems quite logical to get this error. CMake as the other make utilities depend heavily on the order in which the classes get compiled.
From the makefile you've attached it's obvious that the make's entry point is 'xxx.gui.Foo' package problem is though that Foo.java has a dependency to Bar.java which at this point has not been compiled yet.
If you switch the order you could get this to work without any issue, that is Bar.java getting built before Foo.java.
All in all it's a good idea if you ever need to use make files to keep all the utility classes and in general all the classes with as little dependencies to other packages/classes on the top of you make file in order to minimize such problems.
Now, answering as to why you don't get this problem with Maven or javac, in case of the former it's a build tool thus it has a way no resolving all those on it's own. In case of the latter, I suppose that you already had both of the classes compiled hence why it's worked.
I hope the above solves your question.
I've inherited code that uses:
import com.jgoodies.forms.factories.FormFactory;
I'm attempting to build the project.
I've added the jgoodies-forms-1.8.0*.jar files to a 'lib' directory that I made at the same level as the 'JRE System Library' and 'Referenced Libraries' within my Project.
/project
|-- src
| `--(...)
|-- JRE System Library
|-- Referenced Libraries
`-- lib
|-- jgoodies-forms-1.8.0-javadoc.jar
|-- jgoodies-forms-1.8.0-sources.jar
|-- jgoodies-forms-1.8.0-tests.jar
`-- jgoodies-forms-1.8.0.jar
At the source files that use FormFactory, Eclipse Luna 4.4 tells me that:
The import com.jgoodies.forms.factories.FormFactory cannot be resolved.
I understand that this is because jgoodies RELEASE-NOTES.txt:
CHANGES IN 1.6.0
o Renamed FormFactory to FormSpecs.
I figured I could just change "FormFactories" to "FormSpecs" but I get:
The import com.jgoodies.forms.factories.FormSpecs cannot be resolved.
Your package is wrong. According to this FormSpecs is located in com.jgoodies.forms.layout package in 1.8. Assuming that you have the libraries correctly set-up in Eclipse, changing the package should work.
Or just remove the unresolved import and hit CTRL+SHIFT+O to automatically organize the import statements.
Given a Maven artifact (groupId:artifactId:version), how can I programmatically query its dependencies? (I don't need actually retrieve any artifacts, just the dependency information.)
Edit to add I'd like to do this outside of a Maven plug-in, and I'd like to build up a dependency graph.
If you're using a maven plugin (ie: extend AbstractMojo), you can do the following:
/**
* #parameter expression="${project}"
*/
private org.apache.maven.project.MavenProject mavenProject;
List<org.apache.maven.model.Dependency> depmgtdeps = mavenProject.getDependencyManagement().getDependencies();
That will give you the actual dependency objects that it detects. The MavenProject class has a bunch of other methods as well for reading various pom related things. However, I don't believe this works outside a plugin, or at least, I've never tried to do it.
I found these two links helpful..
A Maven Plugin for retrieving the dependencies
Using Eclipse Plugin
The following groovy script uses ivy to resolve dependencies
import groovy.xml.NamespaceBuilder
// Main program
// ============
def ant = new AntBuilder()
def ivy = NamespaceBuilder.newInstance(ant, "antlib:org.apache.ivy.ant")
ivy.resolve(
inline:true,
keep:true,
conf:"default",
organisation:"org.springframework",
module:"spring-core",
revision:"3.1.1.RELEASE",
)
ivy.report(toDir:"reports")
Generates a HTML report and a graphml file:
|-- report.groovy
|-- reports
| |-- ivy-report.css
| |-- org.springframework-spring-core-caller-default.graphml
| `-- org.springframework-spring-core-caller-default.html