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

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

Related

What is a bundle resource path in class loader? How do I access that path?

I have a web application deployed to Websphere and found that there are some conflicting jars. To find the path of the conflicting class I have added the below code
ClassLoader classLoader = MyClass.class.getClassLoader();
URL resource = classLoader.getResource("org/apache/http/conn/ssl/AllowAllHostnameVerifier.class");
System.out.println(resource);
When I check the IBM System.out log file I see the below path for resource. I am not sure what bundle resource path is. I would like to know how do I access the below location?
bundleresource://85.fwk734572965/org/apache/http/conn/ssl/AllowAllHostnameVerifier.class
"bundleresource" URLs represent entries from the OSGi framework class loader. The number maps to a bundle number in the OSGi configuration, which you can find by opening up the OSGi console (from the WAS_HOME/bin directory, osgiConsole.sh|bat -server <servername>) and running the "ss" command, which lists the bundles along with their state and numerical ID.
Assuming you're seeing a conflict at runtime through class loading (not actually pulling in these classes through getResource), I'll say with fairly strong certainty that you're picking up the conflicting classes from the JAX-RS prereq jar, WAS_HOME/plugins/com.ibm.ws.prereq.jaxrs.jar. At the time it shipped, that jar made its copy of Apache HTTP visible to applications. That visibility was removed in a later fixpack, if you're able to patch up your installation to the latest service level.
Note that even if you move to a newer fixpack with that fix, your testcase will probably still show the same thing - I don't think that getResource() is subject to the same filtering as loadClass(), so you might still be able to get at the .class file in that manner. It might help with the issues you're seeing at runtime, though.

Generating XML Resources into Classpath using Annotation Processors

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

Can I read property file with jetty in development?

I am working on a lift project as a sub-project in a gigantic mvn project. I put the property files into:
src/main/resources/props/staging.props
src/main/resources/props/production.props
in the sub-project folder.
Then I run jetty with:
mvn jetty:run -Drun.mode=staging
I printed out the settings from net.liftweb.util.Props using:
println("file_name:" + Props.fileName)
println("mode_name:" + Props.modeName)
The output:
file_name:lift.props
mode_name:staging
The mode name is correct. However, the file name is totally wrong. net.liftweb.util.Props is still using the file name that had been hardcoded in the source. It seemed never reached my property file.
Am I missing something? Or it cannot work with jetty?
While duffymo is right and you can just use the underlying servlet facilities for getting resources, I would still use Lift's Properties abstraction. It already does the work for differentiating different run modes. It also allows you to have different properties per-user and/or per-machine, which can be useful, depending on your development team.
The default properties for a given mode should be put in /props/modeName.default.props, so your files should be renamed to:
src/main/resources/props/staging.default.props
src/main/resources/props/production.default.props
I would put the .properties file in your /WEB-INF/classes and use the servlet context's getResourceAsStream() to read it in.

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).

Spring classpath path unit testing eclipse

I have been reading:
http://static.springsource.org/spring/docs/2.5.x/reference/resources.html
But am having difficulty understanding how to specify classpath resource paths. For example I have a project structure as follows in an eclipse spring project:
project1
src
main
resources
maincontext.xml
test
resources
testcontext.xml
java
uk
co
project1
Unittest.java
Then in my testfile I have:
#ContextConfiguration(locations={"classpath:testcontext.xml", "classpath:<path of maincontext>"})
public class BlacklistTest extends AbstractTransactionalJUnit4SpringContextTests{
When I right click on my test file and select debug as JUnit test, the testcontext.xml is found fine. This makes me think the root of my classpath is "project1/src/test/resources". I do not understand where this is determined in eclipse..? Furthermore once I have done this, how do I include maincontext.xml if it is above my root? And finally if I included another project 'project 2' and wanted to add a spring context file from it, how do I reference that in my unittest.java file.
The "root" of your classpath is, literally, "" (an empty string, consider it like a "/" on a filesystem).
It looks like you're using Maven. This means that things like /src/main/java, /src/main/resources, etc. get merged during the build process--in other words, Eclipse uses each as a source directory. The test hierarchy follows suit.
You don't want to include something that is "above" your root--IMO stick to classpath resources. If you don't, you must name it explicitly, leave off the "classpath:" prefix, since it isn't on the classpath, and provide a fully-qualified path (or as fully-qualified as your environment requires, for example, a web-app filename may be based off of the web context root, like "/WEB-INF/foo-context.xml").