jpa-maven-plugin Released

I’m pleased to announce to my enormous reading audience (both of you) the jpa-maven-plugin project. Please peruse the documentation, the Javadocs and then finally try using it and let me know what you think.

Advertisements

I'm pleased to announce to my enormous reading audience (both of you) the jpa-maven-plugin project.

Please peruse the documentation, the Javadocs and then finally try using it and let me know what you think.

Thread safety and PermissionCollection

I just made an interesting discovery while implementing the PolicyConfiguration#addToUncheckedPolicy(PermissionCollection) method. Notice anything unusual about the contract? No?Consider this: PermissionCollection subclasses need to be thread-safe…

I just made an interesting discovery while implementing the PolicyConfiguration#addToUncheckedPolicy(PermissionCollection) method.

Notice anything unusual about the contract??? No?

Consider this: PermissionCollection subclasses need to be thread-safe, as the Javadoc says:

Subclass implementations of PermissionCollection should assume that they may be called simultaneously from multiple threads, and therefore should be synchronized properly.

OK, so when implementing this method, you might take the na??ve approach, as I did initially.?? The incoming PermissionCollection is thread-safe, so there's no need to synchronize on anything.?? Hopefully you're cringing at my haste:

private final PermissionCollection uncheckedPermissions = new Permissions();

@Override
public void addToUncheckedPolicy(final PermissionCollection permissionCollection) {
?? if (permissionCollection != null && this.uncheckedPermissions != null) {
?????? // Look, ma, no synchronization!

?????? final Enumeration<Permission> elements = permissionCollection.elements();
?????? if (elements != null) {
?? ?? ?? while (elements.hasMoreElements()) {
?? ?? ?? ?? final Permission permission = elements.nextElement();
?????? ?? ?? if (permission != null && !this.uncheckedPermissions.implies(permission)) {
?????? ?? ?? ?? this.uncheckedPermissions.add(permission);
?????? ?? ?? }
?????????? }
?????? }
?? }
}

You could probably get away with this.?? After all, you know that the uncheckedPermissions member variable is guaranteed to be thread-safe (java.security.Permissions instances, like all PermissionCollection subclasses, must be "synchronized properly").?? Surely there's nothing more to worry about?

Wrong.?? JACC makes no guarantees one way or the other about what is happening to the incoming PermissionCollection that you're adding in this method.?? This PermissionCollection could be being modified by some other thread while you're processing it.?? So your elements() call–your enumeration of the individual Permission instances "inside" that PermissionCollection–will be inconsistent and broken.

OK, you think (I think), I'll just synchronize on the incoming PermissionCollection object.?? But there's nothing in the PermissionCollection documentation that indicates that PermissionCollection objects must synchronize on themselves during modification operations (such as add()).?? They can synchronize on whatever they want and are under no obligation to tell you what that mutex is going to be.?? Nine times out of then you're going to be handed a Permissions instance, of course, and if you go look at the source, yes, indeed, the PermissionCollection implementation inside that synchronizes on itself.?? But it certainly doesn't have to, and you shouldn't rely on it.

In the absence of further guarantees, all you can do is add the incoming PermissionCollection to a set of such PermissionCollections, and then, when you actually need to check permissions, walk through the set one by one and call implies() on each PermissionCollection.

The takeaway here is that in any code that you're using that enumerates a PermissionCollection, you're probably doing it wrong unless you have control of "both sides" of the PermissionCollection–unless you control both when Permissions are added to it and when they are enumerated.

Javadocs

One thing I believe very strongly in is good Javadocs.It’s one of the first places that I go when I need to understand how to use a library. I don’t attempt to understand how to use the library through my IDE’s autocomplete statements or the sourc…

One thing I believe very strongly in is good Javadocs.

It's one of the first places that I go when I need to understand how to use a library.?? I don't attempt to understand how to use the library through my IDE's autocomplete statements or the source code.?? I often end up in the source code, but that's usually because the API has not been well-designed or well-documented.

