2012-12-10 42 views
1

我有一个库用于mavenized java项目中。该库由两部分组成:一个暴露API的jar和3个dll(本地lib)。 jar中有一段加载dll的代码,因此dll所在的目录必须位于PATH环境变量中。Maven和原生库文件

将jar添加到我的项目很容易。我设置dll的方式是每个开发人员将dll下载到一个目录中,然后将path-to-dll添加到PATH环境变量中。

理想情况下,当新开发人员下载项目时,我希望尽可能少设置。有没有更好的方法来设置dll(没有从项目中单独下载它们的开销,并将目录添加到PATH中)?

+0

请参阅:http://stackoverflow.com/questions/7073039/how-to-include-native-library-on-mavens- java-library-path-variable?rq = 1 – Hossein

+0

谢谢,这解决了我的一个问题(在测试服务器上运行测试)。但是每个开发人员仍然必须将PATH指向包含dll的目录才能在本地运行代码(例如从IntelliJ IDEA开始)。有没有解决办法? –

回答

0

如果您可以更改库的加载代码:将jar包含在jar/classpath中。然后将copy这个DLL文件复制到本地文件系统中。从那里加载。以下假定库位于类路径中。

public void loadLibrary(String library) throws IOException { 
    InputStream source = getClass().getResourceAsStream(library); 
    File tempFile = File.createTempFile("javatmp", ".dll"); 
    FileOutputStream dest = new FileOutputStream(tempFile); 
    try { 
     IOUtils.copy(source, dest) 
    } 
    finally { 
     dest.close(); 
     source.close(); 
    } 
    System.load(tempFile.getAbsolutePath()); 
    tempFile.delete(); 
} 

如果你不能改变如何库加载DLL文件,那么你可以修改(使用JNA)的路径和DLL文件复制到该位置。以下假定库位于类路径的根目录下。

public void exposeLibrary(String library, File tempDir) throws IOException { 
    InputStream source = getClass().getResourceAsStream(library); 
    File tempFile = new File(tempDir, library); 
    FileOutputStream dest = new FileOutputStream(tempFile); 
    try { 
     IOUtil.copy(source, dest) 
    } 
    finally { 
     dest.close(); 
     source.close(); 
    }  
    WinLibc.INSTANCE._putenv("PATH=" + 
     System.getenv().get("PATH") + File.pathSeparator + tempDir.getAbsolutePath()); 

    // After this point System.loadLibrary(library) will load the DLL. 
} 


public interface WinLibC extends Library { 
    static WinLibC INSTANCE = Native.loadLibrary("msvcrt", WinLibC.class); 

    public int _putenv(String name); 
} 

注:我没有测试任何这个。第二个解决方案将不适用于Linux(但可以与几个changes。)