Java.lang.Class # getAnnotation () returns null when called in eclipse plugin

I am writing an eclipse plugin to support Frege programming language. I use the IMP meta-tool platform and Eclipse Indigo (3.7). Runtime is Java 1.7.

The plugin uses the same code as the batch compiler for parsing, parsing, etc. However, when I started from the eclipse plugin, I noticed different behavior and traced it to the next method, which reads a class file from a previously compiled module to get meta-information, which is stored there in the form of java annotations:

public static MD.Operator[] getOperators(ClassLoader loader, String pack) throws ClassNotFoundException { Class<?> cl = null; cl = loader.loadClass(pack); MD.FregePackage os = cl.getAnnotation(MD.FregePackage.class); if (os == null) return null; // <-- no annotation present return os.ops(); } 

Note that the code creates its own instance of URLClassLoader , which is passed as an argument. If I did not set the class path correctly, the getOperators method throws a ClassNotFoundException correctly, so I'm sure it loads the class. A trace message tells me that the class loader is built in the following path (by default, this is the class path):

 mkClassLoader:[C:\opt\eclipse\plugins\org.eclipse.equinox.launcher_1.2.0.v20110502.jar, X:\dev\frege\build] 

Since the class file not created by the frege compiler usually cannot contain the MD.FregePackage annotation, this usually indicates that the user tried to import a simple Java class, and indeed I get the following message in the plugin:

 X:/dev/runtime-EclipseApplication/TestJFrege/src/Neu.fr:1: `frege.prelude.Base` is not a frege package 

However, from the command line I can compile this just fine. I have included this here as evidence that the relevant annotations can indeed be downloaded from the same place:

 X:\dev\frege>java -cp ./build frege.compiler.Main X:/dev/runtimeEclipseApplication/TestJFrege/src/Neu.fr mkClassLoader: [./build] running: javac -cp ./build -d . -encoding UTF-8 ./Neu.java 

Resumption of facts:

  • The code that should load the annotations works fine when the compiler is invoked through the command line interface.
  • The code that should download the annotations does not know if it is called from the plugin or command line. In fact, the plugin did not even exist until last week, while the command line interface worked fine for several months.
  • Annotations, of course, are RetentionPolicy.RUNTIME , otherwise compiling the command line also does not recognize them. But it will work.

So, the only conclusion I can make is that Class.getAnnotation() somehow doesn't work correctly. This is very unsuccessful, since it effectively destroys the basic functions that I need for a modular system.

If it matters: the Frege compiler code that uses the plugin is written to Frege itself, and the frege.prelude.Base class mentioned above is the base library that every module needs, so it should already be loaded when the plugin is activated, although of course , with another classloader.

Does anyone have such experiences? Can this be solved and how? Any suggestions on how to get around this are welcome.

+4
source share
1 answer

Has the MD.FregePackage class MD.FregePackage loaded by the class loader used in your method? Perhaps first try loading this first, as two classes are not equal() if they were loaded by different class loaders. This may explain why it was not found.

+2
source

Source: https://habr.com/ru/post/1383609/


All Articles