2010-07-29 19 views
2

J'écris un plug-in (ClassRefactoringPlugin) qui examine le code source dans Eclipse 3.6.1. Le plug-in contient une classe CallData qui examine un fichier source Java et détermine quels éléments Java sont appelés à partir d'une méthode utilisant des opérations JDT. J'ai écrit un test JUnit 4 pour cette classe qui réside également dans le projet ClassRefactoringPlugin. Quand je l'ai couru comme un test de plug-in JUnit, j'ai eu:Comment JUnit trouve-t-il le plug-in eclipse testé?

Qu'est-ce que j'ai fait de mal? La configuration spécifie de se lancer avec tous les espaces de travail et les plug-ins cible activés, et ClassRefactoringPlugin est dans mon répertoire dropins. (Bien que ne devrait pas la version du projet de plug-in reconnu par l'espace de travail donné naissance?)

Voici la trace de la pile:

!MESSAGE CallData.calculateCalledMethods: Java Model Exception: Java Model Status [ClassRefactoringPlugin does not exist] 
Java Model Exception: Java Model Status [ClassRefactoringPlugin does not exist] 
     at org.eclipse.jdt.internal.core.JavaElement.newJavaModelException(JavaElement.java:502) 
     at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:246) 
     at org.eclipse.jdt.internal.core.Openable.openAncestors(Openable.java:504) 
     at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:240) 
     at org.eclipse.jdt.internal.core.Openable.openAncestors(Openable.java:504) 
     at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:240) 
     at org.eclipse.jdt.internal.core.Openable.openAncestors(Openable.java:504) 
     at org.eclipse.jdt.internal.core.CompilationUnit.openAncestors(CompilationUnit.java:1170) 
     at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:240) 
     at org.eclipse.jdt.internal.core.SourceRefElement.generateInfos(SourceRefElement.java:107) 
     at org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:515) 
     at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:252) 
     at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:238) 
     at org.eclipse.jdt.internal.core.JavaElement.getChildren(JavaElement.java:193) 
     at org.eclipse.jdt.internal.core.JavaElement.getChildrenOfType(JavaElement.java:207) 
     at org.eclipse.jdt.internal.core.SourceType.getMethods(SourceType.java:403) 
     at nz.ac.vuw.ecs.kcassell.utils.EclipseSearchUtils.addDesiredMethods(EclipseSearchUtils.java:333) 
     at nz.ac.vuw.ecs.kcassell.utils.EclipseSearchUtils.getMethods(EclipseSearchUtils.java:210) 
     at nz.ac.vuw.ecs.kcassell.callgraph.CallData.collectMethodCallData(CallData.java:203) 
     at nz.ac.vuw.ecs.kcassell.callgraph.CallData.calculateCalledMethods(CallData.java:176) 
     at nz.ac.vuw.ecs.kcassell.callgraph.CallData.collectCallData(CallData.java:151) 
     at nz.ac.vuw.ecs.kcassell.callgraph.CallDataTest.testCollectCallData(CallDataTest.java:67) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at junit.framework.TestCase.runTest(TestCase.java:168) 
     at junit.framework.TestCase.runBare(TestCase.java:134) 
     at junit.framework.TestResult$1.protect(TestResult.java:110) 
     at junit.framework.TestResult.runProtected(TestResult.java:128) 
     at junit.framework.TestResult.run(TestResult.java:113) 
     at junit.framework.TestCase.run(TestCase.java:124) 
     at junit.framework.TestSuite.runTest(TestSuite.java:232) 
     at junit.framework.TestSuite.run(TestSuite.java:227) 
     at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83) 
     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) 
     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
     at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:62) 
     at org.eclipse.pde.internal.junit.runtime.UITestApplication$1.run(UITestApplication.java:116) 
     at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) 
     at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134) 
     at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3515) 
     at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3164) 
     at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640) 
     at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604) 
     at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438) 
     at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671) 
     at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) 
     at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664) 
     at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) 
     at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115) 
     at org.eclipse.pde.internal.junit.runtime.UITestApplication.start(UITestApplication.java:47) 
     at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) 
     at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) 
     at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) 
     at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369) 
     at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619) 
     at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574) 
     at org.eclipse.equinox.launcher.Main.run(Main.java:1407) 
     at org.eclipse.equinox.launcher.Main.main(Main.java:1383) 

Je me demande si le message d'erreur peut être un hareng rouge. L'erreur se produit lors d'un appel à IMethod[] methods = type.getMethods();

Si je mets un il point d'arrêt et de regarder type dans la vue Variables du débogueur, je vois:

CallDataTest (not open) [in CallDataTest.java [in nz.ac.vuw.ecs.kcassell.callgraph [in test [in ClassRefactoringPlugin]]]] 

Je me demande si j'omets une importante étape préliminaire pour rendre le projet disponible pour examen. Tout d'abord, je tente d'activer le plan de travail, comme ceci:

public static void activateWorkbench() { 
    // possible for PlatformUI.getWorkbench to throw an IllegalStateException 
    // if the workbench is not yet started e.g createAndRunWorkbench() has not yet been called 
    IWorkbench workbench = PlatformUI.getWorkbench(); 
    IWorkbenchWindow workbenchWindow = 
     workbench.getActiveWorkbenchWindow(); 
    workbenchWindow.getActivePage(); 
} 

Ensuite, j'essaie d'obtenir le type en utilisant la poignée:

protected IType iType = EclipseUtils.getTypeFromHandle(
     "=ClassRefactoringPlugin/test<nz.ac.vuw.ecs.kcassell.callgraph{CallDataTest.java[CallDataTest"); 