Good Javadocs are very hard to put together because at the same time you begin to put them together you run face-to-face with the weaknesses in your API.?? So you change the API to correct the problem, and now your Javadocs need to be torn up.?? Many developers stop there and throw the Javadocs out, or turn up their nose at them because they're not a very agile thing to do.?? But to me, they're absolutely essential–with them and unit testing, you can put together some decent APIs pretty quickly–or, I guess, more accurately, as quickly as you should be putting them together.?? :-)?? Good APIs take time, and the best ones explain themselves.

Here are some of the things that I do when writing Javadocs:

  • For any class name, I wrap it with the {@link tag}, whenever and wherever it appears.?? Think about that.?? This helps keep the reader in the flow: they can always turn down the styles in their browser or take other measures to get rid of blue underlines–I don't worry about too many links–but having the ability to quickly link to the class under discussion is invaluable.
  • For any identifier, or keyword, I wrap it with the {@code} tag.?? This is just following good typographical style.
  • For every parameter, I document whether null is permitted or not.?? This forces me to figure out what to do with nulls in every situation.?? Sometimes I will realize that accepting nulls is a perfectly reasonable thing to do (more often than not–but this is a stylistic question that every developer has a strong opinion on).
  • For every @return tag, I document whether the method can return null or not.?? Every single one.
  • For personal software, I use the @since tag and supply the month, year and date.?? That helps keep me honest and shows what order I've developed things in.
  • I always try to use the @author tag with my hyperlinked email address.
  • I try to use (and wish I were better at using) the @see tag to establish a rough trail through the API.
  • I try to hyperlink portions of explanatory documentation to methods and fields that the documentation refers to {@linkplain Object#equals(Object) as I do here in this example about the <tt>Object#equals(Object)</tt> method}.?? Note the use of the {@linkplain} tag and the nested <tt>s.
  • I have a standard boilerplate Subversion-friendly Javascript hairball that I use for the @version tag (I use keyword expansion of $Revision$):

@version <script type="text/javascript"><!–
document.write("$Revision: 0.0 $".match(/d+.d+/)[0]);
–></script><noscript>$Revision: 0.0 $</noscript>

Hope this helps you think about how you document your own code.

Towards a composable Policy delegation framework

The first step in putting together a Java Policy-based security system of any kind is to figure out what you’re going to do when you have to delegate.You will have to delegate certain permission checks in certain situations–there’s just no pragma…

The first step in putting together a Java Policy-based security system of any kind is to figure out what you're going to do when you have to delegate.

You will have to delegate certain permission checks in certain situations–there's just no pragmatic way around it.

Different security systems require different algorithms for checking permissions.?? Sometimes you might have several subsystems that all have to effectively vote on a permission check, and there will need to be an algorithm in place for such collaborative efforts that can resolve conflicts.

When a security system is asked whether a permission to do something is granted or not, it can respond in one of several ways.?? It can:

  • Grant the permission.?? This might not be the final word.
  • Deny the permission.?? This might not be the final word either.
  • Mandate the permission.?? For whatever reason, this security system's answer should be treated as the final word.
  • Prohibit the permission.?? For whatever reason, this security system's answer should be treated as the final word.
  • Not support the permission.?? The security system might not be equipped to render an answer at all for this kind of permission check.
  • Waffle.?? Perhaps the security system supports the permission, but cannot render a decision because of, say, conflicting information.

Ultimately, the caller is almost always interested at some level in a boolean response.

This sounds like an enum:

public enum PermissionEvaluation {

?? UNSUPPORTED,
?? INDETERMINATE,
?? DENIED,
?? PROHIBITED,
?? GRANTED,
?? MANDATED;

?? public boolean isAuthoritative() {
?????? return this == PROHIBITED || this == MANDATED;
?? }

?? public boolean toBoolean() {
?????? switch (this) {
?????? case GRANTED:
?????? case MANDATED:
?????????? return true;
?????? default:
?????????? return false;
?????? }
?? }
}

This enum captures the kinds of permission evaluations that are possible, the boolean values to which they reduce, and an indication of how "strong" or authoritative they are (in the absence of a higher authority).

From there, we might be able to extrapolate a PermissionEvaluator interface:

public interface PermissionEvaluator {

?? public PermissionEvaluation evaluate(final ProtectionDomain protectionDomain, final Permission permission);

}

Implementations of this interface would be able to answer the question–much like a java.security.Policy–"Is the supplied Permission granted, excluded, etc. in the context of the supplied ProtectionDomain?"

Picture, now, a whole chain of these returning various PermissionEvaluations for the same Permission and ProtectionDomain parameters.?? Now something will need to exist to combine the results and render a final boolean decision:

public interface PermissionEvaluationCombiner {

?? public boolean isAuthoritative(final ProtectionDomain protectionDomain, final Permission permission, final PermissionEvaluation evaluation);

?? public boolean combine(final ProtectionDomain protectionDomain, final Permission permission, final PermissionEvaluation… evaluations);

}

That would handle the true-or-false authorization questions and would help put together the building blocks of a composable delegating Policy-based authorization framework.?? Next up: handling the java.security.Policy#getPermissions(ProtectionDomain) method.

Policy delegation and combining

(See my previous post for a broad-brush, ruthless condensation of the JACC specification.)One thing I found while going through the specification and writing a JACC implementation is that most of the effort involved has to do with Policy delegatio…

(See my previous post for a broad-brush, ruthless condensation of the JACC specification.)

One thing I found while going through the specification and writing a JACC implementation is that most of the effort involved has to do with Policy delegation.?? I've run into this in the past, too, in a non-JACC scenario.?? Briefly: in any non-trivial authorization system, you're going to ultimately have to combine the results from various Policy implementations in some kind of chained delegation model.

As I said, I've had to write such a thing several times now which means it's time to abstract it out.?? :-)?? Watch this space for a general-purpose Policy delegation and combining framework.

