I try to use a word-segmentation software, I create a new java project named JNA, and import the required files into JNA dir, then I try to run it without any code modification, and MyEclipse warns me that:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'E://java//JNI//JnaTest_NLPIR//NLPIR': Native library (win32-x86-64/E://java//JNI//JnaTest_NLPIR//NLPIR.dll) not found in resource path ([file:/D:/javasoft/MyEclipse_workspace/JNA/bin/, file:/D:/javasoft/MyEclipse_workspace/JNA/lib/jna-4.0.0.jar])
I tried to:
create the same dirs and move NLPIR.dll to E:/java/JNI/JnaTest_NLPIR/, it didn't work.
move NLPIR.dll directly to JNA/bin or JNA/lib, but it didn't work, too.
I think that it is caused by the position of my NLPIR.dll. But I could not figure out how to fix it.
I would be grateful for any help or suggestions.
Ensure NLPIR.dll (and all its dependent libraries) is on %PATH%, or use -Djna.library.path=... to indicate the folder it's in.
Related
I have received the task, at work, to find a way to use some methods from an existent jar file in a Python project. I have very limited experience in Python, but I have worked with that specific jar file before (it is part of a project we are working on). I am not allowed to modify much of both projects, and they are required to be as independent as possible.
I have researched multiple ways to include the jar methods in Python. So far, I have tried Jython (which I cannot use because the Python project uses PyQt among other libraries, which force the use of CPython, if my understanding is correct), Pyjnius and JPype. JPype seems the most promising, but I cannot get it working either. I have pasted the my code below, slightly censored because I don't know how much I am allowed to share.
from jpype import *
import jpype.imports
try:
jpype.addClassPath("jars/sdk.jar") #the relative path to the jar file
jpype.startJVM(convertStrings=False)
java.lang.System.out.println(jpype.getClassPath()) #printing the classpath to check, the path is correctly pointing to the sdk.jar file
java.lang.System.out.println("Hello world") #just to check if jpype is installed correctly, works
jpype.imports.registerDomain("a")
from a.b.c.d.e.f.g.h import SomeClass #fails here
except OSError as err:
print(err) # ToDo: Remove print when done
pass
The error I am getting is that the module a.b.c.d.e.f.g.h.SomeClass could not be found. I have tried different ways to give the path (absolute path, relative path, place the jar in different places in the project and outside of it), but that doesn't seem to be the problem, as the path printed is the correct absolute path to the jar file.
Also, the jar is used in other (Java) projects and it works. It is created using maven package (using IntelliJ, if it is relevant, and the same Java version as the one used by the JPype JVM). In the Java projects, the import would be:
import a.b.c.d.e.f.g.h.SomeClass;
I have copied this and just transformed the syntax into Python.
I have also tried to create the class with JObject (which I probably didn't do right anyway) and also tried the older syntax (to my understanding) with JPackage. For the JPackage way, I am getting the exception that the package a.b.c.d.e.f.g.h.SomeClass.someMethod is not Callable, which to my understanding is an equivalent exception to the one I'm getting using jpype imports. I have already gone through all the questions I could find here with similar problems, but none of those solutions have helped me.
Can anyone suggest some possible solution? Or can anyone see what I'm doing wrong? Suggestions of other possibilities to replace JPype are also welcomed. If there is any clarification needed, I will edit the question.
The only thing that seems likely if the jar is on the classpath and failed to import would be for there to be some missing dependency. You have two other ways to try loading the class which may provide additional diagnostics.
jpype.JClass("a.b.c.d.e.f.g.h.SomeClass")
and
jpype.JClass("java.lang.Class").forName("a.b.c.d.e.f.g.h.SomeClass")
The first is manually loading a class by full class specification. It is mechanically what is happening under the import. The second is calling for Java to load the class (bypassing all of JPype). It returns a java.lang.Class which can be passed to JClass to make a wrapper.
Common failures include missing a jar or native library, attempting to start JPype from within a module and having the wrong relative path, error in initialization of the class due to missing resource. JPype is just calling JNI calls, so if everything is fine on Java end it should work. Given that you checked the java.class.path System variable, it has to be something to do with class resources.
The JPype user manual has an alternatives section if you would like to try to find another package. Most of the alternatives with the exception of PyJnius appear to be unmaintained.
I have dependencies on org.bytedeco:opencv:4.1.2-1.5.2 that is in turn added to the project by
<groupId>org.datavec</groupId>
<artifactId>datavec-data-image</artifactId>
<version>${datavec.version}</version>
And for the needs of datavec-data-image the open-cv is loaded well and all the internal open-cv actions are executed.
Then, I'd like to do some open cv executions explicitly. I use a class from https://github.com/rostrovsky/pdf-table that does this stuff:
public class PdfTableReader {
private TableExtractor extractor;
private PdfTableSettings settings;
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
and it fails with
Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java412 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at pdftable.PdfTableReader.<clinit>(PdfTableReader.java:32)
at pdftable.ExtractSyzlekFromPdf.main(ExtractSyzlekFromPdf.java:12)
What I should to do to make this explicit javacv part to work with datavec image code without doing the double explicit open-cv installation to some location on my pc and setting up the java.library.path explicitly? At least the datavec image code obtains it somehow without this explicit set up.
I also tried to follow up this answer: https://stackoverflow.com/a/57515132/1759063 but with no success (if I understand right, they use the dependency that ships native libs in a cross-platform way, i.e. ships all platform binaries and the needed one is used on the right platform). I suppose there should be a way to make java.library.path to be dynamically updated if the open-cv native binaries packed to the maven dependencies are attached to the project. But how?
If DL4J guys can explain how to use the javacv part there correctly, that would be perfect.
The Java API of OpenCV found in the org.opencv package doesn't come with a loader, so the libraries need to be loaded by something else externally. In the case of the JavaCPP Presets for OpenCV, the libraries and wrappers are all bundled in JAR files and we can call Loader.load(opencv_java.class) to load everything as documented here:
https://github.com/bytedeco/javacpp-presets/tree/master/opencv#documentation
JavaCV, Deeplearning4j, and DataVec do not use that Java API of OpenCV, they use the API found in the org.bytedeco.opencv package, which loads everything automatically, so they do not need to call anything.
I would like to make my OptaPlanner project run on the module path.
I created an example repository (mwkroening/optaplanner-modulepath-example) based on the cloud balancing demo in the docs.
The example project is running well on the classpath but there is an issue I can't workaround when trying to make it run on the module path. You can see the progress so far in PR #1.
The scoreDrl specified in the solverConfig.xml fails to load with the following exception:
Exception in thread "main" java.lang.IllegalArgumentException: The scoreDrl (io/github/mwkroening/optaplannermodulepathexample/cloudBalancingScoreRules.drl) does not exist as a classpath resource in the classLoader (jdk.internal.loader.ClassLoaders$AppClassLoader#7c16905e).
at org.optaplanner.core#7.18.0.Final/org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryConfig.java:519)
at org.optaplanner.core#7.18.0.Final/org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildScoreDirectorFactory(ScoreDirectorFactoryConfig.java:351)
at org.optaplanner.core#7.18.0.Final/org.optaplanner.core.config.solver.SolverConfig.buildSolver(SolverConfig.java:255)
at org.optaplanner.core#7.18.0.Final/org.optaplanner.core.impl.solver.AbstractSolverFactory.buildSolver(AbstractSolverFactory.java:61)
at io.github.mwkroening.optaplannermodulepathexample/io.github.mwkroening.optaplannermodulepathexample.App.main(App.java:14)
I got a similar exception before when calling SolverFactory.createFromXmlResource.
My workaround for that problem was instead calling:
SolverFactory.createFromXmlInputStream(
App.class.getResourceAsStream("cloudBalancingSolverConfig.xml"));
I looked at PLANNER-883 and psiroky/optaplanner-cloudbalancing-jdk9, but I think a classpath resource was used in that case and not one on the module path.
How could I resolve this issue?
Perhaps I should open an issue instead of posting this here, right?
There's an overloaded method of every SolverFactory.createFrom*(...) that accepts a classloader: SolverFactory.createFrom*(..., classloader). That class loader isn't just used for loading the XML resources, but also the DRL resource.
So try:
SolverFactory.createFromXmlResource("/.../cloudBalancingSolverConfig.xml",
App.class.getClassLoader())
I haven't tested this out yet myself, but if it works, I'd love to see this added to the "jigsaw" section in the manual (PR welcome :).
A little background:
I have a java application that needs to talk to a third party hardware on mac. They have given me the sdk but it is not in Java. So I am trying to make jnilib that will act as a bridge between my java application and the SDK.
The issue:
I have made a small sample jnilib that talks to the SDK but when I try to use it in my java program I get the following error
Exception in thread "main" java.lang.UnsatisfiedLinkError: /Users/john.doe/Desktop/eclipse/workspace/Lesson13_Jni_Smart7/bin/libSmartTest7.jnilib: Library not loaded: build/Release/SMARTResponseSDK.framework/Versions/A/SMARTResponseSDK Referenced from: /Users/john.doe/Desktop/eclipse/workspace/Lesson13_Jni_Smart7/bin/libSmartTest7.jnilib
Reason: image not found
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1827)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1742)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1045)
at com.learning.lesson13.JniSmart7.<clinit>(JniSmart7.java:6)
From the error it looks like my libSmartTest7.jnilib is looking for the library SMARTResponseSDK.
What I have tried
I know where the library SMARTResponseSDK is on my Mac. I tried copying it over to my working folder in eclipse but I still get the error. I have tried using the -DJava.library.path but I still get the error.
Any ideas on what the best possible approach would be.
Once you are inside JNI code, it no longer matters what java.library.path points at.
Once you are inside JNI code, all you can do is to make sure library is visible to your code via LD_LIBRARY_PATH/DYLD_LIBRARY_PATH, or you can dynamically load your library file from any location you like.
So, for you, I suggest to take a look here:
dynamic loading of library in JNI - http://jnicookbook.owsiak.org/recipe-No-018/
Calling code from shared library (adapter pattern) - http://jnicookbook.owsiak.org/recipe-No-023/
You can also benefit from compilation flags while building your JNI library and use rpath.
When i am trying to run my program it is giving the following error
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jacob-1.14.3-x86 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1030)
at com.jacob.com.LibraryLoader.loadJacobLibrary(LibraryLoader.java:184)
at com.jacob.com.JacobObject.<clinit>(JacobObject.java:108)
at javaSMSTest.main(javaSMSTest.java:18)
please help
From the Javadoc:
Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native.
It is an error related to JNI. loadJacobLibrary is trying to load the native library called jacob-1.14.3-x86 and it is not found on the path defined by java.library.path. This path should be defined as a system property when you start the JVM. e.g.
-Djava.library.path=<dir where jacob library is>
On Windows, the actual native library file will be called jacob-1.14.3-x86.dll while on Linux it would be called libjacob-1.14.3-x86.so
You need the jacob-1.14.3-x86 library on your java library path.
On windows, this would be jacob-1.14.3-x86.dll.
This is a binary file which is used by java to run native methods. It's probably required by some library (jar) you're using.
In here you can see not only a jar, but also the binary required by the jar. Pick the one for your platform.
To quote http://www.velocityreviews.com/forums/t143642-jni-unsatisfied-link-error-but-the-method-name-is-correct.html:
There are two things that cause UnsatisfiedLinkError. One is when
System.loadLibrary() fails to load the library, the other is when the
JVM fails to find a specific method in the library. The text of the
error message itself will indicate which is the case...
The error which you describe clearly cannot find the library at all. As the others have said, include it in your Java library path.
The other error—when the library can be found but the method within the library is not found—looks as follows:
java.lang.UnsatisfiedLinkError: myObject.method([Ljava/lang/Object;)V
In this case you either have the wrong method name, or will have to go back and add the method and recompile the code...