Java can't seem to find my native libraries - java

I am trying to run my program from my jar, called PViz.jar. The jar is sitting in a directory with all of its dependent jars and the .so files that they depend on. I am using Mac OS X. When I run this:
java -cp PViz.jar pviz.PVizStart
Then I get an UnsatisfiedLinkError saying "no jogl in java.library.path". This is reasonable, i'm using jogl.jar which makes use of the native library libjogl.so.
So I run this:
java -Djava.library.path=. -cp PViz.jar pviz.PVizStart
and I get the same error. But libjogl.so is in the current directory! I figured maybe I needed to give the whole path, so I tried this:
java -Djava.library.path=/bla/bla/bla/libjogl.so -cp PViz.jar pviz.PVizStart
and it still gives me the same UnsatisifedLinkError. Argh!

Here is a step by step explanation on how to setup jogl on different operating systems, OS X included.

Try loading the lib in a static initializer in one of the main classes of your app.
Example (Copied + renamed from one of my projects):
public class MainClass {
static {
System.loadLibrary( "Your_native_lib_file_name" ); // Note: do not include the file extension!
}
}
The native lib should be in the same directory as your jar.

Related

Error: Could not find or load main class fileReader.Main Caused by: java.lang.ClassNotFoundException: fileReader.Main (individual case) [duplicate]

