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 :

Chargement dynamique de jar


Sujet :

Java

  1. #1
    Membre éprouvé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2013
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 116
    Par défaut Chargement dynamique de jar
    Bonjour,

    J’utilise le code suivant pour charger dynamiquement un Jar, dans mon cas un pilote JDBC.
    Le code marche, mais c’est en partie du copier-coller.
    Je suis un peu au-dessus de mes pompes.

    Par exemple il y a beaucoup d’exception.
    Je me demande lesquels sont vraiment à gérer, a part celles liées aux fichiers.

    En plus ça marche sauf avec Oracle.
    Dans ce cas je dois faire un Class.forname à la main.
    Il y a-t-il un moyen de savoir, si le pilote n’est pas déclaré dans le classpath.
    Et éventuellement de demander à l’utilisateur de le faire à la main.

    Cela ne lève pas d’erreur.
    Seulement quand je fait mon appel à la couche JDBC.
    Mais ça pourrait venir d’ailleurs, alors je dois détecter avant de l’utiliser.

    Je ne peux pas faire quand même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if(oracle… {
    	Class.forname(}
    Cordialement et merci pour votre aide
    Fabrice

    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
    28
    29
    	public boolean loadDriver(String pathDriver) {
    		boolean success = false;
    		File file = new File(pathDriver);
     
    		try {
    			URLClassLoader systemClassLoader = (URLClassLoader) ClassLoader
    					.getSystemClassLoader();
    			URL url = file.toURI().toURL();
    			Method addURL = URLClassLoader.class.getDeclaredMethod("addURL",
    					new Class<?>[] { URL.class });
    			addURL.setAccessible(true);
    			addURL.invoke(systemClassLoader, new Object[] { url });
     
    			success = true;
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		} catch (NoSuchMethodException e) {
    			e.printStackTrace();
    		} catch (SecurityException e) {
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			e.printStackTrace();
    		} catch (IllegalArgumentException e) {
    			e.printStackTrace();
    		} catch (InvocationTargetException e) {
    			e.printStackTrace();
    		}
    		return success;
    	}
    Consultez mes articles sur l'accessibilité numérique :

    Comment rendre son application SWING accessible aux non voyants
    Créer des applications web accessibles à tous

    YES WE CAN BLANCHE !!!

    Rappelez-vous que Google est le plus grand aveugle d'Internet...
    Plus c'est accessible pour nous, plus c'est accessible pour lui,
    et meilleur sera votre score de référencement !

  2. #2
    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
    Ce code est une tentative foireuse d'essayer d'injecter un jar supplémentaire dans le classloader systeme qui n'existe pas nécessairement (tiens donc, pas de test sur ce null?), d'appeler aveuglément une méthode addUrl qui n'existe pas nécessairement et de prier pour que ça lise le META-INF/


    Laisse tomber. C'est quoi ton but, pourquoi le driver doit être ajouté après démarrage? Qui va utiliser ce driver après?

  3. #3
    Membre éprouvé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2013
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 116
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Ce code est une tentative foireuse d'essayer d'injecter un jar supplémentaire dans le classloader systeme qui n'existe pas nécessairement (tiens donc, pas de test sur ce null?), d'appeler aveuglément une méthode addUrl qui n'existe pas
    aveuglément c'est tout moi.
    Le problème j'ai du mal à cerner les testes à faire
    Je veux juste m'assurer, que le fichier est un jar ou qu'il existe
    Qu'il a bien été chargé et ajouté au classpath

    nécessairement et de prier pour que ça lise le META-INF/

    Justement ça ne marche pas avec Oracle


    Je te trouve un peu dur
    Il y a pas beaucoup de documentation sur le sujet.

    Pourquoi je fais ça ?
    En fait j'ai du me faire mon propre client SQL, car ceux du marché ne sont pas top niveau accessibilité.

    Entre autre j'affiche mes résultats sous forme de HTML plutôt que sous forme de JTable.

    Donc je veux utiliser plusieurs base de données, et pour ça je charge le Jar en fonction de la base que je veux attaquer.
    Et en plus j'ai des ancienne versions de serveurs à utiliser, qui me sont imposées. Donc je dois bien choisir mon pilote selon le cas.
    Ca marche avec MySql, HsqlDb et PostgreSQL

    Mon plus gros problème c'est que j'ai pas l'habitude de travailler avec cette partie de Java
    Consultez mes articles sur l'accessibilité numérique :

    Comment rendre son application SWING accessible aux non voyants
    Créer des applications web accessibles à tous

    YES WE CAN BLANCHE !!!

    Rappelez-vous que Google est le plus grand aveugle d'Internet...
    Plus c'est accessible pour nous, plus c'est accessible pour lui,
    et meilleur sera votre score de référencement !

  4. #4
    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
    L'option la plus simple c'est de démarrer directement avec tous les drivers dont tu as besoin dans le classpath dès le départ.

    L'option plus compliquée, c'est de le charger via un URLClassLoader bien propre. Utiliser ServiceLoader pour charger le driver et l'enregistrer, puis lancer la connection en utilisant le classloader

    Un truc de ce genre pour enregistrer le driver

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    cl = new URLClassLoader(new URL[]{file.toURI().toURL()};
    SeviceLoader.load(Driver.class,cl);
    //tiré du code de DriverManager pour le chargement initial
    Iterator<Driver> driversIterator = loadedDrivers.iterator();
    while(driversIterator.hasNext()) {
        driversIterator.next(); //equivalent du Class.forName sur le driver
    }
    Un truc de ce genre pour l'utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Thread.currentThread().setContextClassLoader(cl); // prendre le classloader du driver.
    DriverManager.getConnection(... connection utilisant le nouveau driver...);

  5. #5
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    A noter que depuis Java6, vous n'avez plus besoin de déclarer un Class.forName à partir du moment où le jar du driver contient le système JDBC 4.0, grâce au système du ServiceProvider

    http://docs.oracle.com/javase/6/docs...erManager.html
    JDBC 4.0 Drivers must include the file META-INF/services/java.sql.Driver. This file contains the name of the JDBC drivers implementation of java.sql.Driver. For example, to load the my.sql.Driver class, the META-INF/services/java.sql.Driver file would contain the entry:

    my.sql.Driver

    Applications no longer need to explictly load JDBC drivers using Class.forName(). Existing programs which currently load JDBC drivers using Class.forName() will continue to work without modification.
    Si le driver est compatible JDBC 4.0 (s'il possède un fichier java.sql.Driver dans un sous répertoire META-INF/services), vous avez juste besoin de l'avoir dans le classpath


    Pour l'utiliser, vous pouvez avoir des jar pour n'importe quelle base de données, le système reconnaîtra celle que vous voulez attaquer grâce à l'URL de connexion dans la méthode getConnection

  6. #6
    Membre éprouvé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2013
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 116
    Par défaut
    plus besoin de déclarer un Class.forName à partir du moment où le jar du driver contient le système JDBC 4.0, grâce au système du ServiceProvider


    Justement j'ai l'impression que le pilote d'Oracle ne le déclare pas.
    De tout façon je dois revoir ma copie en profondeur.
    Je vais me servir de vos indications.
    Et je reposterai ma version.

    Merci à vous deux
    Consultez mes articles sur l'accessibilité numérique :

    Comment rendre son application SWING accessible aux non voyants
    Créer des applications web accessibles à tous

    YES WE CAN BLANCHE !!!

    Rappelez-vous que Google est le plus grand aveugle d'Internet...
    Plus c'est accessible pour nous, plus c'est accessible pour lui,
    et meilleur sera votre score de référencement !

  7. #7
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Du coup plusieurs questions :
    - Quel est le driver oracle utilisé? (nom, version)
    - Quel JDK est utilisé?
    - Est-ce que le driver est bien dans le classpath?
    - Que se passe-t-il quand tu exécutes le code suivant (en changeant l'url de connexion, le user et le mot de passe)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public static void main(String[] args) throws Exception {
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:sid", "user", "password");
        System.out.println(conn.isValid(5));
        conn.close();
    }
    - Tu utilises bien un driver de type thin?

  8. #8
    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 eulbobo Voir le message
    - Est-ce que le driver est bien dans le classpath?
    Ben c'est là tout la difficulté. Il est pas dans le classpath et il essaie de le forcer avec des bidouille, mais en forcant comme ça, le drivermanager ne le verra jamais, car il aura scanné les service avant cette injection.

  9. #9
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Ben c'est là tout la difficulté. Il est pas dans le classpath et il essaie de le forcer avec des bidouille, mais en forcant comme ça, le drivermanager ne le verra jamais, car il aura scanné les service avant cette injection.
    Oui, mais comme je disais, il n'y a aucun intérêt à ne pas le mettre dans le classpath (et à mettre tous les autres drivers dans le classpath) vu que le driver manager sait très bien se démerder pour choisir le bon driver par rapport à l'url de connexion

  10. #10
    Membre éprouvé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2013
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 116
    Par défaut
    Citation Envoyé par eulbobo Voir le message
    Du coup plusieurs questions :
    - Quel est le driver oracle utilisé? (nom, version)

    ojdbc14.jar
    C'est pas récent
    Je crois que le serveur ete une version 10g
    Le problème c'est que je n'utilise pas Oracle directement.
    C'est une erreur qu'on m'a remonté.
    Je devrais peut être demander les traces, ou créer un fichier de log, que l'utilisateur devrait me renvoyer

    - Quel JDK est utilisé?

    Normalement une 8.
    Mais l'application est écrite en Java7 et déclare utilisé Java 7

    - Est-ce que le driver est bien dans le classpath?

    Je le charge dynamiquement, donc je ne suis pas sûr.
    Pour que ça marche je dois faire Class.forname("...

    - Que se passe-t-il quand tu exécutes le code suivant (en changeant l'url de connexion, le user et le mot de passe)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public static void main(String[] args) throws Exception {
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:sid", "user", "password");
        System.out.println(conn.isValid(5));
        conn.close();
    }

    Ca devrait marcher, mais je veux un code dynamique

    - Tu utilises bien un driver de type thin?
    Je ne sais pas. Voire plus haut
    En fait moi je tourne sur MySql, hsqlDb, et PostGreSQL
    je n'ai pas de problème sauf avec PostGreSQL, qui me retourne n'importe quoi avec les métadatas, quand je fais mon explorateur de base de données.
    Et je pense essayer d'autre bases.

    Mais on m'a fait remarqué que ça ne marchait pas avec Oracle.
    J'ai avait éssayé sans succès avec une 9g et une 10g
    Consultez mes articles sur l'accessibilité numérique :

    Comment rendre son application SWING accessible aux non voyants
    Créer des applications web accessibles à tous

    YES WE CAN BLANCHE !!!

    Rappelez-vous que Google est le plus grand aveugle d'Internet...
    Plus c'est accessible pour nous, plus c'est accessible pour lui,
    et meilleur sera votre score de référencement !

  11. #11
    Membre éprouvé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2013
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 116
    Par défaut
    Citation Envoyé par eulbobo Voir le message
    Oui, mais comme je disais, il n'y a aucun intérêt à ne pas le mettre dans le classpath (et à mettre tous les autres drivers dans le classpath) vu que le driver manager sait très bien se démerder pour choisir le bon driver par rapport à l'url de connexion
    Je ne suis pas sûr, que se soit sans conséquence, de tous les charger.
    J'ai un dossier lib pour les pilotes jdbc, j'en propose plusieurs, les plus courant et en différente versions.
    Par exemple personnellement je dois travailler avec Postgres 8 et 9
    J'ai peur que ça pose problème

    Et en plus on a définit qu'ils peuvent choisir leur pilotes.
    Consultez mes articles sur l'accessibilité numérique :

    Comment rendre son application SWING accessible aux non voyants
    Créer des applications web accessibles à tous

    YES WE CAN BLANCHE !!!

    Rappelez-vous que Google est le plus grand aveugle d'Internet...
    Plus c'est accessible pour nous, plus c'est accessible pour lui,
    et meilleur sera votre score de référencement !

  12. #12
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Pour le côté dynamique, ça sera lié aux chaînes de connexion (jdbc:oracle ou jdbc:mysql ou jdbc:postgres...), l'idée est de savoir si ça marche ou pas. Et si ça ne marche pas quelle est l'erreur retournée.

    Oracle 9 ou 10, une application Java7 qui tourne sur une JRE8 et un driver ojdbc14.jar? Si je peux me permettre : vous cherchez la merde :p
    Le driver ojdbc14 est fait pour fonctionner avec un JDK 1.4 ou 1.5... Pas sûr qu'il fonctionne correctement en JDK8. Et il est fait pour se connecter avec des bases Oracle 10
    Oracle 9 fonctionne avec des drivers qui sont fait pour tourner en JDK 1.2 ou 1.3 (c'est 9i, pas 9g d'ailleurs)
    Une application compilée en java7, autant la faire tourner dans une jre 7 (même si ça marche avec une JRE8)

    Il FAUT que tu saches les versions des bases auxquelles tu accèdes pour avoir le bon driver de connexion !

    Le problème c'est que je n'utilise pas Oracle directement.
    C'est une erreur qu'on m'a remonté.
    Je devrais peut être demander les traces, ou créer un fichier de log, que l'utilisateur devrait me renvoyer
    Ca serait bien d'avoir des logs ou quelque chose oui. D'où l'intérêt que tu exécutes le code que je t'ai donné plus haut : vérifier si la connexion fonctionne correctement ou si ton problème vient d'ailleurs !



    Je ne suis pas sûr, que se soit sans conséquence, de tous les charger.
    J'ai un dossier lib pour les pilotes jdbc, j'en propose plusieurs, les plus courant et en différente versions.
    Par exemple personnellement je dois travailler avec Postgres 8 et 9
    J'ai peur que ça pose problème

    Et en plus on a définit qu'ils peuvent choisir leur pilotes.

    Comment ça 'ils peuvent choisir leur pilote' ?
    C'est quoi l'architecture de l'application pour que l'utilisateur puisse choisir son pilote?
    C'est sûr que si tu as plusieurs versions d'un même driver, il vaut mieux ne pas le charger automatiquement... Mais dès que tu en auras chargé un, tu ne pourras plus en charger un autre dans la même JVM de toute façon.

    Je pense que ton problème de driver multiple selon le "client" peut se résoudre de manière organisationnelle... Avec un système de packaging spécifique par exemple qui te permet de ne pas avoir à gérer ça vu que ce n'est que le choix d'une implémentation qui est spécifique à chaque conteneur

  13. #13
    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 eulbobo Voir le message
    Mais dès que tu en auras chargé un, tu ne pourras plus en charger un autre dans la même JVM de toute façon.
    Pour être compatible avec le jee qui autorise un driver différent par webapp, le driver manager compare le classloader du driver au contextclassloader. Il est donc tout à fait possible de charger plusieurs drivers pour le même prefixe. Juste un seul par classloader.

  14. #14
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Pour être compatible avec le jee qui autorise un driver différent par webapp, le driver manager compare le classloader du driver au contextclassloader. Il est donc tout à fait possible de charger plusieurs drivers pour le même prefixe. Juste un seul par classloader.
    Pardon, j'ai pas été assez précis

    A partir du moment où tu auras chargé une VERSION d'un driver donné, tu ne pourras plus charger une autre version du même driver !

  15. #15
    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 eulbobo Voir le message
    A partir du moment où tu auras chargé une VERSION d'un driver donné, tu ne pourras plus charger une autre version du même driver !
    Ben si, il y a pas de raison, il y a isolation entre classloaders.

    Edit: et pour convaincre que c'est possible:
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    package sanboxsimple;
     
    import java.io.File;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLClassLoader;
    import java.sql.Driver;
    import java.sql.SQLException;
    import java.util.Iterator;
    import java.util.ServiceLoader;
     
    public class MainDriver {
      public static interface DriverLoader {
        public Driver getDriver(String url) throws SQLException;
      }
     
      public static void main(String[] args) throws MalformedURLException, SQLException {
        String driver1Location = "/tmp/mysql-connector-java-5.0.8-bin.jar";
        String driver2Location = "/tmp/mysql-connector-java-5.1.37-bin.jar";
        String driver3Location = "/tmp/mysql-connector-java-3.1.14-bin.jar";
        // Pour des raisons obscures et pénétrantes, le 5.0.8 n'utilise pas service
        // locator
        URLClassLoader driver1ClassLoader = loadDriver(driver1Location, "com.mysql.jdbc.Driver");
        URLClassLoader driver2ClassLoader = loadDriver(driver2Location);
        URLClassLoader driver3ClassLoader = loadDriver(driver3Location, "com.mysql.jdbc.Driver");
     
        Driver d1 = getDriver("jdbc:mysql://localhost/test", driver1ClassLoader);
        Driver d2 = getDriver("jdbc:mysql://localhost/test", driver2ClassLoader);
        Driver d3 = getDriver("jdbc:mysql://localhost/test", driver3ClassLoader);
        System.out.println("Driver 1 class: "
            + System.identityHashCode(d1.getClass()) + "Version: " + d1.getMajorVersion() + "/" + d1.getMinorVersion()
            + " Domain " + d1.getClass().getProtectionDomain().getCodeSource().getLocation());
        System.out.println("Driver 2 class: "
            + System.identityHashCode(d2.getClass()) + "Version: " + d2.getMajorVersion() + "/" + d2.getMinorVersion()
            + " Domain " + d2.getClass().getProtectionDomain().getCodeSource().getLocation());
        System.out.println("Driver 3 class: "
            + System.identityHashCode(d3.getClass()) + "Version: " + d3.getMajorVersion() + "/" + d3.getMinorVersion()
            + " Domain " + d3.getClass().getProtectionDomain().getCodeSource().getLocation());
     
      }
     
      private static Driver getDriver(String jdbcUrl, URLClassLoader driverClassLoader) throws SQLException {
        ClassLoader previousContext = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(driverClassLoader);
        try {
          return ((DriverLoader) driverClassLoader.loadClass("driver.loader.DriverLoaderImpl").newInstance()).getDriver(jdbcUrl);
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
          e.printStackTrace();
          return null;
        } finally {
          Thread.currentThread().setContextClassLoader(previousContext);
        }
      }
     
      private static URLClassLoader loadDriver(String drv1, String... driverClassName) throws MalformedURLException {
        URLClassLoader driverClassLoader = new URLClassLoader(new URL[] {
            new File(drv1).toURI().toURL(),
            new File("/home/davidd/Workspaces/copan/DriverInterfaceImpl/bin").toURI().toURL() }, MainDriver.class.getClassLoader());
        ClassLoader previousContext = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(driverClassLoader);
        try {
          ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class, driverClassLoader);
          // tiré du code de DriverManager pour le chargement initial
          Iterator<Driver> driversIterator = loadedDrivers.iterator();
          while (driversIterator.hasNext()) {
            Driver next = driversIterator.next(); // equivalent du Class.forName sur
                                                  // le driver
            System.out.println("registering driver " + "for " + drv1 + ": " + next);
          }
          for (String driverName : driverClassName) {
            try {
              System.out.println("registering driver " + "for " + drv1 + ": " + Class.forName(driverName, true, driverClassLoader));
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
          return driverClassLoader;
        } finally {
          Thread.currentThread().setContextClassLoader(previousContext);
        }
      }
     
    }
    Dans projetImpl il y a seulement ceci pour leurrer le DriverManager (il vérifie que le Driver potentiel est du même classloader que l'appel, check sécurité, donc je met l'appelement potentiel dans le URL classloader)
    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
    package driver.loader;
     
    import java.sql.Driver;
    import java.sql.DriverManager;
    import java.sql.SQLException;
     
    import sanboxsimple.MainDriver.DriverLoader;
     
    public class DriverLoaderImpl implements DriverLoader {
     
      @Override
      public Driver getDriver(String url) throws SQLException {
        return DriverManager.getDriver(url);
      }
     
    }
    Output:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    registering driver for /tmp/mysql-connector-java-5.0.8-bin.jar: class com.mysql.jdbc.Driver
    registering driver for /tmp/mysql-connector-java-5.1.37-bin.jar: com.mysql.jdbc.Driver@194fa3e
    registering driver for /tmp/mysql-connector-java-5.1.37-bin.jar: com.mysql.fabric.jdbc.FabricMySQLDriver@1193f2d
    registering driver for /tmp/mysql-connector-java-3.1.14-bin.jar: class com.mysql.jdbc.Driver
    Driver 1 class: 24071475Version: 5/0 Domain file:/tmp/mysql-connector-java-5.0.8-bin.jar
    Driver 2 class: 33317470Version: 5/1 Domain file:/tmp/mysql-connector-java-5.1.37-bin.jar
    Driver 3 class: 26852690Version: 3/1 Domain file:/tmp/mysql-connector-java-3.1.14-bin.jar

  16. #16
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Si tu utilises plusieurs ClassLoader oui... Je parlais avec un seul, je considère qu'utiliser plusieurs ClassLoader pour résoudre un problème veut dire que tu as un autre soucis ailleurs... Du genre : architecture.

    Et quand tu en es à devoir utiliser plusieurs ClassLoader différents, tu t'exposes souvent à plus de problèmes que ça ne résoudra de problèmes...

  17. #17
    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
    Pour ce que j'ai compris il réalise un client SQL genre SQLDevelopper de oracle. Dans ce cas, ça prend tout son sens de vouloir avoir plusieurs version du driver. Un pour se connecter à oracle 8, un pour se connecter à oracle 11. L'utilisateur s'attends à pouvoir tester un driver précis, voir à comparer les résultats à ceux sortis par un autre driver sur la même base.

    Maintenant, j'ai jamais dit que c'était facile, juste que le DriverManager est prévu pour gérer correctement les ClassLoader, autant en profiter.

  18. #18
    Membre éprouvé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2013
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 116
    Par défaut
    Tout d'abord, je suis désolé d'avoir planté ma propre discussion pendant plus d'une semaine.
    Surtout que vous vous êtes impliqué, et un peu chamaillés sur le sujet

    Je me suis consacré à la rédaction de mon article, sur l'accessibilité des applications Swing aux non-voyants. Car j'ai pu le boucler.
    Avec un peu de chance, il y aura "un article publié" à côté de mon pseudo

    A la base, j'ai fait un client SQL universselle pour moi.
    Car les clients du marché, ne sont pas tous accessible, et en tant que non-voyants on a des besoins spécifiques.

    Quand on arrive dans mon application, on entre :
    -la chaine JDBC (l'URL)
    - le pseudo
    - le mot de passe
    - le chemin du pilote JDBC à télécharger
    J'ai même pour les exigeants un gestionnaire de config.

    Comme je m'adresse à des développeurs ou des DBA, ça ne pose pas de problèmes de sécurités.
    Ils utiliseront le pilote, qu'ils veulent.
    Et si ils me donnent un fichier Jar bidon, c'est leur problème.
    Moi je contrôle juste que le fichier existe, et sinon je retourne l'exception. "FileNotFound".
    Je ne peux pas les empêcher de se faire mal.
    C'est leur config et leur base de données.

    Concernant Oracle, c'est à mon ancienne école, ils utilisent une 10G ou une 9G.
    Pour le pilote je peux demander s'ils peuvent utiliser un pilote de meilleur facture.
    C'est gratuit si on a la licence ?
    En tout cas c'est celui qu'ils m'ont donnée

    Je vais réécrire la fonction en me basant sur votre code et celui des discussion similaires


    Et je reposte
    Je voudrais juste pondre un truc plus propre.

    Si je comprends bien.
    Ssi le Jar est pourri j'y peu rien
    Ma fonction l'est aussi. Et je dois la corriger

    Merci pour tout
    Je veux jus
    Consultez mes articles sur l'accessibilité numérique :

    Comment rendre son application SWING accessible aux non voyants
    Créer des applications web accessibles à tous

    YES WE CAN BLANCHE !!!

    Rappelez-vous que Google est le plus grand aveugle d'Internet...
    Plus c'est accessible pour nous, plus c'est accessible pour lui,
    et meilleur sera votre score de référencement !

  19. #19
    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 CoderInTheDark Voir le message

    Concernant Oracle, c'est à mon ancienne école, ils utilisent une 10G ou une 9G.
    Pour le pilote je peux demander s'ils peuvent utiliser un pilote de meilleur facture.
    C'est gratuit si on a la licence ?
    En tout cas c'est celui qu'ils m'ont donnée
    Les driver oracle sont disponibles librement. Par contre tu n'es pas autorisé à les redistribuer avec ton application.

Discussions similaires

  1. Chargement dynamiquement Jar JDBC
    Par matla dans le forum JDBC
    Réponses: 6
    Dernier message: 14/11/2008, 14h55
  2. Chargement dynamique de Jar
    Par elskwi dans le forum Langage
    Réponses: 1
    Dernier message: 17/04/2008, 15h20
  3. chargement dynamique d'un autre jar
    Par Serik dans le forum Applets
    Réponses: 2
    Dernier message: 19/07/2007, 22h10
  4. Chargement dynamique d'une archive.jar
    Par cfrayer dans le forum Langage
    Réponses: 5
    Dernier message: 29/08/2006, 16h00
  5. [jar]chargement dynamique.
    Par Teddy-htk dans le forum API standards et tierces
    Réponses: 10
    Dernier message: 27/04/2006, 15h19

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