Unable to load library (libFile.so) on jboss server on redhat linux - java

I am getting the unsatisfied link error when I try to run the web-app.
Suppressed: java.lang.UnsatisfiedLinkError: libXXXX.so: cannot open shared object file: No such file or directory
at deployment.ttt.war//com.sun.jna.Native.open(Native Method)
at deployment.ttt.war//com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:191)
... 74 more
Suppressed: java.lang.UnsatisfiedLinkError: libXXXX.so: cannot open shared object file: No such file or directory
at deployment.ttt.war//com.sun.jna.Native.open(Native Method)
at deployment.ttt.war//com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:204)
... 74 more
Suppressed: java.io.IOException: Native library (linux-x86-64/libXXXX.so) not found in resource path (/opt/jboss-eap-7.3/jboss-modules.jar)
at deployment.ttt.war//com.sun.jna.Native.extractFromResourcePath(Native.java:1095)
at deployment.ttt.war//com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:275)
... 74 more
I have created the function which loads the native library stored at "/home/libraryFiles", using JNA.
I have stored all of my libXXXX.so files at "/home/libraryFiles".
I have exporting my war file from eclipse in windows and deploying it on the jboss server on redhat linux.
This is my function :
public class function1(){
public interface CLibrary extends Library {
public int method1(String message);
}
public int execute (String param) throws Exception{
NativeLibrary.addSearchPath("libXXXX", "home/libraryFiles");
CLibrary pLib =(CLibrary)Native.loadLibrary("XXXX",CLibrary.class);
return pLib.method1(param);
}
}
I am mapping url through rest controller to execute
new function1().execute("aaaaaaa");
I have also tried setting jna.library.path & java.library.path to "home/libraryFiles", but of no use. (using system.setProperty())
I also tried set $LD_LIBRARY_PATH=home/libraryFiles but still no good.
Seems like my web-app is not able to point out of the default resource path "/opt/jboss-eap-7.3/jboss-modules.jar"
Any help is welcoming.
PS :
I tried the same function/code on my windows PC, its working fine. I don't know why its not working on redhat linux.
Thanks in Advance.

The addSearchPath() method is specific to a library, and the additional path(s) are stored in a map with the library name as the key.
The loadLibrary() method checks that map using the library name.
You have used differing strings as the key to store the path and retrieve it:
NativeLibrary.addSearchPath("libXXXX", "home/libraryFiles");
CLibrary pLib =(CLibrary)Native.loadLibrary("XXXX",CLibrary.class);
You should either change "libXXXX" to "XXXX" in the first line (probably the preferred style) or do the reverse in the second line to match.
As noted in the comments, you also must be careful with relative vs. absolute file paths and directory permissions.

Related

What's the reason behind inconsistent 'UnsatisfiedLinkError' while trying to load a .so file through JNA?

