Generating XML Resources into Classpath using Annotation Processors - annotation-processing

I am currently working on a Gradle 3.3 project in Intellij 15.0.6.
I am using the Gradle APT plugin to add annotation processors to my classpath.
It works fine when generating Java class files, however I need to be able to generate XML sources within the resources directory equivalent in the build directory's generated directory.
Here is my build directory structure currently:
Project Build Directory Image
As you can see, it does not include a resources directory, which I suspect is what may be causing this problem.
The current exception I receive from running my annotation processor via ./gradlew assemble is: java.lang.IllegalArgumentException: Resource creation not supported in location CLASS_PATH
The code I am using within my annotation processor to generate the xml file:
FileObject source = processingEnv.getFiler()
.createResource(StandardLocation.CLASS_PATH, "", "ap-test-2.html");
Note: I used an HTML extension just as a test, XML should produce the same results.
javax.tools.StandardLocation has other output locations as well:
The SOURCE_OUTPUT location worked to place the XML within the same package as the generated Java classes, within src/apt/main. This is not my desired behaviour however. I need them to reside within the classpath.
I have not found this exception discussed anywhere else after extensive research.
Any help is appreciated. Thank you for reading this question.

StandardLocation.CLASS_PATH is only for input, not output. The only output locations are SOURCE_OUPUT (the build/generated/source/apt/… folder), CLASS_OUTPUT (the standard Gradle build/classes/…), and NATIVE_HEADER_OUPUT. See https://docs.oracle.com/javase/8/docs/api/javax/tools/StandardLocation.html
JavaC has no notion of classes vs. resources outputs, but if you run your annotation processor during your compilation then CLASS_OUTPUT should work (Gradle should then copy everything into the final directory/JAR). See https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javac.html

Related

Don't load/scan class files from a specific jar

I'd like to know how to configure the maven-bundle-plugin (backed by bnd) to completely ignore the classes contained within an embedded jar.
Background
I'm working in a controlled environment where the environment my code is running on is defined by a single company (including all the tools). The code is java and uses OSGi to define module dependencies.
Some of the provided modules contain what look like invalid class files, I can only assume that the system will 'correct' these class files before it tries to load them into any type of JVM. In any case these class files work when deployed onto the target system.
I'm trying to create a build system based on Maven that can produce packages the system understands and have hit a problem where these invalid class files are being read by BND (via apache-felix) which causes errors.
I'd like a way to have the jars that contain these class files on the class path of the bundle but where the contained .class files aren't read/processed by bnd. I could settle for simply ignoring the errors and continuing but can't find a way to do that either without felix aborting the entire build phase.
I just found the -failok directive, don't know why I didn't find it before. Adding <_failok>true</_failok> to the instructions allows me to continue working.
See instructions-ref

Creating javadoc with gwt-user.jar through Gradle

I'm trying to compile the javadocs for my application, and for some reason it throws errors while compiling like this:
/Users/Sander/.gradle/caches/artifacts-23/filestore/com.google.gwt/gwt-user/2.4.0/jar/949dcb5d14cb0e2c8dec98efc0760be68753c124/gwt-user-2.4.0.jar(com/google/gwt/dom/client/CanvasElement.java):18: error: cannot access Context
import com.google.gwt.canvas.dom.client.Context;
All the errors thrown are found in gwt-user-2.4.0.jar. Basically, what (I think) it's trying to do is compile the .java source files the jar file contains, which it shouldn't do. Is there a way to make the javadoc command ignore java source files?
I've tried removing the source files from the jar manually, this way the build succeeds. However, since the jar is a gradle dependency, manually altering the file is not an option.
I finally got it to work. As it turned out, the javadoc command needed a sourcepath flag set, because otherwise it would start looking for the source files in the classpath, which contained some source files from the GWT jar file. Since the MinimalJavaDocOptions GWT class doesn't support this, I had to set it manually by adding the following line:
options.addStringOption("sourcepath", <path_to_source>)
This fixed the problem. Obviously it is not ideal, a topic in the Gradle Support Forums has already been created, see http://forums.gradle.org/gradle/topics/allow_javadoc_sourcepath_to_be_set_directly

Spring Webflow 2.3 Testing (with Maven): How to reference parent flow with filename different from id

