web-dev-qa-db-fra.com

Comment créer un fichier JAR comprenant des fichiers DLL?

J'ai acheté une bibliothèque tierce Java qui comprend un fichier JAR et deux fichiers DLL. J'ai écrit mon propre Java programme qui appelle le fichier JAR tiers. Maintenant ma question est comment puis-je empaqueter tout mon code dans un seul fichier JAR qui inclut tout mon code et le JAR et les DLL tiers?

Je sais [~ # ~] swt [~ # ~] est un tel cas. Le swt.jar inclut des fichiers dll, mais je ne sais pas comment faire ni comment le faire fonctionner correctement.

65
Just a learner

Emballez-le n'importe où dans le pot. Une chose que vous devez garder à l'esprit cependant - avant de pouvoir utiliser les DLL, vous devez réellement les extraire du JAR et les vider sur le disque dur quelque part sinon vous ne pourrez pas les charger

Donc, fondamentalement - j'ai fait un projet JNI pour le client où j'utiliserai un tel pot emballé pendant la guerre. Cependant - avant d'exécuter des méthodes natives, j'obtiendrais le DLL en tant que ressource et l'écrirais sur le disque dans le répertoire temporaire. Ensuite, j'exécuterais le code d'initialisation normal où mon DLL est réglé sur le même emplacement que je viens d'écrire DLL to

Oh, et juste au cas où: il n'y a rien de spécial à empaqueter les dll ou tout autre fichier dans le bocal. C'est comme emballer des trucs dans Zip

Voici un code que je viens de creuser

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
}
76
Bostone

Utilisez http://www.jdotsoft.com/JarClassLoader.php qui pourrait charger des DLL et des JAR à partir d'un autre JAR avec une imbrication illimitée. Par exemple, DLL pourrait être dans JAR qui est dans un autre JAR racine. Toutes les DLL et JAR sont chargées comme elles sont dans un chemin de classe ou un chemin de bibliothèque.

6
gorokhmn