DigitalJoel

2012/11/23

Eclipselink static weaving

Filed under: development, eclipse, java — Tags: , , — digitaljoel @ 11:26 pm

I’m playing with a new project and decided to get eclipselink static weaving working in this one. I started on the official eclipselink project documentation on the subject. That’s nice and all, but it doesn’t say anything about getting the weaving to work with maven or eclipse. I really wanted both. Here’s what I did.

First, in persistence.xml you should add the following property:

    <properties>
      <property name="eclipselink.weaving" value="static" />
    </properties>

My maven project has several modules. domain-api contains the entity definitions. domain-impl contains the code for interacting with the database. That means that my persistence.xml is contained in domain-impl and the @Entity classes are in domain-api. That’s alright. To get this all working I decided to use the command line option rather than use the ant task.

The weaving needs to take place on the entities, so the weaving step is placed in the domain-api pom.xml. Within build/plugins I added this plugin.

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.2.1</version>
        <executions>
          <execution>
            <id>weave-classes</id>
            <phase>process-classes</phase>
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <mainClass>org.eclipse.persistence.tools.weaving.jpa.StaticWeave</mainClass>
          <commandlineArgs>-classpath %classpath -loglevel FINE -persistenceinfo ${basedir}/../domain-impl/src/main/resources ${basedir}/target/classes ${basedir}/target/classes</commandlineArgs>
        </configuration>
      </plugin>

That’ll run the java program to weave the class files in place. Note that my -persistenceinfo argument points to ../domain-impl/src/main/resources. That’s because the StaticWeave class will look for META-INF/persistence.xml within that directory, and my persistence.xml is contained in the domain-impl module, not within domain-api. If you are using maven resource filtering on your persistence.xml this will cause a problem since domain-impl builds after domain-api. That’s not a problem in my case so I’m going to be lazy and not address it.

Once you have that in your pom you should be able to do a mvn clean install and see output something like:

[INFO] --- exec-maven-plugin:1.2.1:java (weave-classes) @ domain-api ---
[EL Config]: metadata: 2012-11-23 23:15:42.798--ServerSession(1166215941)--Thread(Thread[org.eclipse.persistence.tools.weaving.jpa.StaticWeave.main(),5,
org.eclipse.persistence.tools.weaving.jpa.StaticWeave])--
The access type for the persistent class [class com.xyg.model.JoelTest] is set to [FIELD].

I added line breaks for formatting. Anyway, that kind of output means things are working.

Sadly, Eclipse’s maven integration isn’t smart enough to figure this part of the pom out. If we tell Eclipse to ignore this part of the build then the classes won’t get weaved and it’s likely that if you try to run the project from within eclipse it’s not going to work properly. Fortunately, we can work around this.

Within the same pom (in my case, in domain-api) you can add another plugin. This plugin is NOT within the plugins element, but is within a pluginManagement element. You can get eclipse to generate the entry for you by telling it to ignore the execution when it tells you it has an error because it has no lifecycle mapping for the given execution. When you do that it’ll generate an xml block in your pom.xml that will look like this:

    <pluginManagement>
      <plugins>
        <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
        <plugin>
          <groupId>org.eclipse.m2e</groupId>
          <artifactId>lifecycle-mapping</artifactId>
          <version>1.0.0</version>
          <configuration>
            <lifecycleMappingMetadata>
              <pluginExecutions>
                <pluginExecution>
                  <pluginExecutionFilter>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <versionRange>[1.2.1,)</versionRange>
                    <goals>
                      <goal>java</goal>
                    </goals>
                  </pluginExecutionFilter>
                  <action>
                    <execute/>
                  </action>
                </pluginExecution>
              </pluginExecutions>
            </lifecycleMappingMetadata>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>

The version eclipse generates will say something like <ignore></ignore> in the action section of this configuration. If you simply change that to <execute/> then eclipse will execute it. It will execute it every time, even on incremental builds, so hopefully it isn’t too intrusive. I’m just getting started on this project so I don’t have many entity classes yet, but if there’s an issue I’ll get back and update this post.

With this configuration I’m able to execute my integration tests from the command line and I’m also able to run the tests and launch the webapp from within eclipse, and I don’t incur the runtime penalty of dynamic weaving.

Advertisements