I am trying to run a Java application, but getting this error:
java.lang.ClassNotFoundException:
After the colon comes the location of the class that is missing. However, I know that that location does not exist since the class is located elsewhere. How can I update the path of that class? Does it have something to do with the class path?
A classpath is a list of locations to load classes from.
These 'locations' can either be directories, or jar files.
For directories, the JVM will follow an expected pattern for loading a class. If I have the directory C:/myproject/classes in my classpath, and I attempt to load a class com.mycompany.Foo, it will look under the classes directory for a directory called com, then under that a directory called mycompany, and finally it will look for a file called Foo.class in that directory.
In the second instance, for jar files, it will search the jar file for that class. A jar file is in reality just a zipped collection of directories like the above. If you unzip a jar file, you'll get a bunch of directories and class files following the pattern above.
So the JVM traverses a classpath from start to finish looking for the definition of the class when it attempts to load the class definition. For example, in the classpath :
C:/myproject/classes;C:/myproject/lib/stuff.jar;C:/myproject/lib/otherstuff.jar
The JVM will attempt to look in the directory classes first, then in stuff.jar and finally in otherstuff.jar.
When you get a ClassNotFoundException, it means the JVM has traversed the entire classpath and not found the class you've attempted to reference. The solution, as so often in the Java world, is to check your classpath.
You define a classpath on the command line by saying java -cp and then your classpath. In an IDE such as Eclipse, you'll have a menu option to specify your classpath.
Your classpath is broken (which is a very common problem in the Java world).
Depending on how you start your application, you need to revise the argument to -cp, your Class-Path entry in MANIFEST.MF or your disk layout.
This is the best solution I found so far.
Suppose we have a package called org.mypackage containing the classes:
HelloWorld (main class)
SupportClass
UtilClass
and the files defining this package are stored physically under the directory D:\myprogram (on Windows) or /home/user/myprogram (on Linux).
The file structure will look like this:
When we invoke Java, we specify the name of the application to run: org.mypackage.HelloWorld. However we must also tell Java where to look for the files and directories defining our package. So to launch the program, we have to use the following command:
NOTE: You have to execute the above java command no matter what your current location is. But this is not the case for javac. For
compiling you can even directly go into the directory where you have
your .java files and directly execute javac ClassName.java.
If you know the path of the class or the jar containing the class then add it to your classpath while running it. You can use the classpath as mentioned here:
on Windows
java -classpath .;yourjar.jar YourMainClass
on UNIX/Linux
java -classpath .:yourjar.jar YourMainClass
I had the same error and it took me a whole day to realize it's a dependency conflict issue:
I imported two libraries, A and B;
Both A and B depends on another library C, but different versions of C. Let's say A depends on C 1.0 and B depends on C 2.0;
B makes use of a class that only exists in C 2.0;
However, A is "closer" in the dependency tree, so Maven uses C 1.0 for both A and B and doesn't even warn you about this (it's quite astounding to me);
As a result, when B tries to use the class that only exists in C 2.0, a ClassNotFoundException is thrown;
Now the weird thing is: if you navigate the code of B in your IDE and try to jump to the class that only exists in C 2.0, it works correctly. C 2.0 is indeed installed and your IDE knows about it, but it's just ignored when running the application.
This really drove me mad...
I ended up having to add C 2.0 to my pom.xml so that it can be chosen over C 1.0.
Please refer to this post for how Maven chooses the closest dependency: https://stackoverflow.com/a/63815140/7438905
You can use mvn dependency:tree to visualize the dependency tree.
Try these if you use maven. I use maven for my project and when I do mvn clean install and try to run a program it throws the exception. So, I clean the project and run it again and it works for me.
I use eclipse IDE.
For Class Not Found Exception when running Junit test, try running mvn clean test once. It will compile all the test classes.
Basic Generic Question - Simplest Generic Answer ;)
Given the information I will make the assumption that you might be trying a basic approach to coding, building/compiling and running a simple console app like "Hello World", using some simple text editor and some Command Shell.
This error occurs in the fallowing scenario:
..\SomePath>javac HelloWorld.java
..\SomePath>java HelloWorld.class
In other words, use:
..\SomePath>java HelloWorld
P.S. The adding the file extension .class produces the same mistake.
Also be sure to have the Java's (JDK/JRE) bin folder in the operating system's Environment Variables's PATH.(Lookup for more details other posts on this)
P.P.S Was I correct in my assumption/s?
If you use maven, check that you have this plugin in your pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.0</version>
<executions>
<!-- Attach the shade goal into the package phase -->
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
It will put your dependency (the exception reason) to your jar.
FYI:
this will include all dependencies inflated in the final jar
To add the location of a class to your classpath via command line simply add -cp or -classpath and the location of the class while running it. I.E.
java -cp "c:/location/of/file" YourProgram
Or if you're running an IDE such as eclipse you can right click on the project -> build path -> configure build path
and add the external JAR containing your class to the build path then it should work fine.
Use ';' as the separator. If your environment variables are set correctly, you should see your settings. If your PATH and CLASSPATH is correct, windows should recognize those commands. You do NOT need to restart your computer when installing Java.
Add the full path of jar file to the CLASSPATH.
In linux use: export CLASSPATH=".:/full/path/to/file.jar:$CLASSPATH". Other way worked (without editing the CLASSPATH) was unzipping the jar in the current project folder.
Ways didn't work for me:
1) Using -cp option with full path of jar file.
2) Using -cpwith only the name of jar when located in the current folder
3) Copying the jar to the current project folder
4) Copying the jar to standard location of java jars (/usr/share/java)
This solution is reported for class com.mysql.jdbc.Driver in mysql-connector-java.5-*.jar, working on linux with OpenJDK version 1.7
This can happen on Windows after a java update where the old version of the java SDK is missing and a new one is present. I would check if your IDE is using the installed java SDK version (IntelliJ: CTRL + SHIFT + ALT + S)
Go up to the top and remove the import statement if there is one, and re import the class. But if that isn't the case do a clean then build. Are you using Netbeans or Eclipse?
I ran into this as well and tried all of the other solutions. I did not have the .class file in my HTML folder, I only had the .java file. Once I added the .class file the program worked fine.
It could happen if your classpath is not correct
Let us posit a serializable class and deserializable class under same projectname. You run the serializable class, creating a serializable object in specific folder. Now you need the desearialized data. In the meantime, if you change the name of the project it will not work. You have to run the serializable class first and then deserialize the file.
If you are using maven
try to maven update all projects and force for snapshots.
It will clean as well and rebuilt all classpath..
It solved my problem..
I just did
1.Invalidate caches and restart
2.Rebuilt my project which solved the problem
It's worth noting that sometimes Java lies about the Class that is causing the problem.
You can get this error if java tries to load class A which depends on class B and class B can't be loaded.
In some circumstances java reports that class A can't be loaded when the problem is B.
From recollection the last time this occurred was when class A includes a static field or a static initializer that loaded class B.
So after checking your class path is correct (I actually dump the full classpath on startup) I then do a binary chop on class A.
By this I mean, I remove half of the code in A.
If it still fails I remove another half and so on until the problem (hopefully goes away).
I was trying to run .jar from C# code using Process class. The java code ran successfully from eclipse but it doesn't from C# visual studio and even clicking directly on the jar file, it always stopped with ClassNotFoundException: exception. Solution for my, was export the java program as "Runnable JAR file" instead of "JAR File". Hope it can help someone.
If you have added multiple (Third-Party)**libraries and Extends **Application class
Then it might occur.
For that, you have to set multiDexEnabled true and replace your extended Application class with MultiDexApplication.
It will be solved.
In my case the class thrown as class not found exception has properties related to ssl certificates. Close the eclipse and open with as “Run as Administrator” then issue got resolved. As eclipse have issue related permission it will throw such kind of exception.
I started having this issue after upgrading the "Java Language Support" plugin from Visual Studio Code from version 0.66.0 to 0.67.0.
Downgrading back allowed me to run the same code without any issue.
If you have moved your project to new machine or importing it from git, then try this.
Right Click on class > Run as > Run Configuration
remove main class reference
Apply > Close
Now again right click on class > run as java application.
It worked for me.
I ran the Java code at the Terminal and adding Class Path was solution like this:
> java -cp <JAR file> <JAVA Class file>
for example,
c:\code\prototype-app\target\classes>java -cp ..\prototype-app-1.0-SNAPSHOT.jar com_stree.app.DetectLabels
My runtime environment:
  OS: Windows 10
  JAVA: 15.0.1
  Maven: 3.8.1
