Cannot load resources in Annotation Processor (Not on classpath)

后端 未结 3 508
庸人自扰
庸人自扰 2021-01-04 01:31

I have an annotation processor which shall generate a enumeration with the keys defined by getter methods of an interface.

The interface resides in

相关标签:
3条回答
  • 2021-01-04 01:36

    As a workaround you could try to add the classpath you need to use via a command line argument -Xboothclasspath/a:path, the /a will append the value in path to the boot class path. You would need to add this as a command line option to the actual annotation processing run so in Eclipse that would be: Right click project, select properties, Java Compiler, Annotation Processing, click New in the table and add key -Xbootclasspath/a and the path to add as value. I'm afraid I haven't tried this for annotation processing but it's worth a try!

    0 讨论(0)
  • 2021-01-04 01:55

    My problem is that the properties files are not available via the classloader of the processor or via Filer.getResource(...).

    I'm not sure I'm understanding your problem. But maybe something here will help.

    How can I make the source or classpath of this project available to the processor, so that I can load the properties files ?

    You need to add the src/main/resources as a "source folder" in Eclipse. First select Configure Build Path in Eclipse on your Java project. Then choose the Source tab and click on Add Folder. You should be able to select the src/main/resources folder and click Ok. You should now see the src/main/resources in the Source Folders list.

    If you look into your target/classes directory, you should see all of the files from the resources directory in there which lets you know that they were copied into the classpath correctly.

    # files in the src main resources
    > ls src/main/resources/x/y/z
    jgroups_udp.xml
    # should compile into target/classes
    > ls target/classes/x/y/z
    jgroups_udp.xml org
    # and should show up in the jar
    > -tvf target/project.jar 
       0 Thu Nov 03 18:50:00 EDT 2016 META-INF/
     135 Thu Nov 03 18:49:58 EDT 2016 META-INF/MANIFEST.MF
     ...
    3036 Thu Nov 03 18:49:36 EDT 2016 x/y/z/jgroups_udp.xml
    

    Then in your code you can reference the file by doing the following. This will load the file from the top of the classpath. If it is in a subdir then you lead with:

    InputStream stream =
        getClass().getClassLoader().getResourceAsStream("x/y/z/jgroups_udp.xml");
    

    Btw, if you were using maven, you would add something like the following to you pom.xml:

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>
    
    0 讨论(0)
  • 2021-01-04 02:01

    The issue is the ClassLoader that is bound to the current thread (Thread.currentThread().getContextClassLoader()) is not a URLClassLoader when Processor#process is called. It appears to be a restricted class loader that does not allowing loading resources. This happens with javac, eclipse compiler, maven compiler, etc.

    Luckily your processor class will have an appropriate ClassLoader bound to it (ie getClass().getClassLoader()).

    The problem is most utilities expect the correct ClassLoader to be bound to the thread (most notably the ServiceLoader and ResourceBundles).

    Thus there is a work around. When your Processor executes you can rebind the ClassLoader to the current thread:

    @Override
    public boolean process(
            Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {
    
        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
        //...
    }
    
    0 讨论(0)
提交回复
热议问题