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

Eclipse Java Discussion :

[ eclipse ] [ plugin ] [ JNI ] Unhandled event loop error


Sujet :

Eclipse Java

  1. #1
    Membre averti Avatar de Jean-Philippe Shields
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    278
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2005
    Messages : 278
    Points : 330
    Points
    330
    Par défaut [ eclipse ] [ plugin ] [ JNI ] Unhandled event loop error
    Bonjour à tous ,

    Ceci est mon premier message sur le forum, donc si ce post n'est pas au bon endroit je m'en excuse à l'avance.

    J'ai un problème pour lequel je n'ai pas trouvé de solution dans la recherche du forum.

    Mon problème consiste à trouver pourquoi un appel à JNI dans un plugin Eclipse ne fonctionne pas, si le même code fonctionne dans une application java normale compilée avec Eclipse.

    Mon plugin est dérivé d'un exemple offert par Eclipse qui ajoute un item au menu et une action au workbench. L'appel à une fonction native à l'intérieur de la fonction public void run(IAction action) donne l'erreur suivante :

    Unhandled event loop exception
    Reason:
    embedWindow

    embedWindow est le nom de ma fonction native. Voici le code de mon plugin:
    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
     
     
    public class BindCalculator implements IWorkbenchWindowActionDelegate {
    	private IWorkbenchWindow window;
    	/**
             * The constructor.
             */
    	public BindCalculator() {
    	}
     
    	public native void embedWindow();
     
    	static
    	{ 
    		System.out.println("trying to load Lib");
    		System.load("C:/JNITest.dll");
    		System.out.println("Lib loaded!");
    	}
     
    	/**
             * The action has been activated. The argument of the
             * method represents the 'real' action sitting
             * in the workbench UI.
             * @see IWorkbenchWindowActionDelegate#run
             */
    	public void run(IAction action) {
     
    		System.out.println("Hello World");
    		/*
    		MessageDialog.openInformation(
    			window.getShell(),
    			"CalculetteView Plug-in",
    			"Hello, Eclipse world");
    		*/
    		embedWindow();
    	}
     
    	/**
             * Selection in the workbench has been changed. We 
             * can change the state of the 'real' action here
             * if we want, but this can only happen after 
             * the delegate has been created.
             * @see IWorkbenchWindowActionDelegate#selectionChanged
             */
    	public void selectionChanged(IAction action, ISelection selection) {
    	}
     
    	/**
             * We can use this method to dispose of any system
             * resources we previously allocated.
             * @see IWorkbenchWindowActionDelegate#dispose
             */
    	public void dispose() {
    	}
     
    	/**
             * We will cache window object in order to
             * be able to provide parent shell for the message dialog.
             * @see IWorkbenchWindowActionDelegate#init
             */
    	public void init(IWorkbenchWindow window) {
    		this.window = window;
    	}
    }
    ma classe implémente IWorkbenchWindowActionDelegate.
    La dll est effectivement bien loadée car les commentaires s'affichent sur la console de sortie. Le même code venant d'une application java fonctionne parfaitement. J'aimerais savoir si quelqu'un détient une solution à mon problème.

    Merci à l'avance.

  2. #2
    Membre habitué
    Inscrit en
    Avril 2003
    Messages
    159
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 159
    Points : 139
    Points
    139
    Par défaut
    Et ton System.out.println() juste avant ton appel à embedWindow() n'est fait qu'une fois ?
    Sinon quel est le but de ta méthode native ?

  3. #3
    Membre averti Avatar de Jean-Philippe Shields
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    278
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2005
    Messages : 278
    Points : 330
    Points
    330
    Par défaut
    Oui, les System.out.println() ne sont que des points de repères pour m'assurer que

    1) la dll est effectivement bien chargée (j'ai l'impression que le problème se situe effectivement là).

    2) l'exécution se rend bien jusqu'à la fonction native embedWindow() (après l'appel rien ne s'affiche plus si je met d'autres System.out.println() ).

    Oui effectivement le "Hello World" n'est affiché qu'une fois. La fonction native embedWindow() sert à prend une fenêtre d'un logiciel en particulier (comme calc.exe) et de la faire devenir enfant de celle de Eclipse. Ce code est implémenté en C++ à l'aide de fonction du os de windows.

  4. #4
    Membre averti Avatar de Jean-Philippe Shields
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    278
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2005
    Messages : 278
    Points : 330
    Points
    330
    Par défaut
    Après avoir fait d'autres tests voici quelques détails supplémentaires.

    l'utilisation d'un try and catch autour de la fonction native me permet de déterminer avec précision le type d'erreur lancée et effectivement le problème vient de la dll qui n'est probablement pas chargée correctement. Voici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    try
    {
            embedWindow();
    }
    catch (UnsatisfiedLinkError e)
    {
            System.out.println("Unable to load JNITest.dll");
    }
    La console imprime effectivement le message d'erreur, mais je ne comprends pas plus pourquoi cette erreur survient.

  5. #5
    Membre habitué
    Inscrit en
    Avril 2003
    Messages
    159
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 159
    Points : 139
    Points
    139
    Par défaut
    Juste pour faire un test, essaie de mettre tes chargements de librairies en dehors du bloc static (dans ton run par exemple) et en les entourant d'un try..catch.

  6. #6
    Membre habitué
    Inscrit en
    Avril 2003
    Messages
    159
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 159
    Points : 139
    Points
    139
    Par défaut
    Euh je viens d'y penser, mais normalement tu ne spécifie pas l'extension de te librairie. En effet pour rester portable, (sous linux c'est des .so), il ne faut pas spécifier .dll.
    Esaaie donc de charger ta lib sans le .dll dans son nom.

  7. #7
    Membre averti Avatar de Jean-Philippe Shields
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    278
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2005
    Messages : 278
    Points : 330
    Points
    330
    Par défaut
    En utilisant l'idée de bourbaki2003 j'ai mis un try catch autour du load comme suit:
    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
     
    try
    		{
    			System.load("C:/JNITest.dll");
    		}
    		catch(Exception e)
    		{
    			System.out.println("1 Unable to load JNITest.dll");
    		}
     
    		try
    		{
    			embedWindow();
    		}
    		catch (UnsatisfiedLinkError e)
    		{
    			System.out.println("2 Unable to load JNITest.dll");
    		}
    La console n'indique pas d'erreur après le load(), mais après embedWindow() oui.

    Pour ce qui est de l'extension, la fonction loadLibrary() n'utilise pas l'extension, mais on doit placer la dll dans le classpath. La fonction lload() nous permet de spécifier un chemin précis, mais il faut mettre l'extension.

    Je vais crinquer le débugger pour voir si java.exe a effectivement loadé la dll en mémoire.

  8. #8
    Membre habitué
    Inscrit en
    Avril 2003
    Messages
    159
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 159
    Points : 139
    Points
    139
    Par défaut
    Es-tu sur de ton code C++ sinon ?

  9. #9
    Membre averti Avatar de Jean-Philippe Shields
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    278
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2005
    Messages : 278
    Points : 330
    Points
    330
    Par défaut
    Malheureusement oui car il fonctionne parfaitement dans une application java normale avec un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public static main(string [])
    Je viens de débugger javaw.exe à partir de visual studio .net pour m'apercevoir que ma dll est effectivement chargée par javaw.exe lorsque je roule le plugin dans eclipse. Je ne comprends cependant pas pourquoi il ne peut pas résourdre le nom de la méthode (c'est le seul problème restant). Je vais essayer mon code avec l'appel à System.loadLibrary.

  10. #10
    Membre averti Avatar de Jean-Philippe Shields
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    278
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2005
    Messages : 278
    Points : 330
    Points
    330
    Par défaut
    Salut à tous ,

    Je suis content de vous annoncer que j'ai résolu mon problème. Les appels à JNI se faisaient incorrectement car dans un plugin Eclipse, les classes font, par défaut, partie d'un package particuler nom de classe.view dans mon cas car je créais un plugin view dans Eclipse.

    JNI était incapable de résoudre le nom de la fonction dans la dll C++ car le nom du package doit se trouver avant le nom de la classe dans l'entête de la fonction.

    Ex:

    package calculette.view;

    class Main
    {
    private native void embedWindow();
    }

    Le nom de la fonction JNI doit être

    JNIEXPORT void JNICALL Java_calculette_view_Main_embedWindow

    Le problème vient du fait que l'outil javah.exe qui génère automatiquement ces entêtes en C++ ne génère pas le nom du package. Il doit être rajouté à la main.

    Merci.

Discussions similaires

  1. Réponses: 3
    Dernier message: 12/02/2010, 18h20
  2. Réponses: 8
    Dernier message: 12/02/2010, 12h51
  3. Unhandled event loop exception Item not added
    Par *alexandre* dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 25/07/2009, 15h31
  4. [ Eclipse ] [ plugin ] [ JNI ] Utilisation de JNI?
    Par Jean-Philippe Shields dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 25/11/2005, 22h54
  5. [Debutant] Erreur "Unhandled event loop exception"
    Par pilz dans le forum Eclipse Platform
    Réponses: 14
    Dernier message: 08/12/2004, 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