2009/11/16

How to remove cruft from Open Resource in Eclipse

Filed under: eclipse, java, maven — Tags: , — digitaljoel @ 1:07 pm

I got really tired of seeing my maven target directory and .svn directory entries show up in the ctrl+shift+R (open resource) dialog in Eclipse. Here’s what I did to remove them.

For .svn directories, I simply shared the project through subversive. I suspect doing the same with subclipse will work. Once eclipse knows that it is in version control, it removes the .svn directories from the Open Resource dialog.

For the maven target directory, I marked the directory as Derived. To do this, simply open the properties for the directory by pressing alt+enter or right clicking and selecting properties. Then, select the “Derived” property.

Set Directory to Derived

Derived Setting

Finally, you can remove the target directory from your Package Explorer using filtering. Simply select the little down arrow menu in the package explorer, then “filters”, and in the Name filter patterns, type “target”. Note that this will remove target from the Package Explorer, so if you want to mark it as Derived, you will need to do so before removing it from the Package Explorer.

Filtering in Package Explorer

2009/09/11

Recovering a lost file in Eclipse

Filed under: eclipse — Tags: — digitaljoel @ 8:46 pm

The other day I was working on my project. I had cygwin open and copied a file to another so I could use it as a template. Unfortunately, I typed the wrong name and overwrote an existing file that I had local modifications in. Because of the local modifications, couldn’t just get it back from source control. So, how could I the contents of the file back?

Since the file was in eclipse, I refreshed the project, then right clicked on the file. Select “Compare To” and “Local History”. I selected a time previous to when I had copied the file over my existing file. The previous revision is on the right side of the comparison, and my new, incorrect stuff is on the left. I was then able to select all on the right and copy it into where it ought to be.

Since that time I have learned that you can right click the file in the Package Explorer, select Replace With, and Local History or Previous from Local History and you can select a previous version and replace the file rather than having to select the contents and paste.

This also works if you delete a file, even if you delete it within eclipse. Simply create a new file of the same name, refresh the project to get the new file, and compare to local history.

2009/06/03

Maven, Eclipse, Glassfish, and a Webapp

Filed under: eclipse, glassfish, maven — digitaljoel @ 4:13 pm

Update: As of Eclipse Juno, the m2e plugin is much more reasonable and usable. I would suggest using m2e and m2e-wtp rather than following the instructions below.

Original Post:

At work we are using Maven and Glassfish for our webapp build and hosting. I have been using Eclipse since the 2.0 days and wanted to continue to use Eclipse. As I’ve said before, I’ve not had a lot of luck with the Maven plugins for eclipse. Since my project was created with the maven eclipse:eclipse plugin, it’s not marked in eclipse as a web project, so I can’t just hit run and have it go. I finally have my project setup in a way that I feel is the most productive. This is how I did it.

After running

mvn eclipse:eclipse