I debugged my Spring Webflow test to the point of figuring out the first part of the issue: When you have a flow with a filename that is not the same as the id of the flow ('commons-flow.xml' with id='commons') then just using resourceFactory.createFileResource(pathToFlowFile) does not work because that assumes the id is the filename.
There is a method available to override the id, resourceFactory.createResource(pathToFlowFile, attributesMap, overrideId)
However, this uses the Classloader to resolves files whereas it seems the createFileResource used a different means.
I cannot figure out how I am supposed to get the Classloader to recognize the flow files. I inspected it's classpaths and it only has the JAR dependencies and then dynamically created target/classes and target/test-classes folders. No reference to my project.
This is a Maven project, and the path I have from project root to flows is something like:
src/main/webapp/WEB-INF/flows/<flow-folder>/<flow-filename>.xml
I have seen webflow testing, unable to find flow model which reiterates what I discovered already, but for some reason I have the issue with the Classloader that other seems not to have.
Where I see people successfully referencing the flow files, they seem to either be relative from the project root or relative from the WebContext at src/main/webapp.
I am running the JUnit test with a Run Configuration in Eclipse and also with the maven test goal.
It is possible for me to configure a custom classpath for the Run Configuration in Eclipse to include the parent folder of the relative path I have defined as pathToFlowFile.
However, that does not help at all with Maven, which has the classloader/classpath issue still when executing the test goal.
I ran into something similar where I had to set the flow id and specify the path. So instead of using the FlowDefinitionResourceFactory I created a FlowDefinitionResource instance like below
FlowDefinitionResource resource = new FlowDefinitionResource(flowId, path, attributes);
So in your method you should have something like this
protected FlowDefinitionResource[] getModelResources(FlowDefinitionResourceFactory resourceFactory) {
FlowDefinitionResource resource = new FlowDefinitionResource("flowId", src/main/webapp/WEB-INF/flows/<flow-folder>/<flow-filename>.xml", null);
return new FlowDefinitionResource[] {resource};
}
If you get a FileNotFoundException just check the stacktrace to see where it is looking for the file.
Hope this helps.
M

Packaging GWT module jar

I have created a GWT-loadable module (maven) with this output jar structure (using mvn package command):
mygwtlibrary
->src/main/java
-->org.mygwtlib
---->public
------>flash.swf
-->org.mygwtlib.client
---->MyClientCode.class
However when I run a application that use this library, error shows: Error 404 for fetching the flash.swf file.
Here's the scenario:
I have setup the project properly, including the <inherits> in the gwt.xml file
When I just include the whole library project into another GWT application project then run, it works fine. That is, the files from the public folder is loaded too.
What could be the problem?
The problem is that you're trying to fetch the flash.swf file over HTTP. This is (at best) bad practice. A better approach (by no means the only alternative) would be pulling it in as a resource which lives in your code. One way to do such a thing would be using Spring's ClassPathResource (or less preferably, FileSystemResource).

Loading resources off the classpath in Jython using 'classpath:'

I've got a relatively large Java application that would benefit from a bit of Python love. To that end I've been working on getting it up and running in Jython. My current roadblock is getting the classpath right.
I've taken two approaches to setting the classpath:
Using a shell script, I've built up a list of jars and executed java -cp ${CP} -jar jyton.jar where $CP is a list of the jars needed for my app. This doesn't seem to work. I'm unable to import any classes from these jars, getting only ImportError: No module named apache instead.
Using a bootstrap python script, i've created a list of paths using glob, and appended them to the current path using [sys.path.append(path) for path in JAR_LIST]. This seems to work correctly; I can now import any of the classes I need to from the included jars.
The above is a bit confusing as most information I've been able to find has steered towards using $CLASSPATH and -cp to added your jars, but I can't get that to work. So the question so far: Is #2 the proper way to add dependancies to your classpath when using Jython?
The main reason I question my methods is because I'm still having problems fully utilizing my application. A number of places in my app reverences resources using relative URLs : classpath:some-critical-file.xml
some-critical-file.xml and a number of my classes reside within the same jar. I'm able to import classes from that jar, but any attempts to load my xml with classpath:some-critical-file.xml results in a java.io.FileNotFoundException
Any insight as to why my classes are available but relative paths to resources using classpath: are not would be much appreciate. I'm at a loss at this point.
I've run into a little classpath weirdness myself lately. Have you tried the old school approach of:
CLASSPATH = ${CLASSPATH}:your.jar
export CLASSPATH
jython your_script.jy
If you're invoking the standalone jar using java -jar then from the Java Documentation ...
-jar
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
So it it not possible to add anything to the classpath when using -jar. See this answer for a solution - basically add the jython.jar to the classpath (either using -cp or CLASSPATH) and run the org.python.util.jython class directly.