On 13/02/2012, at 10:34 PM, Adam Murdoch wrote:

> 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?

It might be too difficult in the short term, but I'd prefer 3 and a DSL to 
specify that this should happen and have the JPA plugin just “invoke” this DSL.

That is, make a standard function of the war plugin that it can test/run 
against the war easily but does not by default.

-- 
Luke Daley
Principal Engineer, Gradleware 
http://gradleware.com

Reply via email to