Check the .jar or .class file permissions. I had the jar on a project library with permission of -rw-r--r-- and I changed it to -rw-rw-r-- using on Linux:
chmod 664 <.jar>
One library was calling ClassLoader.loadClass which started the error when loading the class in the jar with wrong permission.
I deleted some unused imports and it fixed the problem for me. You can't not find a Class if you never look for it in the first place.
sorry i am late to the question, but i will explain it to you in the simplest layman language.
When you type 'javac <programname.java>
The compiler checks the program and finds errors, first of all make sure your program is in the same directory as you have executed in the command prompt. Then it creates a. Class file of your program. For ex. If the name of my program was Test.java then the class file created should be Test.class which will be executed in the next line.
Sometimes java takes some other name for your .class, use that name and voila you'll get the output.
Put all the code in try block then catch exception in a catch block
try
{
// code
}
catch(ClassNotFoundException e1)
{
e1.getmessage();
}

Java runs in eclipse and will compile, but wont execute on cmd, but still runs in eclipse. How can I get it to execute in cmd?

So I have a basic hello world set up in eclipse and I can compile it using cmd easily (I have set all the necessary paths), however when I then try to use the java command to execute the hello world, it always returns the same error:
Error: Could not find or load main class helloWorld
Caused by: java.lang.NoClassDefFoundError: net/codejava/helloWorld (wrong name: helloWorld)
This is the code used:
package net.codejava;
public class helloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
I am cd in the right directory (I think, I cd into the src directory and then into the package file stored in src) and am using Windows 10 with java 18.0.1 and JRE build 18.0.1+10-24
Any help would be greatly appreciated, as this is highly frustrating, when the code runs effortlessly on the eclipse console. Thanks.
Your file has a 'package' of net.codejava and a name of helloWorld, meaning, the full name of this class is net.codejava.helloWorld.
The java command, at least in the way you're using it, requires that you pass the full name, thus, you must run java net.codejava.helloWorld. Just java helloWorld simply isn't going to work.
But that's not all.
Java needs to then find the class file that contains the code for class net.codejava.helloWorld. It does this by first turning that full name into a path of sorts: net/codejava/helloWorld.class, and it will then scan each entry in the classpath for that. You can put directories and jar files on the classpath.
Thus, you have a directory on your system; let's call this directory X. X contains a directory named net, which contains a directory named codejava, which contains a file named helloWorld.class. If there is no such X (i.e. your class file is not in a dir named codejava for example), you're going to have to fix that by making these directories.
Then, X (and not the codejava dir!) needs to be on the classpath. Usually (it depends on how you configured things), 'the current dir' is by default on the classpath.
Given that your code is in, say, /home/PythonSux/workspace/learningjava/net/codejava/helloWorld.class, that means the dir that needs to be on the classpath is /home/PythonSux/workspace/learningjava. After all, if you, from there, look for net/codejava/helloWorld.class, you find the right file.
Therefore, either cd to that directory, or run java -cp /home/PythonSux/workspace/learningjava net.codejava.helloWorld
Note that this isn't usually how you actually run java apps. You either run them from your IDE, or you ask your build tool to run it, or you package your java app into a jar file and run that, etcetera.

