On 14/02/2012, at 7:53 PM, Luke Daley wrote:

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

We already have most of this in sourceSets.main.runtimeClasspath. The 
implementation might be something like this:

* Those things that need to execute code within the project should honour 
sourceSets.main.runtimeClasspath (they almost all do already)
* The plugin would change the default for sourceSets.main.runtimeClasspath from 
(sourceSets.main.output + configurations.runtime) to (jar + 
configurations.runtime)
* We might add some convenience properties to SourceSet to ask for the 
(default) runtime class path with classes bundled into a jar, or exploded into 
directories, so the plugin can just do sourceSets.main.runtimeClasspath = 
sourceSets.main.runtimeClasspathWithJar (or whatever).


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

I think we want something more cross-cutting than this, as the problem happens 
where-ever you happen to be running the code, and regardless of whether you're 
building a web app. For example, you can hit it in: grade test, gradle run 
(command-line app), gradle jettyRun (web app).


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