6 Replies Latest reply: Oct 7, 2010 12:51 PM by 799936 RSS

    javac auto-compiles files created by a processor. how to turn it off?

    799936
      I wrote an annotation to annotate classes and methods, which should be extracted to create in interface-like class structure. The main idea is to provide an interface-JAR to developers who then can write plug-ins with it.

      I'm using ANT to call javac:
                <javac srcdir="${dir.src}/${dir.main}/java"
                          destdir="${dir.tmp}"
                          classpath="${classpath.libs};lib/one-jar-boot.jar"
                          fork="true">
                     <compilerarg line="-processorpath ${classpath.libs};bin/${dir.main};${dir.src}/${dir.main}/${dir.resources}" />
                     <compilerarg line="-processor com.my.super.CompilerProcessor" />
                     <compilerarg value="-proc:only" />
                     <compilerarg line="-s ${dir.tmp.src}/${dir.interface}" />
                     <compilerarg line="-d ${dir.tmp.jar}/${dir.interface}" />
                     <compilerarg value="-J-XX:-PrintCommandLineFlags" />
                     <compilerarg value="-implicit:none" />
                </javac>
      The processor creates all Java-files the way I want to in the correct folder. However, once that step of the processor has completed, javac tries to compile those new files. Since they all have the same name as the original, it fails. Because there are more than just a few classes, I end up with a long pointless list of "duplicate class"-errors. For obvious reasons those errors are correct. I know that and that's why I want to tell javac to simply not compile those new files.

      I put a log-statement at the beginning of process() to list the annotations and the round-environment:
      [com.my.super.Annotation]/[errorRaised=false, rootElements=[<a list of affected classes>], processingOver=false]
      G:\Source\Eclipse\project\target\tmp\src\interface\com\my\super\classes\ClassA.java:7: duplicate class: com.my.super.classes.ClassA
      public class ClassA {
             ^
      :
      :
      []/[errorRaised=false, rootElements=[<a list of affected classes>], processingOver=false]
      []/[errorRaised=false, rootElements=[], processingOver=true]
      For simplicity I only put one error here.

      The "-J-XX:-PrintCommandLineFlags" doesn't seem to do anything, by the way.

      My goal is to get rid of the round of compiling. Please understand that I'm new to the processor-stuff and I may have overlooked something basic or used something wrong. I'm impressed that it all works this good so far...

      What can I do? Or what am I doing wrong here?
        • 1. Re: javac auto-compiles files created by a processor. how to turn it off?
          jschellSomeoneStoleMyAlias
          If it was me I would do the following
          - Create a directory with two small test files in it.
          - Use the command line (not ant) to play with compiler options.

          I believe there is an output directory option.

          If all else fails it should be possible to write an ant task that
          1. List all files
          2. Compile each file individually
          3. Move generated file out after completion.
          • 2. Re: javac auto-compiles files created by a processor. how to turn it off?
            799936
            jschell wrote:
            If it was me I would do the following
            - Create a directory with two small test files in it.
            - Use the command line (not ant) to play with compiler options.

            I believe there is an output directory option.
            The -d option sets the output directory. As I said, that works fine. That directory seems to be added to the classpath automatically.
            jschell wrote:
            If all else fails it should be possible to write an ant task that
            1. List all files
            2. Compile each file individually
            3. Move generated file out after completion.
            I can't compile each file individually as they are compiled automatically after the annotation processor runs through all classes the first time. And that part is what I want to skip because I know that it breaks due to classpath-issues ("duplicate class"). See my output from previous post.

            Edited by: verminator on Oct 3, 2010 5:43 PM
            • 3. Re: javac auto-compiles files created by a processor. how to turn it off?
              799299
              Hello,

              Is it possible to you exclude the original classes/annotated from the classpath of the compiler?

              Perhaps using a reference for the classpath ( classpath refid= ) where you can decide what include/exclude ( exclude name= ) works for you.


              Best reggards,
              <path id="classpath">
                   <fileset dir="${classpath.libs}">
                      <include name="**/*.jar"/>
                      <exclude name="**/*whatever*"/>
                </fileset>
                <pathelement location="lib/one-jar-boot.jar"/>
              </path>
              
              <javac srcdir="${dir.src}/${dir.main}/java"
                                  destdir="${dir.tmp}"                    
                                  fork="true">
                             <classpath refid="classpath" />     
                             <compilerarg line="-processorpath ${classpath.libs};bin/${dir.main};${dir.src}/${dir.main}/${dir.resources}" />
                             <compilerarg line="-processor com.my.super.CompilerProcessor" />
                             <compilerarg value="-proc:only" />
                             <compilerarg line="-s ${dir.tmp.src}/${dir.interface}" />
                             <compilerarg line="-d ${dir.tmp.jar}/${dir.interface}" />
                             <compilerarg value="-J-XX:-PrintCommandLineFlags" />
                             <compilerarg value="-implicit:none" />
              </javac>
              • 4. Re: javac auto-compiles files created by a processor. how to turn it off?
                799936
                First, sorry for the delay.

                And then I completely misread Seguy's post...

                I'll be back later.

                Edited by: verminator on Oct 7, 2010 6:02 PM
                • 5. Re: javac auto-compiles files created by a processor. how to turn it off?
                  799936
                  Seguy Gasques wrote:
                  Hello,

                  Is it possible to you exclude the original classes/annotated from the classpath of the compiler?

                  Perhaps using a reference for the classpath ( classpath refid= ) where you can decide what include/exclude ( exclude name= ) works for you.


                  The problem seems to be srcdir-parameter, which is applied for the processor and then again for compiling process, which shouldn't happen (I just noticed this). Now, the compiling fails because of the "duplicate" source files, not the class-files... I don't see a way to turn that one off.

                  Anyway, next post :)
                  • 6. Re: javac auto-compiles files created by a processor. how to turn it off?
                    799936
                    I managed to somehow work around this.

                    In the processor I added this line after creating all source files:
                              processingEnv.getMessager().printMessage(Kind.ERROR, "This error happens on purpose! The generated sources shouldn't be compiled.");
                    This would normally let ANT fail. However:
                              <javac srcdir="${dir.src}/${dir.main}/java"
                                        destdir="${dir.tmp}"
                                        classpath="${classpath.libs};lib/one-jar-boot.jar"
                                        fork="true"
                                        failonerror="false">
                                   <compilerarg value="-proc:only" />
                                   <compilerarg line="-processorpath ${classpath.libs};bin/${dir.main};${dir.src}/${dir.main}/${dir.resources}" />
                                   <compilerarg line="-processor com.my.super.CompilerProcessor" />
                                   <compilerarg line="-s ${dir.tmp.src}/${dir.interface}" />
                                   <compilerarg line="-d ${dir.tmp.jar}/${dir.interface}" />
                                   <compilerarg value="-implicit:none" />
                              </javac>
                    where
                                        failonerror="false">
                    is the most important line. Now ANT will continue even though the processor "fails".

                    IMHO that's not the nicest way to make this work, but now things run a bit faster and less spammy :)

                    In other words, this one is answered. Thanks to all who participated and thought about it.