解决方案 »

  1.   

    加载路径不对。
    你开发测试的时候是 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 <[email protected]>, 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());
        }
    }
      

  2.   

    版主,你这个NativeUtils 是要打成jar包吗?我直接调用报错! was not found inside JAR!
      

  3.   

    不需要,跟你调用 jni 的类放一起即可
      

  4.   

    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
      

  5.   

    /usr/local/dog/libgrandlinuxj_64.so 这个文件在服务器上是存在的!
      

  6.   

    路径还是不对
    你去好好看看 NativeUtils 的源码,读懂了就知道该怎么做了
      

  7.   

    版主我看了你的那个源码,     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.
      

  8.   

    随便放在一个 java.library.path 路径下应该都能找到
    如果你的动态库的文件名是libgrandlinuxj_64.so,应该用loadLibrary("grandlinuxj_64")
    如果还不行,你用load("这里填文件的绝对路径")
      

  9.   

    试过了,还是找不到,但是用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)
      

  10.   

    版主,我直接System.load("/usr/local/dog/libgrandlinuxj_64.so")这个so文件和你创建个临时文件
    然后直接load据对路径有什么区别?
      

  11.   

    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) 的源码了。