I'm going crazzy with Eclipse. I writing simple test class which uses external jar. which uses native library .dll
When I Running from Eclipse, command Run.
Here my stack trace:
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Program Files\YAZ\bin\yaz4j.dll: The specified procedure could not be found
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1939)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1864)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854)
at java.lang.Runtime.loadLibrary0(Runtime.java:845)
at java.lang.System.loadLibrary(System.java:1084)
at org.yaz4j.Connection.<clinit>(Connection.java:56)
at ru.Test.testConnection(Test.java:20)
at ru.Test.main(Test.java:15)
But when I run this code from console like this
java -cp "bin;C:\Program Files\YAZ\java\yaz4j.jar" ru.Test
Everything works perfect!
It's the same code. How is it works in console and not works in Eclipse?
here how I plugin this referenced jar to my project in Eclipse:
The messages you get when native methods fail to link are dreadful. I can think of several root causes that might give this message:
The DLL isn't loading some other dependent DLL when loaded from Eclipse. This is governed by the Windows PATH environment variable, which could be different when you're running in Eclipse.
It's a 32-bit DLL, and you're running with a 64-bit JVM under Eclipse, but 32-bit from the command line (or vice versa.)
I have been struggling with exactly the same problem for some days now trying to use the YAZ toolkit in my project. The thing was that native libraries get loaded correctly on various test computers, but not on my personal PC.
In short: the cause of the problem is that the JVM loads the incorrect libxml2.dll and libxslt.dll dependent libraries.
When I launch the JVM from the IDE, it starts looking in the following places for the native libraries:
(jdk_home_dir)\jre\bin. Somehow this step is skipped on all other test computers when loading dependent libraries (other than the main yaz4j.dll). This way the test computers don't load the wrong dll's.
(jdk_home_dir)\bin
if you set the -Djava.library.path parameter, it will look in that dir at this step
%SystemRoot%\system32
%SystemRoot%
The working directory set for the project, if any. This step is skipped on my personal PC, for unknown reasons, but works on all other test computers.
the %path%
I have figured out this by using Process Monitor. Note that steps 1 and 2 may be interchanged.
The YAZ toolkit main DLL named yaz4j.dll makes secondary calls to other dll's in the toolkit: libxml2.dll and libxslt.dll (among others).
My JVM finds them in the (jdk_home)\jre\bin directory. They seem to be bundled with Java and they are obviously different from the ones in the YAZ toolkit.
That means that procedures that are being called by yaz4j.dll could not be found in those dll's. This way the UnsatisfiedLinkException is thrown.
My JVM seems to be always searching firstly for native libraries in (jdk_home)\jre\bin regardless of the environment %path% variable or the -Djava.library.path switch.
Replacing the dll's in that dir may break some JVM native functionality so I wouldn't recommend that.
So the last step that needs to be done is to figure out how to make the JVM load the correct libxml2.dll and libxslt.dll libraries.
Recompiling yaz4.dll to make it point to renamed libxml2.dll and libxslt.dll might be a potential solution.
I had same problem, you need to have JDK not JRE build path library
Related
Hello This is my code :
if (isWindows()) {
//System.setProperty("jna.library.path", getClass().getResource("/resources/win32-x86").getPath());//netbeans WinOs
System.setProperty("jna.library.path", System.getProperty("user.dir").toString()+File.separator+"Desktop");//compiler WinOs
} else if (isMac()) {
//System.setProperty("jna.library.path", getClass().getResource("/resources").getPath());//netbeans MacOs
System.setProperty("jna.library.path", System.getProperty("user.dir").toString()+File.separator+"Desktop");//compiler MacOs
} else {
System.out.println("Your OS is not support!!");
}
Why I have 2 PATH (don't understand because for add an image i have only one Path) by OS, one for use with IDE and another for use with .JAR ?
I just realized, that when I'm use windows and I run the project (from netbeans) the "Library" load and I get the information, but when I compile and I launch my .jar I get error :
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: %1 is not a valid Win32 application.
My Structure
It is correct?
On mac only work with this command : java -jar "/System/Volumes/Data/Users/hugoclo/NetBeansProjects/Prezauto/dist/Prezauto.jar"since Terminal. If click on jar i have message error : Not Found .....
Sorry about my English,
There can be two reasons for the "why". While Java is cross-platform, JNA (which relies on some native code) must necessarily behave differently on different operating systems. Particularly in the case of loading DLLs (Windows) or dynamic libraries (OSX), you don't want to mix and match. Because it might be possible to have a dll with the same name compiled for different operating systems, JNA's Getting Started page identifies standard locations for these libraries:
Make your target library available to your Java program. There are several ways to do this:
The preferred method is to set the jna.library.path system property to the path to your target library. This property is similar to java.library.path, but only applies to libraries loaded by JNA.
Change the appropriate library access environment variable before launching the VM. This is PATH on Windows, LD_LIBRARY_PATH on Linux, and DYLD_LIBRARY_PATH on OSX.
Make your native library available on your classpath, under the path {OS}-{ARCH}/{LIBRARY}, where {OS}-{ARCH} is JNA's canonical prefix for native libraries (e.g. win32-x86, linux-amd64, or darwin). If the resource is within a jar file it will be automatically extracted when loaded.
In your code, you appear to be trying to do the first option (setting the jna.library.path) to include the user's desktop. That's fine for testing, not good for production, and likely the reason your compiled jar can't find it. Furthermore, by setting this variable, you are overwriting any previous (default) location for it. If you want to go this route, you should copy the saved location and then append your own additional path to it.
However, for code you'll distribute to users, you don't want to have to rely on an absolute file path. It's far better to put the library in a standard relative path location: a resources path (src/main/resources if using Maven) that will be available on your (or any user's) classpath when executing. This seems to align with the commented-out Windows branch of your code, which will look in the win32-x86 subdirectory of your resources folder.
You may have told your IDE to add something to the classpath (so it works there) but if it's not in a standard location, it may fail in a jar.
I'm not sure why the macOS branch of your code does not put the resources in the darwin subdirectory but it probably should.
I'm trying to code an application in Java that can be executed in a Windows CE operating system.
For this, I use Eclipse on my Windows PC and then transfer the .jar file into my "smaller" system that operates with Windows CE. The .jar file is then executed with the Mysaifu JVM (because we need a JVM to execute a Java program in Windows CE).
So I started with a simple application that will launch a window (with JFrame) and when I tried to execute it, I got an error message :
java.lang.UnsatisfiedLinkError: Native library 'wcepeer' not found (as
file 'wcepeer') in gnu.classpath.boot.library.path and
java.library.path
I've tried to verify if the file representing the native library (wcepeer.dll) is in the correct folder, and I could see that the file is there with another library files, for example wcesound.dll, wcesecurity.dll, etc. Normally these files are provided in Program Files/Mysaifu JVM/jre/bin when I installed the JVM on my Windows CE system.
I've also tried to verify the presence of the wcepeer library with System.loadLibrary() :
try {
System.loadLibrary("wcepeer"); } catch(UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e); }
The result was :
Native code library failed to load. java.lang.UnsatisfiedLinkError: Native library 'wcepeer' not found (as
file 'wcepeer') in gnu.classpath.boot.library.path and
java.library.path
However when I replaced "wcepeer" with "wcesound" for example, there was no error. So I suppose that there's a problem with the wcepeer.dll file, but I've no idea how to solve it. I searched everywhere on the net, there's only a forum about this but it doesn't help too much.
Thanks in advance for helping.
Kindly regards,
You can use dependency walker (http://www.dependencywalker.com/) to open your DLL (it works also on CE dlls, since they use the same format as Windows ones) and see what dependencies this DLL has.
It may be that other DLLs are required (if they are statically linked via export lib your DLL will fail to load anyway) or that the DLL requires some system DLLs or APIs that are not supported on your device.
Windows CE is a componentized OS so you may have a different set of APIs, depending on the components you included in the OS image.
I'm using JNI as mean to connect my java code and C code.
The code compiles fine and the screen GUI application opens and then closes which means that there is nothing wrong with that part of the code which is pure C.
However when I run the program the output console immediately tells me:
Error occurred during initialization of VM
Unable to load native library: Can't find dependent libraries
and returns 1 as error code. I got the jvm.dll in the same folder of the exe and I think JDK PATH is correctly set up. I have no clue for what the problem may be.
I searched for the error but couldn't fix it.
That error means that the Java VM is finding and attempting to load your .dll, but additional .dlls that your .dll depends on cannot be found. One option is to make sure that those extra dependencies are in the PATH, but that can be tricky because it depends on setting up environment variables during installation, setting them at runtime, or placing additional .dlls into the same folder.
Another way to fix it is to use the -static linker flag when linking your .dll (note that this is not mutually exclusive with the -shared option, which tells the linker to package your code into a .dll). This means that the additional dependencies will be statically linked into your .dll, instead of needing to be located at runtime.
I currently wrote a simple GUI in Eclipse which runs as intended. I was hoping to export it so I can share it with my friend (who doesn't need to install eclipse and the java libraries). I tried all 3 library handling method Eclipse provides and none of them works. I read a little online and saw something about a manifest file, but wasn't quite sure what to do with it. Is it going to help?
This is where I placed the folder that comes with the .dll file.
This is the result. Am I doing something wrong?
As indicated by the error messages in the first screenshot, what you are missing here is the native library - the software library written and compiled to native code specific to the operating system. What you will need to do is provide the libraries specific to the operating system on which your software will run, eg. dlls for 32 or 64 bit Windows. The manifest does not provide the capability to include those libraries.
When the program is run on Windows, Java will look for native libraries in the following locations:
The current directory
The directories in the PATH environment variable
The directories in java.library.path (if it's specified)
It may be easiest to simply put all files in the one directory. If you do this, you should be able to run the program in the same way as you do now.
The java.library.path option is only needed if you want to put your native library files in a directory separate to the one in which you run your program and not on your PATH. It is only in this case that you will need to add java.library.path, eg. by adding -Djava.library.path=c:\path\to\your\lib after java. Also note that you may use a relative path, ie. a path that is relative to the directory you are in when you execute the command.
I also see from your later error messages that you have another dependency, but on a java library LeapJava.jar. As running a jar with -jar will only work if you have a single jar, but because you have more than one (your own program plus the dependency), you'll instead need to use the -classpath (or -cp for short) argument and add your main class. The classpath argument is a semicolon-separated list of classpath locations, while the main class is the one containing your public static void main method, eg. your.package.name.YourMainClass. So assuming your UI.jar is still in C:\Users\Ian\Desktop\Leap Data UI, you should be able to navigate to that directory and execute with:
java -cp UI.jar;UI_lib\LeapJava.jar -Djava.library.path="UI_lib\x64" your.package.name.YourMainClass
I am using Jacob jar file in my java application.
This Jacob jar file comes with a .dll file. I have added Jacob jar file to my classpath. But when I execute my application a runtime error occurs as
"couldn't load jacob-1.15-M3-x86.dll file"
How can I load this .dll file?
Edited:=================================================================================
I had set the "path" environment varaible to the dir that contains my .dll file and loading that .dll file as follows
static {
System.loadLibrary("jacob-1.15-M3-x86.dll");
}
but the following error occured
java.lang.UnsatisfiedLinkError: no jacob-1.15-M3-x86.dll in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1734)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at TemplateClass.TemplateClass.<clinit>(TemplateClass.java:14)
The 'jacob-1.15-M3-x86.dll' needs to be in a place where your the operating system can find it. You have a few options here:
You can place the .dll file in the directory you started your application from. If you have a batch script to start your application, it would be that directory. If you are starting in some sort of application server, it would typically be the 'bin' directory.
You can place the .dll file somewhere in the %PATH% environment variable. I may be easier to just update your PATH environment variable to include the directory that contains your .dll file.
Another option is to place your .dll into the %SystemRoot%\system32 directory. Usually this is 'C:\Windows\system32'. This option is not usually recommended unless it is a shared library like the MSCVRT runtime.
One other possible issue you might have. If the .dll is compiled as 32-bit, then you must be running in the 32-bit Java runtime. Likewise, if it is a 64-bit .dll it needs to be run in a 64-bit JRE.
Ah, that's not a compilation error but a runtime error.
My guess would be that your DLL needs to be on the PATH. Not CLASSPATH, but PATH, because that's where Windows looks for DLLs. Try either extending your PATH to include the location of your DLL, or do what many other people do: Dump the DLL into \Winnt\System\System32 or whatever the system directory is called on your box. Wherever all the other DLLs are, in other words.
Update
The error message you post, thankfully, is pointing out the exact problem. You can solve it by putting the directory containing your DLL into java.library.path This Sun forum thread shows a nice example: http://forums.sun.com/thread.jspa?threadID=627890
Actually, that's a lot less clean than it should be; this seems to be one of the "shadier" areas in Java. The thread wanders around a lot, I do advise you to read all the way through to see some problems and solutions. I think you'll be able to succeed with a little trial and error.
Other options :
set the property java.library.path to the directory containing the dll. Example :
java -Djava.library.path="path/to/directory/containing/the/dll" -jar appli.jar
in the code, load the dll explicitly, with System.load.
You need to set LD_LIBRARY_PATH. This will give you all the right steps to follow.
When you use System.loadLibrary() don't include the .dll at the end.
Also, if you are not setting java.library.path to point to the folder containing the DLL then the DLL should be in the directory where you launch your Java application from.
I had the same problem.
I see that the question is not "answered", so maybe none of the options above worked.
One of my last hypothesis was that the Jacob.dll is missing its dependency.
What I did was to get depend and check if all the dependence, used by Jacob are loaded.
Of course this works for Windows.
Cheers!