Sunday, July 18, 2010

Eclipse Helios - New Apply Patch Features

Eclipse Helios has a few nice new features for applying patches. In this post I would like to point some of the out

Apply Patch using URL

The Apply Patch wizard now accepts URLs. This is great when you a working with open source projects where patches are frequently added as attachment to bug reports. Previousely, I had to download the patch, find it again (which is difficult when all patches are named patch, and therefore end up being downloaded as patch, patch (1), patch (2), ... ), an then apply. Now I just click on "copy link" and it is automagically pasted into the apply-patch box. Nice one!

Apply Patch in Synchronize View

Even nicer is applying patches in synchronize view - the option is, however, hidden:

  • Switch to the synchronized perspective
  • In the synchronize view, click on the arrow next to the synchronize icon (the first one from the left
  • Select synchronize...

Now you can finally partially apply patches! What makes this feature even better is that it also accepts URLs, so it can be directly used with patches attached to bug reports!

And to bring this all together, there is now the

Apply patch in Synchronize view preference

Hidden in the preferences under "Team", you can check "Apply patch in Synchronize view" to always get this behavior. Now this is one of the most useful settings - unfortunately it is off by default.

Saturday, July 17, 2010

Eclipse Helios and Java 1.6u21 deadlocks

I wanted to write a post about the new Eclipse Helios, which was just released to participate in the Helios Blogathon. So, on my personal machine, I installed the newest JDK (1.6u21), the new eclipse, started it up, tried to work with it and after a few seconds.... It just hangs!

But whait - it worked nicely on my work machine, so what's the deal? Did I install the wrong plug-ins? Tried to open up the wrong editor? I had the same problem on my work machine (Windows 7 x64 with the newest Java 64 bit (1.6u21)). On this machine I fixed it using the 32 bit Java version instead (which just happend to be 1.6u20).

After spending several hours with several 32 and 64 bit versions of Eclipse and Java, I found the deadly combination. It is:

  • Windows 7 x64 (may be unrelated to the problem)
  • Java 1.6 u 21
  • Eclipse Helios

The fix? Get an older Java Version - which is not simple - if you try to get an older version of Java, Oracle asks you to register and wants your email address. They don't tell you that there is a public archive of older Java versions. Why should they? You always want the latest version, right? Even if this means your Eclipse Helios session is limited to 5 seconds.

Helios now runs fine on an Jdk 1.5, with a separate JDK 1.6 installed to actually run my apps.


Update: 11 days after my post Slashdot has some more information: Oracles Java Company Change Breaks Eclipse. Also, there is Bug 6969236.


Thursday, April 1, 2010

DataSource in Jetty through JNDI

Prerequesite: Please ensure JNDI is configured properly and you can pass parameters to Jetty via JNDI.

First, you need to add the used libraries to Jettys classpath. In my case, I wanted commons-dbcp (alternative: c3p0) over an H2 database, so I added the following to my pom.xml


      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>7.0.1.v20091125</version>
        <dependencies>
          <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
          </dependency>
          <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.2.131</version>
          </dependency>
        </dependencies>
      </plugin>

On Jetty standalone, I copied the libraries to the lib/ext directory and added ext to the options in start.ini. Please note that commons-dbcp also requires commons-pool.

Next, add the configuration of your DataSource to jetty-env.xml:


<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="thisfile" class="org.eclipse.jetty.webapp.WebAppContext">
  <New class="org.eclipse.jetty.plus.jndi.Resource">
    <Arg><Ref id="thisfile"/></Arg>
    <Arg>jdbc/nameOfMyDatabase</Arg>
    <Arg>
      <New class="org.apache.commons.dbcp.BasicDataSource">
        <Set name="url">jdbc:h2:/path/to/your/DataBase</Set>
      </New>
    </Arg>
  </New>
</Configure>

To actually have access to the datasource, you also need modify web.xml to declare that you want a resource unter this name:


  <resource-ref>
    <res-ref-name>jdbc/nameOfMyDatabase</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

The database is now available as DataSource at java:/comp/env/jdbc/nameOfMyDatabase and can be used directly in tools such as hibernate by setting hibernate.connection.datasource to this value.

Background: Hibernate did not properly release the database connection when the WebApp shut down. This resulted in Exceptions when trying to undeploy and deploy the webapp without killing Jetty, as the embedded database existed both in the old and the new context. By moving the connection out of the WebApp, and into Jetty's responsibility, the embedded database driver now only exists in Jetty's context. Adding the connection pool is just decoration.

Passing parameters to Jetty 7 via JNDI

If you have the jetty-maven-plugin properly configured in the pom.xml, then everything is already set up.

For Jetty Standalone, please see my other post about configuring JNDI in jetty standalone.

Passing parameters through JNDI proved to be very simple. In src/main/webapp/WEB-INF create a file jetty-env.xml, with the following contents:


<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="thisfile" class="org.eclipse.jetty.webapp.WebAppContext">
  <New class="org.eclipse.jetty.plus.jndi.EnvEntry">
    <Arg><Ref id="thisfile"/></Arg>
    <Arg>paramname</Arg>
    <Arg type="java.lang.String">A sample parameter value</Arg>
    <Arg type="boolean">false</Arg>
  </New>
</Configure>

You can then load your parameter through the standard naming context:


import javax.naming.Context;
import javax.naming.InitialContext;
...
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
String param = (String) envCtx.lookup("paramname");

Of course, you can add other parameters, rename paramname to something that makes more sense, or use other data types. Please note: Jetty supports more datatypes than required by the J2EE standard.

Configuring Jetty 7 standalone for JNDI

Configuring Jetty 7 for JNDI can be a bit tricky. If you miss any of these points, you may end up passing JNDI parameters, but they will not be available in your webapp.

  1. Ensure the plus libraries are loaded. You can to this by adding the option plus in Jetty's start.ini
  2. Ensure jetty is configured to use the plus configuration classes. You can do this by adding the following inside the context, or the jetty-env.xml:
      <Set name="ConfigurationClasses">
        <Array id="plusConfig" type="java.lang.String">
          <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
          <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
          <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
          <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
          <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
          <Item>org.eclipse.jetty.plus.webapp.Configuration</Item>
          <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
          <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item>
        </Array>
      </Set>
    

    The documentation suggests adding etc/jetty-plus.xml to the startup, which would make this configuration available as plusConfig to refer to. This did not work on my machine.

You can now continue with Passing parameters to Jetty 7 via JNDI.

Wednesday, February 10, 2010

Jetty 7 maven plugin authentication realms

The configuration directive UserRealm seems to no longer work with the jetty 7 maven plugin (jetty-maven-plugin). I received the following error:

java.lang.IllegalStateException: No LoginService for org.eclipse.jetty.security.authentication.BasicAuthenticator@4095c5ec in ConstraintSecurityHandler@28f52a14@

Fixing this involved:

  • Creating a jetty configuration file, such as the following:


    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
    <Configure class="org.eclipse.jetty.webapp.WebAppContext">
      <Get name="securityHandler">
        <Set name="loginService">
          <New class="org.eclipse.jetty.security.HashLoginService">
            <Set name="name">YourSecurityRealmHere</Set>
            <Set name="config">src/test/resources/jetty-realm.properties</Set>
            <Call name="start"/>
          </New>
        </Set>
        <Set name="checkWelcomeFiles">true</Set>
      </Get>
    </Configure>

    To be saved as src/test/resources/jetty-test.xml

  • Create a src/test/resources/jetty-realm.properties with your Jetty 7 password file.

  • Updating the jetty configuration in my pom.xml:

          <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>7.0.1.v20091125</version>
            <configuration>
              <webAppXml>src/test/resources/jetty-test.xml</webAppXml>
            </configuration>
            <dependencies>
              <dependency>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-servlets</artifactId>
                <version>7.0.1.v20091125</version>
              </dependency>
            </dependencies>
          </plugin>
    

    The important entry is webAppXML. The extra dependency to jetty-servlets was added to support GZip in Jetty 7.

Jetty seems to ignore webdefault.xml

If just tried to edit webdefaults.xml to disable directory views, and the change was not reflected in my webapp. The reason: webdefaults.xml is not read by default, but must be explicitly added to the context of the webapp:


 <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>

And suddenly all changes in webdefaults.xml are applied.

Home

Blog

Followers