Import the project into eclipse. Now we will modify some of the properties of the project so we can build and deploy without restarting eclipse and without having to hit the command line.

  1. First open up the project properties.  In the Java Build Path in the Source tab, change the Default Output Folder: to /target/mavenartifact-version/WEB-INF/classes.  This will cause eclipse to build the classes into the webapp classes directory directly whenever it builds.  The drawback of this approach is that whenever the version changes, you will have to come and reconfigure this value again.  While you are working, if you find that your java changes are being reflected in the webapp when you test, you will want to check this value first.
  2. Next, we need to configure Glassfish to point to your directory deployed webapp.  This step assumes you have previously built your webapp module using maven and the target directory exists.  In the glassfish admin ui, under Web Applications deploy a webapp of type Web Application (.war) with a Location of Local packaged file or directory that is accessible from the Application Server.  The browse to your /target/- directory using the Browse Folders button.  Set the other properties appropriately, and ensure that it is deployed to the correct Virtual Server and hit OK.  Again, when the project or module version changes maven will build the war into a new directory and you will need to change the directory that glassfish is pointing at.  You can do this in /domains/domain1/config/domain.xml.  In that file, you will search for the web-module that you just deployed, and change the location attribute to match your new version.
  3. Now you should be able to start glassfish and view your webapp.  Changes made to (x)html, jsp, etc. files in the target directory should take effect immediately in glassfish, but we don’t want to be working in there all the time, so the next step is to setup a couple of custom builders in Eclipse to push changes to the target directory when we build.  To do this, go into the project properties again and select the Builders item.  You will add two builders, one to repackage everything when you touch an (x)html or jsp file, and another to tell glassfish to reload the webapp when you touch a java file.
    • First we will create the builder to repackage everything.  This will be a new builder that should come immediately AFTER the default Java Builder.  The Location of the builder should be your maven executable.  On my windows box, this is mvn.bat.  The Working Directory for the builder should be ${workspace_loc:/your-project-name} using your project name in place of your-project-name.  The Arguments: should be -o war:exploded which will tell maven to copy everything over to the target directory, but not necessarily create the .war file.  In the Build Options tab, you should specify that builder run During manual builds and then you will want to Specify a working set of relevant resources.  I’ve talked about the working set in a previous post.  The set you are going to want for this builder is /src/main/webapp. This will make sure that this custom builder only runs when the webapp resources change.
    • Next, we need to setup a custom builder to reload the webapp in glassfish when java resources change.  Glassfish has a nifty function where if you touch a .reload file within the webapp root directory, then glassfish will reload the webapp, including all libraries and classes. This way, you can basically redeploy your directory deployed webapp without having to restart the server or anything. To do this, you will create an empty /src/main/webapp/.reload file. With that location, it should be copied over to the webapp root the first time you run mvn clean install. Now, we need a custom builder that will modify the date on that file. Create a new custom builder, which should be AFTER your new maven builder. If you are on windows, you don’t have the ‘touch’ command. The Location for the new builder should be C:\windows\system32\cmd.exe and the working directory should be the root of your deployed webapp, i.e. ${workspace_loc:/your-project-name/target/your-project-name-version}. The Arguments should be /c echo reload > .reload. This will write a new .reload file. Make sure you set the working set to src/main/java. Again, since we have the version in the working directory for this builder, it’s ANOTHER place you’ll have to update it when your module changes versions. If anyone has a better workaround for this, I would love to hear it.

With those steps done, you should be able to make changes to (x)html, jsp, or java files, hit ctrl+b to build your webapp, and have the changes reflected in your deployed webapp within a few seconds. For larger webapps, the mvn war exploded command may take a few more seconds, but it’s still faster than going to the command line, and safer than working directly within the target directory.

2008/12/22

Starting and stopping glassfish within eclipse

Filed under: eclipse, glassfish, java, maven — digitaljoel @ 4:49 pm
While working in my webapp, I often need to re-deploy. Here’s the setup:
  • Using Maven for full builds of the webapp. See my previous post about web resources within eclipse
  • Glassfish is installed in some directory, and is totally independent of eclipse.*
  • Glassfish has a webapp setup that points to the exploded webapp directory within its maven build target directory.**
  • Eclipse builds its classes into the target/classes directory***. This can save time in my maven build because it’ll notice that it doesn’t have to build classes because they are built by eclipse as I go.
  • I have a program builder on my project that runs “mvn -o package” on my project. It takes care of copying all web resources and all classes from target into the exploded webapp. This builder runs when I do a manual build of the project through the menus or with ctrl-b
Of course, in webapp development, when I modify the java files and compile them, in order to see the changes within my webapp while testing, I have to bounce the webserver. I did have limited success with Netbeans performing a hot-swap of code within glassfish, but that’s another story for another day.
So, the goal was to make glassfish stop and start whenever I modified java files. In order to do this, I did a trick similar to my previous blog post on filtering web resources and deploying them to the webserver. It was actually quite simple. I created two new builders, one which runs before the eclipse java builder, and one that runs at the very end.
In order to swap out jars or classes, I have to stop the webserver so it releases its handles on the files. This is done with the first builder.
The builder simply calls the glassfish asadmin.bat file, passing in arguments to stop the server. In the build options tab you will want to ensure that the “Launch in Background” is unchecked. We need this to run in-process so that the build will wait for it. If you put it in the background, your build may fail if shutdown takes a long time because the server will still have a handle on files the build is trying to delete.
We don’t want to shut down glassfish every time we build, only when java files change. To accomplish this, we will use the working set, like we did in the previous post. This time, you will set it to src/main/java
Next, we need to start the server again after our build is complete. This is almost identical to the first builder we just created. This one will go at the end of the build cycle, but will also call asadmin.bat. The argument is start-domain domain1. This builder SHOULD be launched in the background, otherwise your build will never end. Here is the Build Options tab of that dialog:
Notice that again we are specifying the working set for this builder so that we only try to start the server when java files change. The working set should be src/main/java as with the previous one.
So finally, we have a full build operation that looks like this:
Now, while developing my webapp, if I have only changed .xhtml files and I hit ctrl-b, the server isn’t bounced at all. My web resources are copied out to the webapp directory and changes are seen immediately. If I change java files and hit ctrl-b, the classes are recompiled and the server is shutdown and restarted. I can easily alt-tab to my browser and test my changes either way.
One drawback is that when the version changes, I have to change the deployed directory within the domain.xml file to point to the new target directory. This isn’t a big deal, as it’s simply changing the webapp descriptor from blahblahblah-1.3-SNAPSHOT to blahblahblah-1.4-SNAPSHOT within domain.xml and restarting the server.
All in all, this setup has served me very well for the last few months.
NOTES:
* I couldn’t just setup glassfish as a server within eclipse because the project is not setup as a dynamic web project within eclipse, and I can’t apply that template or property aspect or whatever it’s called after the fact.
** The web-module node within my domain.xml file looks like this:
<web-module root=”myurl” deployed=”true” enabled=”false” location=”c:/src/project/module/target/module-1.5-SNAPSHOT” name=”module” type=”user”/>
***Why didn’t I just build into target/my-web-app/WEB-INF/classes? If I had eclipse build into that directory, they would be wiped out whenever I ran a mvn clean operation, and replaced with newly compiled files from the target/classes directory. I’m not certain, but it may also happen with the mvn package command that my build is running from within eclipse. In any case, I haven’t tried it. If you try it and have good luck with it, let me know.

2008/11/09

Eclipse and Maven filtering

Filed under: eclipse, filtering, glassfish, maven — digitaljoel @ 1:23 am

I’m working on a web application and using Maven filtering for various properties within some of my web pages and application descriptors. I have my web server pointed to my maven target directory for the deployed webapp. This allows me to build and have my changes immediately available in the webserver. If my changes are in the xhtml files only then there is no need to re-deploy the application or bounce the web server. I can simply refresh my browser and see the changes. This makes for a nice development cycle when editing xhtml files.

The difficulty arises when you bring in the maven filtering.

Netbeans has much better Maven integration than Eclipse. It was also much easier for me to take my existing web application and simply ‘run’ it on the webserver. Unfortunately, when building in netbeans, it would simply copy the resources over to the target directory. For me, this meant death of the page because of the un-filtered properties in the pages.

I’ve been an Eclipse user since 2.x, and am much more comfortable in it. Since I’m not using any maven plugin for Eclipse ( haven’t found one that is worth the effort yet ) I use the Eclipse Java builder to build my java classes directly to my target/classes directory. Now to get the xhtml, properties, xml, etc. files over to where they belong with the appropriate filtering.

My answer was to configure a new builder. In Project Properties, select Builders, then create a new Program builder, with the executable being your mvn executable.

For the working directory, set it to your project directory using the Browse Workspace button. In the Arguments section, put the goals for your maven build. I chose package because it’ll get all the xml, properties, xhtml files, filter them, and copy them to the target directory, which is where my webserver is pointing for its webapp.

The magic is to specify the working set for the builder. Setting it to the src/main/webapp folder of your maven project ( the screenshot isn’t quite correct since it is on a non-maven project, but you get the idea ) means that the builder will only run when a file within that directory is modified.

Using the working set, I’m able to only run the maven target when working on my xhtml files. When I’m doing pure java work, updating the web only files does me no good and is a waste of time.

Now I’m able to work on my xhtml files, press ctrl-b to build, and refresh the browser I’m using for testing to see the changes. Quick turn-around, and no reason to hit the command line to manually run my maven command.

Maybe next time I’ll talk about starting and stopping my glassfish server automatically so I can see my java changes as well.

For information on filtering resources with maven, you can check out
http://maven.apache.org/guides/getting-started/index.html#How_do_I_filter_resource_files

Blog at WordPress.com.