JACC condensed

It’s incredibly hard to understand the JACC specification (at least for me). Here it is in pragmatic, condensed terms. Clever insight is courtesy of Ron Monzillo; fumbling incompetence is mine alone.You write a JACC implementation when you want to…

It’s incredibly hard to understand the JACC specification (at least for me). Here it is in pragmatic, condensed terms. Clever insight is courtesy of Ron Monzillo; fumbling incompetence is mine alone.

You write a JACC implementation when you want to use a third-party authorization system. There are other reasons, too. JACC expresses Java EE role-based security mechanisms in terms of java.security.Policy and provides the means to carve the authorization rulebase up into subsets that pertain to individual Java EE modules. It also provides the means to determine that a Permission is explicitly excluded (java.security.Policy can only indicate that it is not granted, which could be because it is excluded or simply not handled).

A JACC implementation typically consists of a Policy subclass, a PolicyConfiguration implementation, and a PolicyConfigurationFactory subclass. It’s possible to write just the last two and to have them puke out policy files that the regular old com.sun.security.provider.PolicyFile class installed in every JVM by default can parse, but usually you write all three if you have cause to write a JACC implementation at all.

You write a PolicyConfiguration implementation to set up and produce your rulebase for a given Java EE module. (JACC calls your rulebase a “policy context”.) By “rulebase”, I mean (usually) the Permissions, granted and excluded, that define your authorization rules. Your rulebase might be a collection of files, a HashMap, a table in a database, etc. etc. The main thing is that your rulebase needs to be accessible by your java.security.Policy subclass (or more correctly by whatever Policy is installed in the system, reachable from the static Policy#getPolicy() method).

You write a PolicyConfigurationFactory subclass to produce instances of your PolicyConfiguration.

Your Policy subclass will be used in some fashion by the JVM to evaluate all permission checks, not just by your Java EE module, so it needs to be able to check things like AWTPermissions, RuntimePermissions, SecurityPermissions and the like (i.e. things you don’t usually think of when you think about Java EE). Typically you’ll delegate some of these calls to the Policy that’s installed already.

(For some reason, JACC refers to your Policy subclass as a “policy provider”. Every time you see “policy provider”, think java.security.Policy instead.)

Your PolicyConfiguration class needs to be thread-safe. It has a very well-defined lifecycle, but the salient points are that it is initially in a state where it is set up (“open”), then it is locked down via its commit() method (“in service”) which has the extremely important side effect of conceptually producing the rulebase (“policy context”) that was just configured and making it available for consultation. Only after its rulebase (policy context) is so produced (placed in service) may your Policy subclass consult it.

Once your rulebase has been created and placed in service by virtue of your PolicyConfiguration‘s having been committed, your Policy subclass will use it to render authorization decisions. All security calls will eventually flow through the Policy#implies(ProtectionDomain, Permission) method. Your implementation of this method must consult your rulebase, but only the proper subset of your rulebase. Which subset? The one that is in effect for the current Java EE module that’s making the current authorization check.

To determine which subset of your rulebase to consider, your Policy subclass calls PolicyContext#getContextID() to obtain a key. This key identifies effectively which Java EE module is making the security call, and hence which subset of your rulebase your Policy implementation needs to check during its implies(ProtectionDomain, Permission) call.

So your Policy subclass, armed with this key, looks up the appropriate rulebase subset (the appropriate policy context). Typically this is either a HashMap lookup, or a consultation of a file on disk, or the execution of a particular kind of SELECT query with an appropriate WHERE clause.

If the key is null, then no special rulebase subset is in effect, and only what the JACC specification calls the “default policy context” is in effect. Basically this means that no Java EE module has made this authorization call and you must consult the JVM-wide Policy for your authorization decision. (The default policy context is always in effect; more on that later.)

If the key is not null, then the rulebase subset—the current policy context, in JACC-speak—is now responsible for answering the authorization question. It may exclude the Permission, in which case no matter what else happens the Permission must not be granted, or it may grant it (provided that the default policy context does not exclude it). Again: if for any reason a given permission is found to be excluded, then java.security.Policy#implies(ProtectionDomain, Permission) must return false.

The default policy context, however it is implemented, forms a part of every authorization decision. That means if somehow it is possible to determine that the default policy context excludes a given Permission (not possible with the regular old java.security.Policy class) then that Permission must be excluded and Policy#implies(ProtectionDomain, Permission) must return false.

Running JPA tests, part 2

(This is part 2. Have a look at part 1 before you continue, or this won’t make much sense.) Now it turns out that all of the JPA providers except Hibernate (this is going to sound familiar after a while) really really really really want you to enh…

(This is part 2.  Have a look at part 1 before you continue, or this won’t make much sense.)

Now it turns out that all of the JPA providers except Hibernate (this is going to sound familiar after a while) really really really really want you to enhance or instrument or weave your entity classes.

First we’ll cover what this is, and then mention the different ways you might go about it.  Then I’ll pick one particular way and show you how to do it.

JPA entities need to be enhanced to enable things like lazy loading and other JPA-provider-specific tests.  The JPA provider might, for example, need to know when a particular property of your entity has changed.  Unless the specification were to have mandated things like PropertyChangeListeners on all properties (which, thankfully, it didn’t), there isn’t any way for the provider to jump in and be notified when a given property changes.

Enter weaving or enhancement (I’ll call it weaving, following EclipseLink’s term).  Weaving is the process where–either at build time or runtime–the JPA provider gets into your classes, roots around, and transforms them using a bytecode processor like Javassist or CGLIB.  Effectively, the JPA provider rewrites some of your code in bytecode so that the end result is a class that can now magically inform the JPA provider when certain things happen to its properties.

Weaving can be done at build time, as I said, or at runtime.

Now, if you’re like most Java EE developers, the reason you’ve never had to deal with weaving is that the Java EE specification requires all JPA providers in a Java EE container to do weaving silently in the background during deployment (if it hasn’t been done already).  So in a JPA 2.0 container like Glassfish or the innards of JBoss, weaving happens automatically when your persistence unit is discovered and deployed.

But the specification does not mandate that such automatic weaving take place when you’re not in a Java EE container.  And if you’re a good unit testing citizen, you want to make sure that your unit test has absolutely no extra layers or dependencies in it other than what it absolutely requires.

So in unit test land, you have to set this up (unless you want to drag in the testing machinery yourself, which is, of course, a viable option, but here we’re focusing on keeping the number of layers to a minimum).

When you go to set up weaving, you have to choose whether you want to do it at build time or at runtime.  I’ve chosen in all three cases to focus on build time weaving.  This has some happy side effects: if you do build-time weaving correctly, then not only do you get faster, more accurate unit tests, but if you perform that weaving in the right place then you can have Maven also deploy JPA-provider-specific versions of your entity classes for you automatically.  That, in turn, means you can install those jar files in your Java EE container and skip the dynamic weaving that it would otherwise have to perform, thus shortening startup time.

Now, all three JPA providers approach build time weaving in a different way (of course).  All three providers provide Ant tasks, but EclipseLink and OpenJPA also provide command line tools.  So we’ll make use of them where we can to avoid the Ant overhead wherever possible.

Regardless of which provider we’re talking about, weaving at build time involves the same necessary inputs:

  • A persistence.xml file somewhere.  This usually lists the classes to be weaved, as well as provider specific properties.  It isn’t (for this purpose) used to connect to any database.
  • The raw classes to be weaved.

Now, wait a minute.  If weaving alters the bytecode of your classes, then what happens if you try to use a Hibernate-weaved class in an EclipseLink persistence unit?

Things blow up, that’s what.

This is where things get regrettably quite complicated.

Before we start weaving, we’re going to need to set up areas for each persistence provider where the weaving may take place.  To set these up, we’re going to step in after compilation and copy the output of plain compilation to each provider’s area.

In Maven speak, anytime you hear the word “copy” you should be thinking about the maven-resources-plugin.  We’re going to have to add that to our pom.xml and configure it to take the classes that result from compiling and copy them to an area for EclipseLink, an area for Hibernate and an area for OpenJPA.

Here is the XML involved for the EclipseLink copy.  This goes in the <plugins> stanza as per usual:

<plugins>
  <plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <executions>
      <execution>
        <id>Copy contents of build.outputDirectory to EclipseLink area</id>
        <goals>
          <goal>copy-resources</goal>
        </goals>
        <phase>process-classes</phase>
        <configuration>
          <resources>
            <resource>
              <filtering>false</filtering>
              <directory>${project.build.outputDirectory}</directory>
            </resource>
          </resources>
          <outputDirectory>${project.build.directory}/eclipselink/classes</outputDirectory>
          <overwrite>true</overwrite>
        </configuration>
      </execution>
      <!– and so on –>
    </executions>
  </plugin>
</plugins>

So during the process-classes phase–which happens after compilation has taken place–we copy everything in ${project.build.outputDirectory}, without filtering, to ${project.build.directory}/eclipselink/classes.  Most commonly, this means copying the directory tree target/classes to the directory tree target/eclipselink/classes.  This area will hold EclipseLink-woven classes that we can later–if we choose–pack up into its own jar file and distribute (with an appropriate classifier).

We’ll repeat this later for the other providers, but for now let’s just stick with EclipseLink.

Before we get to the actual weaving, however, there’s (already) a problem.  Most of the time in any reasonably large project your JPA entities are split up across .jar files.  So it’s all fine and good to talk about weaving entities in a given project, but what about other entities that might get pulled in?  What happens when weaving only happens on some classes and not others?  Unpredictable things, that’s what, so we have to make sure that at unit test time all our entities that are involved in the test–whether they come from the current project or are referred to in other .jar files–somehow get weaved.  This gets tricky when you’re talking about .jar files–how do you weave something in a .jar file without affecting the .jar file?

The answer is you don’t.  You have Maven unpack all your (relevant) dependencies for you, then move the component classes into an area where they, too, can be weaved, just like the entity classes from the current project.  Let’s look at how we’ll set those pom.xml fragments up.  You want to be careful here that these dependencies are only woven for the purposes of unit testing.

The first thing is to make use of the maven-dependency-plugin, which, conveniently enough, features the unpack-dependencies goal.  We’ll configure this to unpack dependencies into ${project.build.directory}/dependency (its default output location):

<plugins>
  <plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.2</version>
    <executions>
      <execution>
        <id>Unpack all dependencies so that weaving, instrumentation and enhancement may run on them prior to testing</id>
        <phase>generate-test-resources</phase>
        <goals>
          <goal>unpack-dependencies</goal>
        </goals>
        <configuration>
          <includeGroupIds>com.someotherpackage,${project.groupId}</includeGroupIds>
          <includes>**/*.class</includes>             
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>

Here you can see we specify which “group ids” get pulled in–this is just a means of filtering the dependency list.  You can of course alter this any way you see fit.  You’re trying to pull in any JPA entities that are going to be involved in your tests and make sure they get woven, so choose your group ids accordingly, and see the unpack-dependencies documentation for more tweaking you can do here.

So if you were to run mvn clean generate-test-resources at this point, the following things would happen:

  • Your regular classes would get compiled into target/classes.
  • Your regular resources would get copied into target/classes.
  • The entire contents of that directory would then get copied into target/eclipselink/classes.
  • Classes from certain of your dependencies would get extracted into target/dependency, ready for further copying.

Now we’ll copy the unpacked dependency classes into the test weaving area.  This little configuration stanza goes in our prior plugin declaration for the maven-resources-plugin:

<executions>
  <!– other executions –>
  <execution>
    <id>Copy dependencies into EclipseLink test area</id>
    <goals>
      <goal>copy-resources</goal>
    </goals>
    <phase>process-test-resources</phase>
    <configuration>
      <resources>
        <resource>
          <filtering>false</filtering>
          <directory>${project.build.directory}/dependency</directory>
        </resource>
      </resources>
      <outputDirectory>${project.build.directory}/eclipselink/test-classes</outputDirectory>
      <overwrite>true</overwrite>
    </configuration>
  </execution>
</executions>

This is so that the dependencies can be woven with everything else–remember that you’ve got to make sure that all the entities in your unit tests (whether they’re yours or come from another jar involved in the unit test)–are woven.

We have two more bits of copying to do to get our classes all in the right place.  Fortunately they can be combined into the same plugin execution.

The first bit is that we have to take the classes that will have been woven in target/eclipselink/classes and copy them unmolested into the test area so that they can reside there with all the unpacked dependency classes.  This is to preserve classpath semantics.  That is, we’ve already laid down the dependencies inside target/eclipselink/test-classes, so now we need to overlay them with our woven entity classes (obviously once they’ve already been woven) to make sure that in the event of any naming collisions the same semantics apply as would apply with a normal classpath in a normal environment.  At the end of this we’ll have a target/eclipselink/classes directory full of our entity classes that are waiting to be woven, and a target/eclipselink/test-classes directory that will ultimately contain our woven classes as well as those from our dependencies.

The second bit is that since sometimes unit tests define their own entities, we have to make sure that the regular old target/test-classes directory gets copied into the EclipseLink test weaving area as well, and, moreover, we have to make sure this happens last so that any test entities “shadow” any “real” entities with the same name.

As I mentioned, we can accomplish both of these goals with one more execution in maven-resources-plugin:

<execution>
  <id>Copy contents of testOutputDirectory and contents of EclipseLink area to EclipseLink test area</id>
  <phase>process-test-classes</phase>
  <goals>
    <goal>copy-resources</goal>
  </goals
>

  <configuration>
    <resources>
      <resource>
        <filtering>false</filtering>
        <directory>${project.build.directory}/eclipselink/classes</directory>
      </resource>
      <resource>
        <filtering>false</filtering>
        <directory>${project.build.testOutputDirectory}</directory>
      </resource>
    </resources>
    <outputDirectory>${project.build.directory}/eclipselink/test-classes</outputDirectory>
    <overwrite>true</overwrite>
  </configuration>
</execution>

Finally, you’ll recall that I said that there are two inputs needed for weaving:

  1. A persistence.xml file somewhere
  2. The raw classes to be woven

We’ve abused the maven-dependency-plugin and the maven-resources-plugin to get (2).  Now let’s look at (1).

The persistence.xml file that is needed by the EclipseLink weaver is really just used for its <class> elements and its <property> elements.  Pretty much everything else is ignored.  This makes a certain amount of sense: EclipseLink will use it as the definitive source for what classes need to be woven if you don’t tell it anything else, and a particular property (eclipselink.weaving) will instruct EclipseLink that indeed, weaving is to be done and is to be done at build time.

So we’ll put one of these together, and store it in src/eclipselink/resources/META-INF/persistence.xml:

<?xml version=”1.0″ encoding=”UTF-8″?>
<persistence version=”2.0″ xmlns=”http://java.sun.com/xml/ns/persistence” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd“>
  <persistence-unit name=”instrumentation” transaction-type=”RESOURCE_LOCAL”>
    <class>com.foobar.SomeClass1</class>
    <class>com.foobar.SomeClass2</class>
    <class>com.foobar.SomeClassFromSomeDependency</class>
    <properties>
      <property name=”eclipselink.weaving” value=”static” />
    </properties>
  </persistence-unit>
</persistence>

…and, back in our monstrous maven-resources-plugin stanza, we’ll arrange to have it copied:

<execution>
  <id>Copy EclipseLink persistence.xml used to set up static weaving</id>
  <goals>
    <goal>copy-resources</goal>
  </goals>
  <phase>process-classes</phase>
  <configuration>
    <outputDirectory>${project.build.directory}/eclipselink/META-INF</outputDirectory>
    <overwrite>true</overwrite>
    <resources>
      <resource>
        <filtering>true</filtering>
        <directory>src/eclipselink/resources/META-INF</directory>
      </resource>
    </resources>
  </configuration>
</execution>

It’s finally time to configure the weaving.  For EclipseLink, we’ll use the exec-maven-plugin, and we’ll go ahead and run the StaticWeave class in the same Maven process.  We will run it so that it operates in-place on all the classes in the EclipseLink test area.

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <configuration>
    <includePluginDependencies>true</includePluginDependencies>
    <includeProjectDependencies>true</includeProjectDependencies>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>org.eclipse.persistence.jpa</artifactId>
      <version>2.2.0</version>
    </dependency>
  </dependencies>
  <executions>
    <execution>
      <id>Statically weave this project’s entities for EclipseLink</id>
      <phase>process-classes</phase>
      <goals>
        <goal>java</goal>
      </goals>
      <configuration>
        <arguments>
          <argument>-persistenceinfo</argument>
          <argument>${project.build.directory}/eclipselink</argument>
          <argument>${project.build.directory}/eclipselink/classes</argument>
          <argument>${project.build.directory}/eclipselink/classes</argument>
        </arguments>
        <classpathScope>compile</classpathScope>
        <mainClass>org.eclipse.persistence.tools.weaving.jpa.StaticWeave</mainClass>
      </configuration>
    </execution>
    <!– there will be other executions –>
  </executions>
</plugin>


This stanza simply runs the StaticWeave class, supplies it with (effectively) -persistenceinfo target/eclipselink as its first effective argument, and then tells it to work in place on the target/eclipselink/classes directory.

In part 3, we’ll put all of this together.