« Return to Thread: JSR-199 Compiler API loses runtime annotations when run under grails-run app

JSR-199 Compiler API loses runtime annotations when run under grails-run app

by Dave Doty-2 :: Rate this Message:

Reply to Author | View in Thread

I have a project in which I am sending source code to a grails server to be compiled using the Java Compiler API, JSR-199. I am having problems implementing it, and have boiled the problem down to the following: When compiling a file under "normal circumstances" (running a java program with java, or running JUnit tests, for instance), the JSR-199 compiler preserves runtime annotations, but executing the exact same code when running grails run-app, the runtime annotations are not preserved by compilation. I have no idea what could account for the difference, or if this is a Grails issue, or a JSR-199 issue, or a bit of both. To reproduce the effect, do the following (using JDK 6, since JSR-199 was introduced in version 6):

1) Create a grails project by executing "grails create-app Test"
2) Download JUnit 4 and place the file junit-4.4.jar in Test/lib/
3) Create a package clientpackage under Test/src/java/, and in that package, create a file ExampleTest with the following code:

ExampleTest.java begin:
------------------------------------------------------------------------------------

package clientpackage;

import org.junit.Before;

public class ExampleTest {
  @Before
  public void setUp() {}
}

------------------------------------------------------------------------------------
ExampleTest.java end


4) Edit conf/BootStrap.groovy to contain the following code:

Bootstrap.groovy begin:
------------------------------------------------------------------------------------

import javax.tools.*
import javax.tools.JavaCompiler.CompilationTask

class BootStrap {

  def destroy = {}

  def init = {servletContext ->
    testCompiling()
  }

  def testCompiling() {
    println '\n*****************************************\n'

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler()
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)
    Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects('src/java/clientpackage/ExampleTest.java')
    StringWriter errorLog = new StringWriter()
    File outputDir = new File("bin/")
    outputDir.mkdir()
    List<String> options = Arrays.asList("-cp", "lib/junit-4.4.jar", "-d", outputDir.toString())
    CompilationTask task = compiler.getTask(errorLog, fileManager, null, options, null, compilationUnits)

    if (task.call()) {
      println 'compilation succeeded'
      URL[] urls = [outputDir.toURL()]
      URLClassLoader classLoader = new URLClassLoader(urls);
      Class<?> compiledClass;
      try {
        compiledClass = classLoader.loadClass('clientpackage.ExampleTest')
      } catch (ClassNotFoundException e) {
        throw new AssertionError("should not reach here if compilation succeeded")
      }
      println compiledClass.getMethod('setUp').getDeclaredAnnotations()
    } else {
      println "compilation failed:\n\n${errorLog.toString()}"
    }

    println '\n*****************************************\n'
  }

}

------------------------------------------------------------------------------------
Bootstrap.groovy end


5) Create a Groovy script (for instance, in the root directory of the project) named CompileExampleTest.groovy, that contains the same code between the println '\n*****************************************\n' statements above, and the same two import statements.
6) Run the script CompileExampleTest.groovy (with working directory set to the Test project root directory) and you should see the following output:

    compilation succeeded
    {@org.junit.Before()}

indicating that the method setUp() is annotated, at runtime, with the org.junit.Before annotation. Now run grails run-app, and you should see the following output when BootStrap.groovy runs:

    compilation succeeded
    {}

indicating that the org.junit.Before annotation was lost during compilation (or during class loading).

I have no idea what could explain the difference in behavior between these two seemingly identical pieces of code.

Thank you in advance,
Dave

 « Return to Thread: JSR-199 Compiler API loses runtime annotations when run under grails-run app

LightInTheBox - Buy quality products at wholesale price!