Hi,

It looks our move to split up resources and compiled classes a few milestones 
back has broken some JPA features. Some background is here: 
http://forums.gradle.org/gradle/topics/regression_with_classloading_in_the_jetty_plugin_with_gradle_1_0_milestone_6

The problem is that the JPA spec requires that class path scanning must be done 
using the root URL of the META-INF/persistence.xml resource. So, if you're 
running against build/classes/main and build/resources/main, the JPA 
implementation will find persistence.xml in build/resources/main, and then go 
scanning that directory for annotated classes. It won't scan 
build/classes/main. And this, of course, means it won't find anything.

You can run into this problem any time you run your code from a task in the 
same project: such as 'jettyRun' or 'test' or (application plugin's) 'run'. You 
don't run into this problem when you use the code from a publication (e.g. via 
a project dependency, or in a war, or an installed application).

I'm not sure what the best solution is here. Some options:

1. Merge the resources and classes back together again into build/classes/main. 
They were originally split to allow us to point the IDEs at the generated 
resources, without having them include all the classes. They also help with 
incremental build, as there's less stuff to scan in each output directory.

2. Always run against the jar, rather than build/classes/main and 
build/resources/main.

3. Add a 'jpa' plugin, which rewires things so that 2. happens.

4. As for 1, but if you're using an IDE plugin, rewire things so that resources 
are generated first into a separate directory that the IDE uses, and then 
copied into build/classes/main.

My preference is to keep the resources and classes separate. Option 2. is not a 
bad option, as execution in the project will look more like execution outside 
the project, from the code's point of view. The downside is the potential 
performance hit we take with building the jar before running the tests.

Options 3 is interesting, in that it states 'this project is using JPA', which 
we can later use to do useful things: create test databases to point the tests 
at, wire config + database instances up at deploy time, configure the JPA 
integration in the IDEs, and so on. Option 3 is also interesting in that we 
don't have to try to solve for the lowest common denominator (which may end up 
being impossible) - we can lay out compile + execution as we think makes sense 
for most projects, and then package up the exceptions as plugins.


Thoughts? other options?


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com

Reply via email to