public static IType getTypeFromHandle(String handle) { 
IType type = null; 
IJavaElement element = JavaCore.create(handle); 
if (element == null) { 
    System.err.println(" No element created from " + handle); 
} else if (element instanceof IType) { 
    type = (IType) element; 
} 
    return type; 
} 

Je suis nouveau plug-in de développement, de sorte que toute aide serait très appréciée.

Cheers, Keith

+0

Je confirme que vous n'avez pas besoin de mettre votre plugin exporté dans le dossier dropins car Eclipse utilise la version du plugin que vous écrivez dans le projet lorsque vous exécutez la configuration JUnit Launch. Pouvez-vous coller la trace de pile complète parce que je ne pense pas que le problème concerne la configuration de Junit run. Si vous êtes en mesure de lancer, je suppose que la classe de test est disponible dans l'onglet de configuration Junit Run principal? –

+0

Je ne suis pas tout à fait sûr de ce que vous entendez par "l'onglet de configuration Junit Run principal"? Depuis Eclipse, si je fais Run-> Run Configurations, j'obtiens une fenêtre "Run Configurations" qui liste CallDataTest comme un "JUnit Plug-in Test". Est-ce que c'est ce que tu voulais savoir? Je suis en train de modifier la publication d'origine pour inclure la trace de la pile. – kc2001

+0

J'ai mis à jour les informations dans la publication principale pour refléter le passage à une nouvelle version d'Eclipse. – kc2001

Répondre

1

Je ne sais pas exactement ce que vous essayez de faire ici, mais il semble que vous essayez d'écrire un test JUnit pour votre plugin. Est-ce correct?

Selon l'identificateur de poignée élément java que vous créez, il devrait y avoir un projet appelé ClassRefactoringPlugin dans votre espace de travail et là, est un dossier source appelé test, et une classe java appelé CallDataTest dans un package appelé nz.ac.vuw.ecs.kcassell.callgraph.

Je suppose que ce n'est pas le cas et que vous voulez référencer un fichier de classe dans le plugin que vous venez de créer. Avant de pouvoir faire cela, vous devez importer un projet dans votre espace de travail de test, définir son chemin de classe, puis accéder à son contenu à l'aide des identificateurs de handle.

Je peux mal comprendre ce que vous essayez de faire, mais il semble que vous essayez d'accéder à un fichier java qui n'existe pas dans votre espace de travail. Si vous pouvez confirmer que c'est ce que vous voulez faire, je peux vous diriger vers un code de test qui fait exactement ce que vous voulez.


Certains projets Open Source font exactement cela et vous pouvez emprunter une partie de leur code source pour votre usage. Un projet que je connais est Groovy-Eclipse http://groovy.codehaus.org/Eclipse+Plugin (puisque je suis le chef de file de ce projet).

Voici un lien vers la classe que nous utilisons pour créer et gérer des projets de test:

https://svn.codehaus.org/groovy/eclipse/trunk/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/TestProject.java

Vous pouvez utiliser tout ou partie de ce code pour vos propres tests. N'oubliez pas de supprimer tous les projets à la fin de chaque test.

+0

Je crois que toutes les conditions préalables que vous avez mentionnées sont définies correctement. Je ne comprends pas votre référence à un «espace de travail de test». J'ai un espace de travail contenant mon ClassRefactoringPlugin qui a à la fois src et des dossiers de test. Lorsque je clique avec le bouton droit sur CallDataTest et "Exécuter en tant que test de plugin JUnit", un nouveau plan de travail est généré. Si je fais cela en mode débogage, je peux réellement passer en revue le code dans le test en utilisant le débogueur. C'est pourquoi je me demande si le message d'erreur peut être trompeur. BTW, je plugin code fonctionne bien dans un espace de travail généré lorsque je débogue, juste pas quand j'essaie d'exécuter des tests JUnit. – kc2001

+0

Droite. Les tests JUnit plugin engendrent un nouvel espace de travail, mais cet espace de travail est initialement vide. Vous essayez d'accéder à un projet (et son code source) qui existe dans l'espace de travail standard, mais pas à votre espace de travail JUnit d'exécution. Je présume que lorsque vous lancez un espace de travail runtime (pas un runtime JUnit), alors vous avez un projet dans cet espace de travail appelé CallDataTest. Vous devez importer 'CallDataTest' dans votre espace de travail JUnit si vous voulez créer un' IJavaElement' basé dessus. Il n'y a pas d'API simple pour cela, mais il y a beaucoup de projets open source qui doivent faire la même chose. –

+0

Mise à jour de ma réponse pour inclure un lien vers un exemple de code source. –

0

Avaient une erreur similaire pour des raisons différentes. Mon erreur a commencé après avoir renommé le paquet cible dans le projet. Après avoir essayé la solution de paskster sans succès, j'ai commencé à diggin '. Le problème réel était que renommer le nom du paquet à partir du fichier manifeste ne fonctionnait pas comme prévu. Je pensais que ça changerait tout partout. Toutefois, l'ancien nom de package était toujours dans le fichier manifeste dans le répertoire de test et dans certaines vues dans les ressources. Après l'avoir renommé manuellement et reconstruit le projet, l'erreur a disparu.

Ceci est la réponse acceptée pour une autre question: Java Model Exception: Java Model Status [gen [in MyApp] does not exist] after Eclipse Android project Clean

Depuis le propriétaire de cette question mise a voté cette réponse comme une solution avec un lien à cette question, je pensais que je poste ici aussi .

+0

Malheureusement, ma joie initiale à la lecture de votre message était prématurée. J'ai fait en sorte que chaque nom soit cohérent et je pouvais toujours avoir le problème. Cependant, je n'ai pas remarqué d'informations "test" spécifiques dans le MANIFEST. – kc2001