I'm trying to load a .so file giving it's absolute path to Native.loadLibrary API. It works but I'm getting UnsatisfiedLinkError at times for which I couldn't find the reason. Can someone help me with this ?
Environment : CentOS 7.4
ImageMagick-7.0.1-2
OpenJDK : 1.8.0_162
I've set the directory path of the sharedobject file in
-Djna.library.path , -Djava.library.path and LD_LIBRARY_PATH .
I have an action class which invokes this method from the .so file through the java interface.
Code in action class :
synchronized (InterfaceforSO .class) {
InterfaceforSO.compressImage(oldPath,newPath);
}
Code in Interface class to load library :
public interface InterfaceforSO extends Library {
InterfaceforSO INSTANCE = (InterfaceforSO)Native.loadLibrary(<absolute_path_of_.so_file>,InterfaceforSO.class);
void compressImage(String path, String newPath);
}
Native.loadLibrary throws exception at times. Failure rate is like 3/5.
The exception is :
java.lang.UnsatisfiedLinkError: Unable to load library '<absolute_path_of_.so_file>': Native library (<absolute_path_of_.so_file>) not found in resource path ([file:/transltr/imgmagic/WEB-INF/classes/, file: <...... jars present in the WEB-INF/lib directory>.
P.S : I've placed the .so file in /transltr/imgmagic/WEB-INF/classes/ directory.
Could someone help me with this ?

Java Attach API: UnsatisfiedLinkError

When using the Java Attach API, I'm getting the following link error on Linux (tried it on different machines) only:
Exception in thread "main" java.lang.UnsatisfiedLinkError: sun.tools.attach.WindowsAttachProvider.tempPath()Ljava/lang/String;
at sun.tools.attach.WindowsAttachProvider.tempPath(Native Method)
at sun.tools.attach.WindowsAttachProvider.isTempPathSecure(WindowsAttachProvider.java:74)
at sun.tools.attach.WindowsAttachProvider.listVirtualMachines(WindowsAttachProvider.java:58)
at com.sun.tools.attach.VirtualMachine.list(VirtualMachine.java:134)
at sun.tools.jconsole.LocalVirtualMachine.getAttachableVMs(LocalVirtualMachine.java:151)
at sun.tools.jconsole.LocalVirtualMachine.getAllVirtualMachines(LocalVirtualMachine.java:110)
...
Interestingly, on Solaris and Windows it's working out of the box.
I tried out several combinations of specifying java.library.path to point to the directory which contains the libattach.so but with no luck.
What's wrong here?
And as a bonus question: Is there a way to see which native library is actually bound to a java class?
Different AttachProvider are used on different platforms. On Linux, it shouldn't use sun.tools.attach.WindowsAttachProvider. It is for Windows.
[solaris] sun.tools.attach.SolarisAttachProvider
[windows] sun.tools.attach.WindowsAttachProvider
[linux] sun.tools.attach.LinuxAttachProvider
This is configured in a resource file META-INF\services\com.sun.tools.attach.spi.AttachProvider (typically this file exists in tools.jar). It will search CLASSPATH to get first occurrence of this resource file and read the AttachProvider implementation class from it.
So you can probably resolve this problem by search sun.tools.attach.WindowsAttachProvider in your CLASSPATH. Possibly you have included a tools.jar from Windows.

Loading external dll with bridj is not possible due to hebrew username

I tried to load native library (lib.dll) to Java application via BridJ on Windows 7, where username is written in Hebrew.
What is important is that the Java application downloads lib.dll and save it properly in place:
C:\Users\דני\AppData\Local\Temp\lib.dll
I have reference to that file -> File lib, and pass lib.getCanonicalPath() to BridJ.
In the end I get the following exception:
Caused by: java.io.FileNotFoundException: Library 'LIB' was not found in path
...
...
...
(failed to load C:\Users\???\AppData\Local\Temp\lib.dll)
at org.bridj.BridJ.getNativeLibrary(BridJ.java:619)
at org.bridj.BridJ.getNativeLibrary(BridJ.java:619)
at org.bridj.BridJ.getNativeLibrary(BridJ.java:599)
at org.bridj.BridJ.getNativeLibrary(BridJ.java:315)
at org.bridj.CRuntime.getNativeLibrary(CRuntime.java:341)
at org.bridj.CRuntime.register(CRuntime.java:299)
... 21 more
So it seems that, getCanonicalPath() converts דני to.
How can I solve that ?
This bug looks similar to the following issue, which was fixed yesterday :
https://github.com/ochafik/nativelibs4java/issues/276
You might want to try again with the latest 0.7-SNAPSHOT.

Error while migrating JSP code from Windows to Linux machine

I worked on a JSP code that is runnning on a Tomcat5.5 server in windows system .
I had to copy all the JSP code to a linux system and when I did the same I got an error stating below.
javax.servlet.ServletException: c:\tmp is not a directory
Readcsv.init(Readcsv.java:36)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
java.lang.Thread.run(Thread.java:636)
I modified a java code in the windows system without that c:\tmp directory and restarted the tomcat server and the tool worked fine.
When I replaced the modified java code of windows to the linux system, I still get the same error.
Note: Am accessing the linux server from windows using the url http://192.168.0.85:8080/CNA/uploadcsv.jspwhere 85 is the system number of linux.
Is there anything like tomcat has to be restarted for the linux version too? If so how to do the same?
UPDATE
This is where I have used the c:\tmp location in my code.
public class Readcsv extends HttpServlet {
private static final String TMP_DIR_PATH = "c:\tmp";
private File tmpDir;
private static final String DESTINATION_DIR_PATH ="/files";
private File destinationDir;
public void init(ServletConfig config) throws ServletException {
super.init(config);
tmpDir = new File(TMP_DIR_PATH);
if(!tmpDir.isDirectory()) {
throw new ServletException(TMP_DIR_PATH + " is not a directory");
}
String realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH);
destinationDir = new File(realPath);
if(!destinationDir.isDirectory()) {
throw new ServletException(DESTINATION_DIR_PATH+" is not a directory");
}
}
How can I find the replacement for the temp path? The destination path works fine.
I exactly copied the code from this example
Don't hardcode disk file system paths in your code. That's only portability and maintainability trouble.
In case of temporary files, rather make use of File#createTempFile().
File tempfile = File.createTempFile("name", ".ext");
It will automatically create the temp file at the right location, regardless of the environment. You can however also obtain the tmp dir root location by System.getProperty("java.io.tmpdir");.
In case of resources which are to be read by your application, just put them in the runtime classpath or add their path to the runtime classpath. Then you can just obtain them from the classpath by getResource() and getResourceAsStream() methods on Class or ClassLoader.
InputStream input = getClass().getResourceAsStream("file.properties");
If you really need to have a fixed path outside the classpath, then rather define it in a properties file so that you at least have any control over the path from outside the application (so, without the need to change the code everytime).
String path = properties.getProperty("my.file.path");
it seems that your application try to read a csv file under "C:\tmp" which doesn't exist on your linux system.
You said you modified the code and redeployed it to Tomcat.
You probably just need to restart Tomcat to get it to pick up the new code. Until then, it will be running the old code and you will get the same error.
How you restart Tomcat depends on which Linux distribution you are running and how you installed Tomcat.

Java Application NoClassDefFoundError

Created a Java application to upload documents via CIS (Content Integration Suite) to a storage application. The app runs successfully in RAD, but as a executable jar in a unix environment, getting a NoClassDefFoundError. I can not find the class on my local machine and there are not references to the class on the internet.
The manifest contains that class path for the needed jar files and the main class.
Can anyone help?
Fri Sep 04 16:47:25 EDT 2009 : StandardBatchApplication startup() completed.
java.lang.NoClassDefFoundError: com.stellent.cis.support.spring.ResourceHelper
at com.stellent.cis.common.classloader.IsolatedJarClassLoader$TemporaryF
at com.stellent.cis.common.classloader.IsolatedJarClassLoader$TemporaryF
at com.stellent.cis.common.classloader.IsolatedJarClassLoader$TemporaryF
at com.stellent.cis.common.classloader.IsolatedJarClassLoader.<clinit>(I
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:196)
at com.stellent.cis.impl.CISApplicationFactory.getCisClassloader(CISAppl
at com.stellent.cis.impl.CISApplicationFactory.getCisApplication(CISAppl
at com.stellent.cis.impl.CISApplicationFactory.initialize(CISApplication
at com.lowes.ipt.edi.processor.CISApp.initialize(CISApp.java:48)
at com.lowes.ipt.edi.processor.EDItoEDAMUploadProcessor.main(EDItoEDAMUp
Caused by: java.lang.ClassNotFoundException: com.stellent.cis.support.spring.Res
at java.net.URLClassLoader.findClass(URLClassLoader.java:496)
at java.lang.ClassLoader.loadClass(ClassLoader.java:631)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:597)
... 11 more
Update: There is only one jar file I have that deals with CIS. I have looked in the jar and there is no class within. I am unfamiliar with any other RAD default classes that have CIS classes. This is not only happening for this class but also for a class that is contained in the webservices.jar. I can see the class and it is part of my class path because when I remove the Jar from the path, it complains about another missing class. When I place it back in my path, it gets further in the program and gives the same error.
The missing class is probably in some JAR file that is installed on your local machine and not on the remote machine. Or more likely - it is installed in the remove machine in a different location then in your local machine (which is expected if the remote machine is a Unix machine and your local is a Windows box).
The classpath set in the MANIFEST.MF file in the JAR that you build must specify the classpath for finding all related JARs on the remote machine - you have to find where that JAR is installed and then add that path to the manifest classpath. JARs in Unix machines are often installed in /usr/share/java but I can't tell you more then that because I'm not familiar with CIS and I don't know what JAR files it normally distributes.
The issue was caused by the permissions on the tmp directory in UNIX. The CIS API uses the tmp directory to create and store needed files/classes for execution. Because I was running the process under my own ID, it was unable to access the tmp files that were created by the wsadmin. To resolve the issue, the process has to be ran as wsadmin.

Categories