java web 找不到java.library.path路径

bzg0382 2014-02-21 08:22:46
项目是在window下开发的,现在放到linux下部署需要加载一个.so的文件,但是调用
System.loadLibrary("xxxx");main方法可以找到,就在当前目录,但是放到web项目里就找不到这个xxx文件了,报错no xxx in java.library.path
我打印出了这个路径,放进去也找不到!
路径如下:
/usr/java/jdk1.6.0_35/jre/lib/amd64/server:/usr/java/jdk1.6.0_35/jre/lib/amd64:/usr/java/jdk1.6.0_35/jre/../lib/amd64:/usr/local/resin/libexec64:/usr/java/jdk1.6.0_35/jre/lib/amd64/server:/usr/java/jdk1.6.0_35/jre/lib/amd64:/usr/java/jdk1.6.0_35/jre/../lib/amd64:/usr/local/resin/webapps/ROOT/trialSys/trialDBInterface/WEB-INF/classes::/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
...全文
2310 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
bzg0382 2014-02-23
  • 打赏
  • 举报
回复
引用 15 楼 abc130314 的回复:
java.lang.UnsatisfiedLinkError: com.ykxx.host.web.dog.JGrandDog.RC_OpenDog(J[B[J)J 这个错误是因为你的 JGrandDog 类放错了包。这个你要看加密狗的文档。 如果没有文档,linux有个命令可以看动态库导出的函数(好像是nm)。 _Java_sun_reflect_ConstantPool_getFieldAt0@16 上面这个函数表示链接的是包 sun.reflect 的类 ConstantPool 的 getFieldAt 方法。 你把 JGrandDog 放到正确的包看看。 至于 loadLibrary 还是找不到库。 你看下 System.mapLibraryName("grandlinuxj_64") 是不是 "libgrandlinuxj_64.so" 然后根据规则反推一个正确的 libname。 如果还不行,你只能看当前的 ClassLoader.findLibrary(String libname) 的源码了。
感谢楼主,问题已经解决是包的问题!
bzg0382 2014-02-22
  • 打赏
  • 举报
回复
引用 8 楼 defonds 的回复:
路径还是不对 你去好好看看 NativeUtils 的源码,读懂了就知道该怎么做了
版主我看了你的那个源码, InputStream is = NativeUtils.class.getResourceAsStream(path);这个path是相对于tomcat目录下的的绝对路径,但是我穿入目录是/webapps/host/WEB-INF/classes/xxx.so还是不行! 还是报错
java.lang.RuntimeException: java.io.FileNotFoundException: File /webapps/host/WEB-INF/classes/com/ykxx/host/web/dog/libgrandlinuxj_64.so was not found inside JAR.
abc130314 2014-02-22
  • 打赏
  • 举报
回复
java.lang.UnsatisfiedLinkError: com.ykxx.host.web.dog.JGrandDog.RC_OpenDog(J[B[J)J 这个错误是因为你的 JGrandDog 类放错了包。这个你要看加密狗的文档。 如果没有文档,linux有个命令可以看动态库导出的函数(好像是nm)。 _Java_sun_reflect_ConstantPool_getFieldAt0@16 上面这个函数表示链接的是包 sun.reflect 的类 ConstantPool 的 getFieldAt 方法。 你把 JGrandDog 放到正确的包看看。 至于 loadLibrary 还是找不到库。 你看下 System.mapLibraryName("grandlinuxj_64") 是不是 "libgrandlinuxj_64.so" 然后根据规则反推一个正确的 libname。 如果还不行,你只能看当前的 ClassLoader.findLibrary(String libname) 的源码了。
Defonds 2014-02-22
  • 打赏
  • 举报
回复
路径还是不对 你去好好看看 NativeUtils 的源码,读懂了就知道该怎么做了
bzg0382 2014-02-22
  • 打赏
  • 举报
回复
/usr/local/dog/libgrandlinuxj_64.so 这个文件在服务器上是存在的!
bzg0382 2014-02-22
  • 打赏
  • 举报
回复
引用 5 楼 defonds 的回复:
不需要,跟你调用 jni 的类放一起即可
import java.io.IOException;


///////////////////////////////////////////////////////
//	GrandDog.java
//	
// 	Contains class GrandDog defining variables and native methods to
// 	interface with DOG device driver.
//
// Copyright (C) 2010 SafeNet China Ltd.
//
///////////////////////////////////////////////////////

public class JGrandDog {
	public native long RC_OpenDog(long lFlag, byte bszProductName[],long lDogHandle[]);

	public native long RC_CheckDog(long lDogHandle);

	public native long RC_GetDogInfo(long lDogHandle,RC_HARDWARE_INFO sHardwareInfo, long lOutLen[]);

	public native long RC_GetProductCurrentNo(long lDogHandle,long lProductCurrentNo[]);

	public native long RC_CloseDog(long lDogHandle);

	public native long RC_VerifyPassword(long lDogHandle, byte bPasswordType,byte bszPassword[], byte bDegree[]);

	public native long RC_ChangePassword(long lDogHandle, byte bPasswordType,byte bszPassword[]);

	public native long RC_GetUpgradeRequestString(long lDogHandle, byte bBuf[],long lLen[]);

	public native long RC_Upgrade(long lDogHandle, byte bUpgrade[], long lLen);

	public native long RC_GetRandom(long lDogHandle, byte bRandom[], byte bLen);

	public native long RC_EncryptData(long lDogHandle, byte bIn[], long lInLen,byte bOut[], long lOutLen[]);

	public native long RC_DecryptData(long lDogHandle, byte bIn[], long lInLen,byte bOut[], long lOutLen[]);

	public native long RC_ConvertData(long lDogHandle, byte bIn[], long lLen,long lRet[]);

	public native long RC_SetKey(long lDogHandle, byte bKeyType, byte bIn[],long lLen);

	public native long RC_SignData(long lDogHandle, byte bIn[], long lLen,byte bOut[], long lOutLen[]);

	public native long RC_ExecuteFile(long lDogHandle, short sDirID,short sFileID, byte bDataIn[], long lInLen, byte bDataOut[],long lOutLen[]);

	public native long RC_ReadFile(long lDogHandle, short sDirID,short sFileID, long lPos, long lLen, byte bBuf[]);

	public native long RC_WriteFile(long lDogHandle, short sDirID,short sFileID, long lPos, long lLen, byte bBuf[]);

	public native long RC_VisitLicenseFile(long lDogHandle, short sDirID,short sFileID, long lReserved);

	public native long RC_CreateFile(long lDogHandle, short sDirID,short sFileID, byte bFileType, long lFileLen);

	public native long RC_DeleteFile(long lDogHandle, short sDirID,short sFileID);

	public native long RC_CreateDir(long lDogHandle, short sDirID, long lSize);

	public native long RC_DeleteDir(long lDogHandle, short sDirID);

	public native long RC_DefragFileSystem(long lDogHandle, short sDirID);

	public native long RC_GetLicenseInfo(long lDogHandle, short sDirID,short sFileID, RC_LICENSE_INFO sLicInfo);

	static {
		System.out.println(1);
			System.loadLibrary("libgrandlinuxj_64");
		} catch (UnsatisfiedLinkError e) {
			System.out.println(e);
			try {
	            NativeUtils.loadLibraryFromJar("/usr/local/dog/libgrandlinuxj_64.so"); // during runtime. .DLL within .JAR
	        } catch (IOException e1) {
	            throw new RuntimeException(e1);
	        }
			System.exit(-1);
		}
	}
}

 
版主,我初始化这个类的时候报错!
java.lang.UnsatisfiedLinkError: no libgrandlinuxj_64 in java.library.path
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at ykxx.trial.service.impl.DBServiceImpl.selectMore(Unknown Source)
        at ykxx.trial.service.lllIIIllIIlIIllI.getResult(Unknown Source)
        at ykxx.trial.service.lllIIIllIIlIIllI.getResult(Unknown Source)
        at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:32)
        at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:34)
        at org.apache.thrift.server.TServlet.doPost(TServlet.java:83)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:153)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:91)
        at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:103)
        at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:187)
        at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:265)
        at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:273)
        at com.caucho.server.port.TcpConnection.run(TcpConnection.java:682)
        at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
        at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
        at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ExceptionInInitializerError
        at DT.checkFlag(DT.java:22)
        ... 20 more
Caused by: java.lang.RuntimeException: java.io.FileNotFoundException: File /usr/local/dog/libgrandlinuxj_64.so was not found inside JAR.
        at JGrandDog.<clinit>(JGrandDog.java:93)
        ... 21 more
Caused by: java.io.FileNotFoundException: File /usr/local/dog/libgrandlinuxj_64.so was not found inside JAR.
        at NativeUtils.loadLibraryFromJar(NativeUtils.java:73)
        at JGrandDog.<clinit>(JGrandDog.java:91)
        ... 21 more
bzg0382 2014-02-22
  • 打赏
  • 举报
回复
引用 8 楼 defonds 的回复:
路径还是不对 你去好好看看 NativeUtils 的源码,读懂了就知道该怎么做了
版主,我直接System.load("/usr/local/dog/libgrandlinuxj_64.so")这个so文件和你创建个临时文件 然后直接load据对路径有什么区别?
bzg0382 2014-02-22
  • 打赏
  • 举报
回复
引用 12 楼 abc130314 的回复:
随便放在一个 java.library.path 路径下应该都能找到 如果你的动态库的文件名是libgrandlinuxj_64.so,应该用loadLibrary("grandlinuxj_64") 如果还不行,你用load("这里填文件的绝对路径")
试过了,还是找不到,但是用system.load的时候就提示另一个错
java.lang.UnsatisfiedLinkError: com.ykxx.host.web.dog.JGrandDog.RC_OpenDog(J[B[J)J
	com.ykxx.host.web.dog.JGrandDog.RC_OpenDog(Native Method)
	com.ykxx.host.web.dog.J2sdkDemo.checkFlag(J2sdkDemo.java:54)
	com.ykxx.host.web.LoginAction.doAction(LoginAction.java:42)
	com.ykxx.host.web.BaseAction.handleRequest(BaseAction.java:42)
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
	org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
Defonds 2014-02-22
  • 打赏
  • 举报
回复
不需要,跟你调用 jni 的类放一起即可
abc130314 2014-02-22
  • 打赏
  • 举报
回复
随便放在一个 java.library.path 路径下应该都能找到 如果你的动态库的文件名是libgrandlinuxj_64.so,应该用loadLibrary("grandlinuxj_64") 如果还不行,你用load("这里填文件的绝对路径")
bzg0382 2014-02-22
  • 打赏
  • 举报
回复
引用 10 楼 wyx100 的回复:
加载路径不对
关键是哪里才是对的路径,就差把所有目录下都放一个so了
wyx100 2014-02-22
  • 打赏
  • 举报
回复
加载路径不对
bzg0382 2014-02-21
  • 打赏
  • 举报
回复
引用 3 楼 defonds 的回复:
加载路径不对。 你开发测试的时候是 eclipse,System.loadLibrary("xxxx") 加载,当然没问题。 但是部署以后,System.loadLibrary("xxxx") 就不行了,你需要这样:
static {
    try {
        System.loadLibrary("crypt"); // used for tests. This library in classpath only
    } catch (UnsatisfiedLinkError e) {
        try {
            NativeUtils.loadLibraryFromJar("/natives/crypt.dll"); // during runtime. .DLL within .JAR
        } catch (IOException e1) {
            throw new RuntimeException(e1);
        }
    }
}
NativeUtils 源码参考:
package cz.adamh.utils;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
/**
 * Simple library class for working with JNI (Java Native Interface)
 * 
 * @see http://frommyplayground.com/how-to-load-native-jni-library-from-jar
 *
 * @author Adam Heirnich <adam@adamh.cz>, http://www.adamh.cz
 */
public class NativeUtils {
 
    /**
     * Private constructor - this class will never be instanced
     */
    private NativeUtils() {
    }
 
    /**
     * Loads library from current JAR archive
     * 
     * The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after exiting.
     * Method uses String as filename because the pathname is "abstract", not system-dependent.
     * 
     * @param filename The filename inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext
     * @throws IOException If temporary file creation or read/write operation fails
     * @throws IllegalArgumentException If source file (param path) does not exist
     * @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters (restriction of {@see File#createTempFile(java.lang.String, java.lang.String)}).
     */
    public static void loadLibraryFromJar(String path) throws IOException {
 
        if (!path.startsWith("/")) {
            throw new IllegalArgumentException("The path to be absolute (start with '/').");
        }
 
        // Obtain filename from path
        String[] parts = path.split("/");
        String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
 
        // Split filename to prexif and suffix (extension)
        String prefix = "";
        String suffix = null;
        if (filename != null) {
            parts = filename.split("\\.", 2);
            prefix = parts[0];
            suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null; // Thanks, davs! :-)
        }
 
        // Check if the filename is okay
        if (filename == null || prefix.length() < 3) {
            throw new IllegalArgumentException("The filename has to be at least 3 characters long.");
        }
 
        // Prepare temporary file
        File temp = File.createTempFile(prefix, suffix);
        temp.deleteOnExit();
 
        if (!temp.exists()) {
            throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist.");
        }
 
        // Prepare buffer for data copying
        byte[] buffer = new byte[1024];
        int readBytes;
 
        // Open and check input stream
        InputStream is = NativeUtils.class.getResourceAsStream(path);
        if (is == null) {
            throw new FileNotFoundException("File " + path + " was not found inside JAR.");
        }
 
        // Open output stream and copy data between source file in JAR and the temporary file
        OutputStream os = new FileOutputStream(temp);
        try {
            while ((readBytes = is.read(buffer)) != -1) {
                os.write(buffer, 0, readBytes);
            }
        } finally {
            // If read/write fails, close streams safely before throwing an exception
            os.close();
            is.close();
        }
 
        // Finally, load the library
        System.load(temp.getAbsolutePath());
    }
}
版主,你这个NativeUtils 是要打成jar包吗?我直接调用报错! was not found inside JAR!
Defonds 2014-02-21
  • 打赏
  • 举报
回复
加载路径不对。 你开发测试的时候是 eclipse,System.loadLibrary("xxxx") 加载,当然没问题。 但是部署以后,System.loadLibrary("xxxx") 就不行了,你需要这样:
static {
    try {
        System.loadLibrary("crypt"); // used for tests. This library in classpath only
    } catch (UnsatisfiedLinkError e) {
        try {
            NativeUtils.loadLibraryFromJar("/natives/crypt.dll"); // during runtime. .DLL within .JAR
        } catch (IOException e1) {
            throw new RuntimeException(e1);
        }
    }
}
NativeUtils 源码参考:
package cz.adamh.utils;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
/**
 * Simple library class for working with JNI (Java Native Interface)
 * 
 * @see http://frommyplayground.com/how-to-load-native-jni-library-from-jar
 *
 * @author Adam Heirnich <adam@adamh.cz>, http://www.adamh.cz
 */
public class NativeUtils {
 
    /**
     * Private constructor - this class will never be instanced
     */
    private NativeUtils() {
    }
 
    /**
     * Loads library from current JAR archive
     * 
     * The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after exiting.
     * Method uses String as filename because the pathname is "abstract", not system-dependent.
     * 
     * @param filename The filename inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext
     * @throws IOException If temporary file creation or read/write operation fails
     * @throws IllegalArgumentException If source file (param path) does not exist
     * @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters (restriction of {@see File#createTempFile(java.lang.String, java.lang.String)}).
     */
    public static void loadLibraryFromJar(String path) throws IOException {
 
        if (!path.startsWith("/")) {
            throw new IllegalArgumentException("The path to be absolute (start with '/').");
        }
 
        // Obtain filename from path
        String[] parts = path.split("/");
        String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
 
        // Split filename to prexif and suffix (extension)
        String prefix = "";
        String suffix = null;
        if (filename != null) {
            parts = filename.split("\\.", 2);
            prefix = parts[0];
            suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null; // Thanks, davs! :-)
        }
 
        // Check if the filename is okay
        if (filename == null || prefix.length() < 3) {
            throw new IllegalArgumentException("The filename has to be at least 3 characters long.");
        }
 
        // Prepare temporary file
        File temp = File.createTempFile(prefix, suffix);
        temp.deleteOnExit();
 
        if (!temp.exists()) {
            throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist.");
        }
 
        // Prepare buffer for data copying
        byte[] buffer = new byte[1024];
        int readBytes;
 
        // Open and check input stream
        InputStream is = NativeUtils.class.getResourceAsStream(path);
        if (is == null) {
            throw new FileNotFoundException("File " + path + " was not found inside JAR.");
        }
 
        // Open output stream and copy data between source file in JAR and the temporary file
        OutputStream os = new FileOutputStream(temp);
        try {
            while ((readBytes = is.read(buffer)) != -1) {
                os.write(buffer, 0, readBytes);
            }
        } finally {
            // If read/write fails, close streams safely before throwing an exception
            os.close();
            is.close();
        }
 
        // Finally, load the library
        System.load(temp.getAbsolutePath());
    }
}
bzg0382 2014-02-21
  • 打赏
  • 举报
回复
引用 1 楼 defonds 的回复:
你这是 jni?
是的,加密狗!
Defonds 2014-02-21
  • 打赏
  • 举报
回复
你这是 jni?

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