Domanda

Ho acquistato una libreria Java di terze parti che include un file JAR e due file DLL. Ho scritto il mio programma Java che richiama il file JAR di terze parti. Ora la mia domanda è come posso impacchettare tutto il mio codice in un singolo file JAR che include tutto il mio codice, JAR e DLL di terze parti?

So che SWT è un caso del genere. Il swt.jar include i file dll, ma non so come farlo e come farlo funzionare correttamente.

È stato utile?

Soluzione

Basta imballarlo ovunque nel vaso. Una cosa che devi tenere a mente però - prima di poter usare le DLL devi estrarle effettivamente dal JAR e scaricarle da qualche parte sul disco rigido altrimenti non sarai in grado di caricarle

Quindi, fondamentalmente, ho fatto un progetto JNI per il cliente in cui userò un tale vaso impacchettato in guerra. Tuttavia - prima di eseguire qualsiasi metodo nativo vorrei ottenere la DLL come risorsa e scriverla sul disco nella directory temporanea. Quindi eseguivo il codice di inizializzazione regolare in cui la mia DLL è impostata nella stessa posizione in cui ho appena scritto la DLL

Oh, e per ogni evenienza: non c'è niente di speciale nel confezionare dll o qualsiasi altro file in jar. È proprio come imballare cose in zip

Ecco un po 'di codice che ho appena estratto

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
}

Altri suggerimenti

Utilizza http://www.jdotsoft.com/JarClassLoader.php che potrebbe caricare DLL e JAR di un altro JAR con annidamento illimitato. Ad esempio, DLL potrebbe trovarsi in JAR che si trova in un altro JAR root. Tutte le DLL e le JAR vengono caricate come se fossero in un percorso di classe o di libreria.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top