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

Entrée/Sortie Java Discussion :

[JNI] Problème d'invocation de méthode native


Sujet :

Entrée/Sortie Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Par défaut [JNI] Problème d'invocation de méthode native
    Bonjour,

    Voici la configuration actuelle de mon programme Java sous Linux :

    - Une bibliothèque écrite en C avec un .so qui se trouve dans /usr/lib,

    - Une bibliothèque JNI en C de liaison entre mon programme Java et ma bibliothèque native (le .so généré va dans ./lib/),

    - Un programme Java qui, en static, charge les deux bibliothèques (System.loadLibrary).

    Les load se passent sans lever d'exception ni d'erreur (ils sont dans un try catch). Ma variable LD_LIBRARY_PATH est bien fixé à ./lib/ et /usr/lib/. Mais à l'invocation de ma première méthode native, j'ai l'erreur suivante qui est levée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    java.lang.UnsatisfiedLinkError: ./maMethodeNative()Z
    Je ne vois pas d'où le problème pourrais venir. Si c'était dans la partie C, j'imagine que l'erreur ne serait pas forcément remontée à la couche Java.
    Toute aide serait appréciée.

  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,


    JNI n'arrive pas à lier la méthode Java avec la méthode native.
    Le problème peut avoir diverse raison.

    Il faudrait voir le stacktrace complet, ton code Java, ton code C et la manière dont tu génères/compiles tout cela...


    a++

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Par défaut
    Voici mon C :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    JNIEXPORT jboolean JNICALL Java_NomPackage_jniStart
      (JNIEnv * env, jobject obj)
    {
           // Sauvegarde de l'environnement pour les appels spontanes du C.
          env->GetJavaVM(&m_javaVM);
          // Sauvegarde de la reference sur le controleur java.
          m_java_controleur = env->NewGlobalRef(obj);
          // Appel a la lib native installee dans /usr/lib
     
          return true;
    }
    Voici mon code Java :

    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
     
    public class JNI_ControleurJNI {
        static {
            try {
                System.out.println("tentative de chargement de la lib c"); //$NON-NLS-1$
                System.loadLibrary("capi"); //$NON-NLS-1$
                System.out.println("librairie native chargee"); //$NON-NLS-1$
                System.out.println("tentative de chargement de la lib JNI"); //$NON-NLS-1$
                System.loadLibrary("monjni"); //$NON-NLS-1$
                System.out.println("librairie JNI chargee"); //$NON-NLS-1$
            } catch (final UnsatisfiedLinkError e) {
                System.out.println("Exception au chargement de la lib"); //$NON-NLS-1$
                System.out.println(e.getMessage());
                e.printStackTrace();
            } catch (final SecurityException e) {
                e.printStackTrace();
            } catch (final NullPointerException e) {
                e.printStackTrace();
            } catch (final Exception e) {
                e.printStackTrace();
            }
        }
     
        /**
         * Demarrage de la classe.
         * 
         * @return <code>true</code> si tout s'est bien passe, <code>false</code>
         *         sinon.
         */
        public boolean start() {
            return jniStart();
        }
     
        private native boolean jniStart();
    }
    Etant dans un contexte OSGi, pour compiler la partie C, j'ai une routine ant au sein de laquelle il y a la target suivante :

    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
     
    <mkdir dir="${target.dir}/main/include" />
    <javah destdir="${target.dir}/main/include" force="yes">
           <classpath>
                    <path location="${target.dir}/main/classes" />
            </classpath>
    	<class name="monPackage.JNI_ControleurJNI" />
    </javah>
     
    <mkdir dir="${basedir}/lib" />
    <exec executable="gcc" dir="${basedir}/lib">
                <arg value="-c" />
                <arg value="-lcapi" />
                <arg value="-I/usr/lib" />
                <arg value="-o"/>
                <arg value="${sources.dir}/main/C/interfaceJNI.o"/>
                <arg value="${sources.dir}/main/C/interfaceJNI.cpp"/>
    </exec> 
    <exec executable="gcc" dir="${basedir}/lib">
            <arg value="-I/usr/lib" />
            <arg value="-lcapi" />
            <arg value="-shared" />
            <arg value="-o"/>
            <arg value="libmonjni.so"/>
            <arg value="${sources.dir}/main/C/interfaceJNI.o"/>
    </exec>
    D'après l'éxécution de ant, cette partie de la routine se passe sans problème. Ma bibliothèque libmonjni.so est bien généré dans le répertoire ./lib.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Par défaut
    Une chose byzarre, c'est que le chargement se passe bien, mais que je le fasse ou pas ne change rien. J'ai essayé en chargeant les deux biliothèques, une seule, aucune : le résultat est le même.

  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
    As-tu bien généré le header C avec la commande javah ?
    Car le nom de ta méthode C ne correspond pas au nom de ta méthode Java...


    a++

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Par défaut
    Oui, le point h est bien généré avec les lignes suivantes dans mon script ant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <javah destdir="${target.dir}/main/include" force="yes">
            <classpath>
                    <path location="${target.dir}/main/classes" />
            </classpath>
            <class name="monpackage.JNI_ControleurJNI" />
    </javah>
    Et le nom de méthode me semble normal. la méthode s'appelle jniStart() dans le java et Java_monPackage_jniStart dans mon C.

  7. #7
    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 K-you Voir le message
    Et le nom de méthode me semble normal. la méthode s'appelle jniStart() dans le java et Java_monPackage_jniStart dans mon C.
    Et dans le fichier .H ?

    a++

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Par défaut
    Ah c'est peut être à ce niveau qu'il y a un problème. En réalité, mon fichier .h devrait s'appeler monPackage_JNI_ControleurJNI.h, il s'apelle monPackage_JNI_0005fControleurJNI.h. Et sinon le prototype de ce .h est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    JNIEXPORT jboolean JNICALL Java_monPackage_JNI_1ControleurJNI_jniStart
      (JNIEnv *, jobject);
    J'ai l'impression que c'est le nommage de ma classe JNIControleurJNI avec le caractère '_' qui pose problème.

    Finalement, c'est la même chose. J'ai toujours l'erreur suivante

    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
     
     
    java.lang.UnsatisfiedLinkError: monPackage.ControleurJNI.jniStart()Z
    	at monPackage.ControleurJNI.jniStart(Native Method)
    	at monPackage.ControleurJNI.start(ControleurJNI.java:112)
    	at monAutrePackage.ClasseN.activate(ClasseN.java:123)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:202)
    	at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:151)
    	at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:310)
    	at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:590)
    	at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:184)
    	at org.eclipse.equinox.internal.ds.Resolver.buildNewlySatisfied(Resolver.java:399)
    	at org.eclipse.equinox.internal.ds.Resolver.enableComponents(Resolver.java:179)
    	at org.eclipse.equinox.internal.ds.SCRManager.performWork(SCRManager.java:704)
    	at org.eclipse.equinox.internal.ds.SCRManager$QueuedJob.dispatch(SCRManager.java:671)
    	at org.eclipse.equinox.internal.ds.WorkThread.run(WorkThread.java:89)
    	at org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor.run(Executor.java:70)

Discussions similaires

  1. JNI et méthode native
    Par miaous dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 06/01/2012, 19h53
  2. [JNI] Time out sur méthode native
    Par pierre2006 dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 17/11/2006, 11h44
  3. [JNI] Java ne trouve pas mes méthodes natives
    Par carotte31 dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 14/06/2006, 21h47
  4. [TOMCAT] JSP problème d'accès aux méthodes d'une classes
    Par gunnm dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 22/05/2004, 14h02
  5. [JNI]problème option -Djava.library.path
    Par sylviiie dans le forum ANT
    Réponses: 2
    Dernier message: 18/05/2004, 08h54

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