Runnable jar works on Mac; gives main class error on Windows

I'm producing an app using Eclipse on a Mac, and am using File Export to produce a Runnable Jar. The Runnable Jar files that I produce run happily on my Mac and on another Mac. But on two different Windows machines, they don't. I've looked around for answers, and have tried the following:
1) When I double click on the jar icon nothing happens.
2) When I type
java -jar Luscinia.jar
at the Command Prompt, I get:
"Could not find or load main class lusc.net.github.Luscinia"
3) When I type
java -cp Luscinia.jar lusc.net.github.Luscinia
I get the same error message.
The JRE on one of the Windows machine (at least) is up to date
(1.8.0_40). So is the JRE on the Mac.
The file structure inside my jar does indeed have
Luscinia.class nested inside github, net and lusc directories.
The manifest contains the lines:
Class-Path: .
Main-Class: lusc.net.github.Luscinia
(& it contains two blank lines at the bottom)
Other jar's are working well on the two Windows machines.
And to emphasise again, it works perfectly well on two Mac machines.
Any ideas?
I checked whether the EOL character had an effect. Changing it to Windows \r\n didn't have any effect. (Thanks to RealSkeptic for the idea).
Are you sure your class doesn't attempt to load a Mac specific class that is not available in the windows JRE (vendor private classes ? like com.sun classes on windows) or it's not missing dependencies in the classpath necessary to the main class ?
If one of your dependant class fails to load when the main class is being class loaded (in static blocks for example), it makes it fail to load the importing class as well and you can have that problem.
In any case, having the source of the main class could help figure out the problem.
The answer provided by DarkRift was correct:
Hidden in one file was a reference to a com.apple... class that was superfluous and, critically, platform specific.
In this case, when I got the error message:
Could not find or load main class lusc.net.github.Luscinia
It meant "Could not load" rather than "Could not find". Thanks for all your suggestions.

Error; Could not find or load main class (Java using Windows CMD)

I am trying to compile and run some java files I have made in Eclipse. The full path to the .java file is C:\Users\MYNAME\Documents\Java\Introduction\src\tests\Test.java. tests is the package I created in Eclipse and src is a folder that Eclipse made under Introduction (which is the project name).
In my environment variables, I have the following relevant variable:
JAVA_HOME C:\Program Files (x86)\Java\jdk1.7.0_40\bin
Under system variables I have the following:
CLASSPATH %JAVA_HOME%
I go to my cmd and cd into the tests directory (cd C:\Users\MYNAME\Documents\Java\Introduction\src\tests). Then I compile using javac Test.java. This seems to work as I then have a Test.class file under the same directory. Now I want to run the file, I type java Test and I get the error, "could not find or load main class". I've tried a variety of things including appending .class and .java to the end but I keep getting the error. I looked at some answers and docs and I managed to get it to work if I cd into:
cd C:\Users\MYNAME\Documents\Java\Introduction\src (i.e, get out of the package)
and then run:
java -cp . tests.Test
So that seems to temporarily set the class path to the current directory, and run Test from the package tests. However, I want to simply be able to type java Test. I know it's possible as I used to be able to do it, but now for some reason I cannot (I must have changed something along the way...).
Any help is appreciated.
However, I want to simply be able to type java Test
That will only work if Test is in the default package - it's as simple as that. You need to pass the java executable the fully-qualified name of the class you want to launch. There's no way round that.
Of course, you could create your own launcher which looks in the current directory for class files, finds out the fully-qualified name of the classes within those files, and launches java providing the full name and probably specifying an appropriate classpath... but that seems like a lot of hassle compared with just including the package name in the command.
You could be making the same mistake I made. So, try the following.
Here is my code for your reference.
class A{
public static void main(String args[]) {
System.out.println("Hello world");
}
}
Once you saved this as "C:\JavaStudy\ClassA.java", try the following.
c:\JavaStudy>javac ClassA.java
c:\JavaStudy>java A.class
Error: Could not find or load main class A.class
c:\JavaStudy>java A
Hello world
c:\JavaStudy>
Note: You don't need to use " java.exe -cp . " if you have class file in the same directory from where you are executing.

java.lang.UnsatisfiedLinkError no *****.dll in java.library.path

