IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

DLL temporaire extrait du jar


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 149
    Par défaut DLL temporaire extrait du jar
    Bonjour!

    Je développe un programme qui utilise Sigar, j'ai donc besoin d'un dll pour la faire fonctionner. J'aimerais que ce dll soit dans le jar directement et je sais que c'est possible, mais seulement après l'avoir copié hors du jar. J'ai alors pack mon dll dans mon jar et c'est là que je bloque, je n'arrive pas à copier le contenu de mon fichier source dans le nouveau (qui se créé mais qui reste vide)... Par ailleurs je ne sais pas trop sûr de comment faire un fichier temporaire, même après avoir cherché sur le net.
    Mon dll s'appelle "sigar-amd64-winnt.dll"

    Voici mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    	//-------------------------------------------------------
    	//Loading Required Libraries
    	//-------------------------------------------------------
    	public static void loadDLL() throws IOException { 
     
            try {
     
                    InputStream in = Main.class.getResourceAsStream("sigar-amd64-winnt.dll");
     
                    File fileOut = new File("sigar-amd64-winnt.dll");
     
                    OutputStream out = FileUtils.openOutputStream(fileOut);
                    IOUtils.copy(in, out);
                    in.close();
                    out.close();
                	System.out.println("Required library successfully loaded!");
            } catch (Exception e) {
            	System.out.println("Failed to load required library...");
            }
    	//Loading Library
    		try {
    	        System.loadLibrary("sigar-amd64-winnt.dll");
    	    } catch (UnsatisfiedLinkError e) {
     
    	    }
        //-------------------------------------------------------	
    	}
    J'utilise Apache pour me faciliter la copie. (sans succès XD)

    J'espère que vous pourrez m'aider.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Je ne sais pas ce que fait ces méthodes d'Apache, mais si le fichier est vide il y a des chances que ce soit à cause d'un buffer, et qu'il faille flusher l'output pour forcer l'écriture.

    Toutefois j'aurais plusieurs remarques sur ton code :
    • La gestion des exceptions fait peur, entre les exception ignorés et celle qui se contente d'afficher un message avant de continuer le traitement...
    • Tu fermes les flux, c'est bien, mais il faudrait le faire via le try-with-ressource de Java 7, ou via des try/finally sinon.
    • Tu places le fichier dans le répertoire courant... mais ce dernier n'est pas forcément dans la liste des répertoires du library-path, donc rien ne dit que ta DLL sera bien chargé.
    • System.loadLibrary() attend un nom logique de librairie... sous windows cela correspond au nom dans le ".dll"...
      Comme tu connais le nom exact du fichier, tu devrais plutôt utiliser System.load()


    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    	private static void loadDLL() throws IOException {
    		// 1. On crée un fichier temporaire :
    		File tempFile = File.createTempFile("temp", ".dll");
    		// 2. On recopie le fichier depuis le jar vers le fichier temporaire
    		try (InputStream input = Main.class.getResourceAsStream("sigar-amd64-winnt.dll");
    			OutputStream output = new FileOutputStream(tempFile)) {
    			byte[] buf = new byte[8192];
    			int len;
    			while ( (len=input.read(buf)) > 0 ) {
    				output.write(buf, 0, len);
    			}
    			output.flush();
    		}
    		// 3. On marque le fichier afin que le JVM le supprime à la fermeture
    		tempFile.deleteOnExit();
    		// 4. On charge directement ce fichier
    		System.load(tempFile.getAbsolutePath());
    	}

    [edit] Et bien sûr il faudrait gérer un chargement de librairie différente selon le système et l'architecture...


    a++

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Si le fichier est vide, c'est probablement parce que tu gère tes exceptions n'importe comment et, du coup, tu n'a pas vu le NullPointerException lancé par IOUtils, qui est du au fait que is est null, lui même du au fait que la dll n'est pas présente à l'endroit où tu la cherche, vraisemblablement. Tu l'a bien mise à coté de ton Main.class, pas dans une autre dossier??

  4. #4
    Membre actif
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 149
    Par défaut
    Oui en effet j'ai oublié de demander le printstacktrace.
    Merci pour tes conseils adiGuba! Je m'occuperais du multi-plateforme plus tard par contre. ^^

    Pour répondre à tchize, j'avais cherché un peu sur internet et j'ai vu qu'il serait préférable de stocker ma librairie dans un dossier à part que j'ai nommé "libraries". Si j'ai bien compris il faudrait que je créé une classe vide dans ce dossier et que je remplace "Main.class..." par ma nouvelle classe. Je ne vois pas spécialement ce qu'apporte l'ajout d'un dossier supplémentaire dans un aussi petit programme mais bon, peut-être que ça a une importance...

    Par contre, avec le code de adiGuba, temp.dll ne se crée pas (du moins je ne le vois pas; j'ai tenté un export et en effet ça ne fonctionne pas)
    J'ai fait le petit remplacement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    	public static void loadDLL() throws IOException { 
    	//Creating temp file
    		File tempFile = File.createTempFile("temp", ".dll");
     
    		try (InputStream input = GetLibraries.class.getResourceAsStream("sigar-amd64-winnt.dll");
    			OutputStream output = new FileOutputStream(tempFile)) {
    			byte[] buf = new byte[8192];
    			int len;
    			while ( (len=input.read(buf)) > 0 ) {
    				output.write(buf, 0, len);
    			}
    			output.flush();
    		}
     
    		tempFile.deleteOnExit();
     
    	//Loading Library
    		System.load(tempFile.getAbsolutePath());
        //-------------------------------------------------------	
    	}
    Précision: J'ai deux packages comme je l'ai dit juste avant: celui avec mon code et celui avec mon dll, d'où le GetLibraries.class.
    Avec ça je n'ai plus la NullPointerException ( après avoir corrigé mes idioties ça marche mieux ^^)

  5. #5
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par JeremGamer Voir le message
    Par contre, avec le code de adiGuba, temp.dll ne se crée pas (du moins je ne le vois pas; j'ai tenté un export et en effet ça ne fonctionne pas)
    Tu n'auras pas de fichier "temp.dll", mais un fichier temporaire dont le nom commence par "temp" et fini par ".dll".
    La JVM mettra quelque chose au milieu afin de s'assurer de ne pas écraser un autre fichier...


    As-tu vérifié précisément à l'emplacement du fichier ? Et avant la fin du programme ?


    Et que veux-tu dire par "j'ai tenté un export et en effet ça ne fonctionne pas" ???


    a++

  6. #6
    Membre actif
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 149
    Par défaut
    Je travaille avec Eclipse et le fichier temporaire se créé donc à un emplacement que je ne connais pas! (Le programme se lance comme il faut dessus mais une fois exporté, ça ne fonctionne plus. Normal vu que Eclipse donne directement le chemin vers mon dll^^)

    Le fichier est sensé se créer dans le dossier où se trouve le jar? Si oui, il n'apparait pas.

    edit: J'ai vérifié pendant que le programme tournait avec Eclipse

  7. #7
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par JeremGamer Voir le message
    Pour répondre à tchize, j'avais cherché un peu sur internet et j'ai vu qu'il serait préférable de stocker ma librairie dans un dossier à part que j'ai nommé "libraries". Si j'ai bien compris il faudrait que je créé une classe vide dans ce dossier et que je remplace "Main.class..." par ma nouvelle classe.
    Heu non, tu n'a pas à créer une classe vide. Mais dans getResourceAsStream, il faut mettre un chemin correct:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    InputStream input = Main.class.getResourceAsStream("/librairies/sigar-amd64-winnt.dll")

  8. #8
    Membre actif
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 149
    Par défaut
    Sans en créer une, même en mettant le chemin correct j'ai une NullPointerException. Sinon je met ma librairie dans le même dossier ce sera plus simple.

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/11/2011, 18h23
  2. Intégration des dll dans un fichier JAR
    Par dot-_-net dans le forum Général Java
    Réponses: 1
    Dernier message: 02/03/2011, 04h27
  3. Réponses: 5
    Dernier message: 29/07/2009, 15h04
  4. Problème de DLL dans un fichier jar
    Par Guigui985 dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 14/10/2008, 18h15
  5. Réponses: 3
    Dernier message: 24/11/2006, 11h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo