Pergunta

Eu comprei uma biblioteca Java de terceiros que inclui um arquivo JAR e dois arquivos DLL. Eu escrevi o meu próprio programa Java que invocar o arquivo JAR de terceiros. Agora a minha pergunta é Como posso empacotar todo o meu código em um único arquivo JAR que incluem todo o meu código eo JAR de terceiros e DLLs?

Eu sei SWT é tal um caso. O swt.jar inclui arquivos DLL, mas eu não sei como fazer isso e como fazê-lo funcionar corretamente.

Foi útil?

Solução

Apenas empacotá-lo em qualquer lugar do frasco. Uma coisa que você tem que manter em mente que - antes de você pode usar as DLLs que você precisa para realmente extrair estes a partir do JAR e despejar estes no disco rígido em algum lugar caso contrário você não será capaz de carregá-los

Então, basicamente - Eu fiz projeto JNI para o cliente onde eu vou usar tais jar empacotado dentro da guerra. No entanto - antes de executar quaisquer métodos nativos gostaria de obter a DLL como um recurso e escrevê-lo para o disco no diretório temporário. Então eu iria correr código de inicialização regular, onde minha DLL está definido para o mesmo local que acabei de escrever DLL para

Oh, e apenas no caso de: não há nada de especial sobre dll embalagem ou qualquer outro arquivo em jar. É como embalagem coisas em zip

Aqui está algum código eu cavei fora

public class Foo {
private static final String LIB_BIN = "/lib-bin/";
private final static Log logger = LogFactory.getLog(ACWrapper.class);
private final static String ACWRAPPER = "acwrapper";
private final static String AAMAPI = "aamapi51";
private final static String LIBEAU = "libeay32";

static {
    logger.info("Loading DLL");
    try {
        System.loadLibrary(ACWRAPPER);
        logger.info("DLL is loaded from memory");
    } catch (UnsatisfiedLinkError e) {
        loadFromJar();
    }
}

/**
 * When packaged into JAR extracts DLLs, places these into
 */
private static void loadFromJar() {
    // we need to put both DLLs to temp dir
    String path = "AC_" + new Date().getTime();
    loadLib(path, ACWRAPPER);
    loadLib(path, AAMAPI);
    loadLib(path, LIBEAU);
}

/**
 * Puts library to temp dir and loads to memory
 */
private static void loadLib(String path, String name) {
    name = name + ".dll";
    try {
        // have to use a stream
        InputStream in = ACWrapper.class.getResourceAsStream(LIB_BIN + name);
        // always write to different location
        File fileOut = new File(System.getProperty("java.io.tmpdir") + "/" + path + LIB_BIN + name);
        logger.info("Writing dll to: " + fileOut.getAbsolutePath());
        OutputStream out = FileUtils.openOutputStream(fileOut);
        IOUtils.copy(in, out);
        in.close();
        out.close();
        System.load(fileOut.toString());
    } catch (Exception e) {
        throw new ACCoreException("Failed to load required DLL", e);
    }
}
    // blah-blah - more stuff
}

Outras dicas

Use http://www.jdotsoft.com/JarClassLoader.php que poderia carregar DLLs e frascos de outro JAR com assentamento ilimitado. Por exemplo, poderia ser DLL no JAR que é noutro JAR raiz. Todas as DLLs e frascos são carregados como eles estão em um caminho de classe ou biblioteca caminho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top