How can I load a custom dll file in my web application? I've tried the following:
Copied all required dlls in system32 folder and tried to load one of them in Servlet constructor System.loadLibrary
Copied required dlls into tomcat_home/shared/lib and tomcat_home/common/lib
All these dlls are in WEB-INF/lib of the web-application
In order for System.loadLibrary() to work, the library (on Windows, a DLL) must be in a directory somewhere on your PATH or on a path listed in the java.library.path system property (so you can launch Java like java -Djava.library.path=/path/to/dir).
Additionally, for loadLibrary(), you specify the base name of the library, without the .dll at the end. So, for /path/to/something.dll, you would just use System.loadLibrary("something").
You also need to look at the exact UnsatisfiedLinkError that you are getting. If it says something like:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
then it can't find the foo library (foo.dll) in your PATH or java.library.path. If it says something like:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
then something is wrong with the library itself in the sense that Java is not able to map a native Java function in your application to its actual native counterpart.
To start with, I would put some logging around your System.loadLibrary() call to see if that executes properly. If it throws an exception or is not in a code path that is actually executed, then you will always get the latter type of UnsatisfiedLinkError explained above.
As a sidenote, most people put their loadLibrary() calls into a static initializer block in the class with the native methods, to ensure that it is always executed exactly once:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}
Changing 'java.library.path' variable at runtime is not enough because it is read only once by JVM. You have to reset it like:
System.setProperty("java.library.path", path);
//set sys_paths to null
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);
Please, take a loot at: Changing Java Library Path at Runtime.
The original answer by Adam Batkin will lead you to a solution, but if you redeploy your webapp (without restarting your web container), you should run into the following error:
java.lang.UnsatisfiedLinkError: Native Library "foo" already loaded in another classloader
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1715)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1646)
at java.lang.Runtime.load0(Runtime.java:787)
at java.lang.System.load(System.java:1022)
This happens because the ClassLoader that originally loaded your DLL still references this DLL. However, your webapp is now running with a new ClassLoader, and because the same JVM is running and a JVM won't allow 2 references to the same DLL, you can't reload it. Thus, your webapp can't access the existing DLL and can't load a new one. So.... you're stuck.
Tomcat's ClassLoader documentation outlines why your reloaded webapp runs in a new isolated ClassLoader and how you can work around this limitation (at a very high level).
The solution is to extend Adam Batkin's solution a little:
package awesome;
public class Foo {
static {
System.loadLibrary('foo');
}
// required to work with JDK 6 and JDK 7
public static void main(String[] args) {
}
}
Then placing a jar containing JUST this compiled class into the TOMCAT_HOME/lib folder.
Now, within your webapp, you just have to force Tomcat to reference this class, which can be done as simply as this:
Class.forName("awesome.Foo");
Now your DLL should be loaded in the common classloader, and can be referenced from your webapp even after being redeployed.
Make sense?
A working reference copy can be found on google code, static-dll-bootstrapper .
You can use System.load() to provide an absolute path which is what you want, rather than a file in the standard library folder for the respective OS.
If you want native applications that already exist, use System.loadLibrary(String filename). If you want to provide your own you're probably better with load().
You should also be able to use loadLibrary with the java.library.path set correctly. See ClassLoader.java for implementation source showing both paths being checked (OpenJDK)
In the case where the problem is that System.loadLibrary cannot find the DLL in question, one common misconception (reinforced by Java's error message) is that the system property java.library.path is the answer. If you set the system property java.library.path to the directory where your DLL is located, then System.loadLibrary will indeed find your DLL. However, if your DLL in turn depends on other DLLs, as is often the case, then java.library.path cannot help, because the loading of the dependent DLLs is managed entirely by the operating system, which knows nothing of java.library.path. Thus, it is almost always better to bypass java.library.path and simply add your DLL's directory to LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS), or Path (Windows) prior to starting the JVM.
(Note: I am using the term "DLL" in the generic sense of DLL or shared library.)
If you need to load a file that's relative to some directory where you already are (like in the current directory), here's an easy solution:
File f;
if (System.getProperty("sun.arch.data.model").equals("32")) {
// 32-bit JVM
f = new File("mylibfile32.so");
} else {
// 64-bit JVM
f = new File("mylibfile64.so");
}
System.load(f.getAbsolutePath());
For those who are looking for java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
I was facing same exception; I tried everything and important things to make it work are:
Correct version of pdf lib.jar ( In my case it was wrong version jar kept in server runtime )
Make a folder and keep the pdflib jar in it and add the folder in your PATH variable
It worked with tomcat 6.
If you believe that you added a path of native lib to %PATH%, try testing with:
System.out.println(System.getProperty("java.library.path"))
It should show you actually if your dll is on %PATH%
Restart the IDE Idea, which appeared to work for me after I setup the env variable by adding it to the %PATH%
The issue for me was naming:
The library name should begin with "lib..." such as libnative.dll.
So you might think you need to load "libnative": System.loadLibrary("libnative")
But you actually need to load "native": System.loadLibrary("native")
Poor me ! spent a whole day behind this.Writing it down here if any body replicates this issue.
I was trying to load as Adam suggested but then got caught with AMD64 vs IA 32 exception.If in any case after working as per Adam's(no doubt the best pick) walkthrough,try to have a 64 bit version of latest jre.Make sure your JRE AND JDK are 64 bit and you have correctly added it to your classpath.
My working example goes here:unstatisfied link error
I'm using Mac OS X Yosemite and Netbeans 8.02, I got the same error and the simple solution I have found is like above, this is useful when you need to include native library in the project. So do the next for Netbeans:
1.- Right click on the Project
2.- Properties
3.- Click on RUN
4.- VM Options: java -Djava.library.path="your_path"
5.- for example in my case: java -Djava.library.path=</Users/Lexynux/NetBeansProjects/NAO/libs>
6.- Ok
I hope it could be useful for someone.
The link where I found the solution is here:
java.library.path – What is it and how to use
It is simple just write java -XshowSettings:properties on your command line in windows and then paste all the files in the path shown by the java.library.path.
I had the same problem and the error was due to a rename of the dll.
It could happen that the library name is also written somewhere inside the dll.
When I put back its original name I was able to load using System.loadLibrary
First, you'll want to ensure the directory to your native library is on the java.library.path. See how to do that here. Then, you can call System.loadLibrary(nativeLibraryNameWithoutExtension) - making sure to not include the file extension in the name of your library.

Categories

Resources