Avro
  1. Avro
  2. AVRO-269

Use system compiler to test SpecificCompiler's generated code.

    Details

    • Type: Test Test
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.3.0
    • Component/s: java
    • Labels:
      None
    • Hadoop Flags:
      Reviewed

      Description

      Using the javax.tools API (http://java.sun.com/javase/6/docs/api/javax/tools/JavaCompiler.html),
      it's possible to test SpecificCompiler's
      generated code by compiling it. Doing so caught a couple of
      bugs.

      1. AVRO-269.patch.txt
        10 kB
        Philip Zeyliger

        Activity

        Hide
        Philip Zeyliger added a comment -

        The attached patch adds code to invoke the System compiler to check that generated code
        is valid. In the course of adding these tests, I found a few minor bugs in
        relation to inconsistent capitalization and mangling. I decided to remove
        capitalization altogether (a schema named "foo" becomes "class foo"), because
        that seemed more transparent and consistent. There were a couple of instances
        where names weren't being mangled, which the tests caught.

        Once concern is that this adds about 6 seconds to the running time of all the
        tests. I've gone about it a bit pedantically, and am compiling every darn
        schema in TestSchema... Removing that would chop 5 seconds off, which may
        be a reasonable compromise.

        I had a fair amount of hassle getting the system java compiler to work in ant's
        test runner. The issue is that, by default, the compiler uses the current
        classpath. With the junit ant task, the classpath only has ant's stuff. Ant
        adds other stuff at runtime. I was able to deal with this by adding
        'fork="yes" forkMode="once"' to the junit task works. Without "once" it's
        miserably slow, but with "once" it seems fine. It should have been
        possible to add a "sysproperty" to the task to pass through test.java.classpath,
        and use Arrays.asList("-classpath", System.getProperty("...", System.getProperty("java.class.path")))
        (the "default" to java.class.path is convenient for other JUnit runners,
        like Eclipse's) as the fourth argument to compiler.getTask(), but I couldn't
        get 'sysproperty' to dereference a path reference inside the build.xml.

        I've gone back and forth on actually creating files to compile them.
        There's a trick (inheriting from SimpleJavaFileObject) to keep the source
        files in memory. Though it works, the output files ended up in my
        source directory, and debugging was harder (what do you do when you
        get a compile error), so I went back to using real files.

        Show
        Philip Zeyliger added a comment - The attached patch adds code to invoke the System compiler to check that generated code is valid. In the course of adding these tests, I found a few minor bugs in relation to inconsistent capitalization and mangling. I decided to remove capitalization altogether (a schema named "foo" becomes "class foo"), because that seemed more transparent and consistent. There were a couple of instances where names weren't being mangled, which the tests caught. Once concern is that this adds about 6 seconds to the running time of all the tests. I've gone about it a bit pedantically, and am compiling every darn schema in TestSchema... Removing that would chop 5 seconds off, which may be a reasonable compromise. I had a fair amount of hassle getting the system java compiler to work in ant's test runner. The issue is that, by default, the compiler uses the current classpath. With the junit ant task, the classpath only has ant's stuff. Ant adds other stuff at runtime. I was able to deal with this by adding 'fork="yes" forkMode="once"' to the junit task works. Without "once" it's miserably slow, but with "once" it seems fine. It should have been possible to add a "sysproperty" to the task to pass through test.java.classpath, and use Arrays.asList("-classpath", System.getProperty("...", System.getProperty("java.class.path"))) (the "default" to java.class.path is convenient for other JUnit runners, like Eclipse's) as the fourth argument to compiler.getTask(), but I couldn't get 'sysproperty' to dereference a path reference inside the build.xml. I've gone back and forth on actually creating files to compile them. There's a trick (inheriting from SimpleJavaFileObject) to keep the source files in memory. Though it works, the output files ended up in my source directory, and debugging was harder (what do you do when you get a compile error), so I went back to using real files.
        Hide
        Doug Cutting added a comment -

        I just committed this, with java compiler-based tests disabled in TestSchema. Thanks, Philip!

        Show
        Doug Cutting added a comment - I just committed this, with java compiler-based tests disabled in TestSchema. Thanks, Philip!

          People

          • Assignee:
            Philip Zeyliger
            Reporter:
            Philip Zeyliger
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development