maven-release-plugin and git fix

Thursday, May 2, 2013 11:57:34 PM

After hours of trying and wondering why my release scripts suddenly stopped working, I found out that maven-release-plugin seems to have an issue with git on recent systems. If you invoke mvn release:prepare and find out that the release process just runs against the current SNAPSHOT instead of the release version, you likely stumbled upon bug MRELEASE-812.

The reason for this issue seems to be that mvn release:prepare parses the output of git status. However the status is localized in recent versions of git, and maven-release-plugin fails to parse the localized output.

The coming fix will probably use git status --porcelain, which returns a machine-readable output. However, for the time being

LANG='en_US.UTF-8'
mvn release:prepare

is a valid workaround.

Written by Shred in Softwaretechnikno comments

Tags: English, git, maven

hibernate3-maven-plugin fails with Java 1.7

Tuesday, January 24, 2012 12:05:32 AM

If you’re using Maven’s hibernate3-maven-plugin for creating a DDL file from your entities, you might encounter the following error when using Java 1.7:

Execution default of goal org.codehaus.mojo:hibernate3-maven-plugin:2.2:hbm2ddl failed:
An AnnotationConfiguration instance is required 

The reason seems to be a broken JRE detection in the Mojo code, which mistakenly assumes that Java 1.7 does not support annotations. However, I haven’t checked that in depth.

The fix is pretty easy. In the plugin configuration of the hibernate3-maven-plugin, add an implementation property to the componentProperties like this:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>hibernate3-maven-plugin</artifactId>
  <version>2.2</version>
  <configuration>
    <componentProperties>
      <implementation>annotationconfiguration</implementation>
    </componentProperties>
  </configuration>
</plugin>

This enforces the use of an AnnotationConfiguration instance.

Written by Shred in Java1 comment

Tags: English, Hibernate, Java 1.7, Maven

Setting a renderer on JComboBox

Thursday, September 1, 2011 12:34:38 AM

When setting a custom renderer to a JComboBox, the usual way is to extend a DefaultListCellRenderer and override the getListCellRendererComponent() method. However, this may lead to ugly comboboxes on some Look and Feels. As you can see on the top combobox, it is rendered considerably smaller and with the letters sticked to the left border, just by using a DefaultListCellRenderer. The Look and Feel seems to use a special renderer class for proper rendering, as it is shown in the combobox below.

A solution is to use a proxy ListCellRenderer instead, which only converts the value and then delegates the rendering to the original renderer. For example:

public class ListCellRendererProxy implements ListCellRenderer {
  private final ListCellRenderer delegate;

  public ListCellRendererProxy(ListCellRenderer delegate) {
    this.delegate = delegate;
  }
  
  @Override
  public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {
    // modify the value here...
    return delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
  }
}

The renderer proxy can be used like this:

JComboBox cbx = new JComboBox();
ListCellRenderer oldRenderer = cbx.getRenderer();
cbx.setRenderer(new ListCellRendererProxy(oldRenderer));

The combobox items are now converted to a string by a custom cell renderer, but are still rendered by the original renderer implementation of the current Look and Feel. However, while a single DefaultListCellRenderer instance can be shared with many JComboBox, a new renderer proxy needs to be instanciated per combobox.

Written by Shred in Javano comments

Tags: English, Swing

String LOBs on PostgreSQL with Hibernate 3.6

Thursday, February 24, 2011 12:35:05 AM

For String properties that may contain more than 255 characters, it is advised to add a @Lob annotation to the appropriate property. For example, to keep a comment text in an entity, one would write:

@Lob
public String getComment() { return comment; }
public void setComment(String comment) { this.comment = comment; }

On PostgreSQL, a large string is usually kept in a TEXT column (instead of VARCHAR). However, after updating to Hibernate 3.6, an exception was suddenly thrown when accessing such a property (along with an SQLState: 22003 from PostgreSQL):

org.postgresql.util.PSQLException: Bad value for type long : This is some text...
	at org.postgresql.jdbc2.AbstractJdbc2ResultSet.toLong(AbstractJdbc2ResultSet.java:2796)
	at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getLong(AbstractJdbc2ResultSet.java:2019)
	at org.postgresql.jdbc4.Jdbc4ResultSet.getClob(Jdbc4ResultSet.java:43)
	at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getClob(AbstractJdbc2ResultSet.java:384)
        ... and more

Obviously, the PostgreSQL connector tried to interprete the textual content as a long integer now, which – of course – results in a failure. PostgreSQL knows two ways of storing binary large objects, either as BYTEA within the table space, or as OID in a separate place and referenced by a numerical identifier. It seems that Hibernate 3.6 suddenly treats TEXT columns like OID columns as well.

In the internet, I have found similar problems related to @Lob annotated byte[] properties. A common solution was to add a @Type annotation to the property.

An attempt to add @Type(type = “org.hibernate.type.MaterializedClobType”) did not help at all. Instead, @Type(type = “org.hibernate.type.TextType”) did the trick:

@Lob
@Type(type = "org.hibernate.type.TextType")
public String getComment() { return comment; }
public void setComment(String comment) { this.comment = comment; }

For PostgreSQL, it now works fine again, even without needing to alter the table column type. However I couldn’t check the impact of the annotation on other DBMS (like Oracle). Your feedback is welcome.

Written by Shred in Java7 comments

Tags: English, Hibernate, PostgreSQL

JSF2.0, mod_proxy and CSS

Tuesday, November 23, 2010 1:59:13 AM

I stumbled upon a strange issue when I recently deployed a JSF 2.0 web application. The application was developed using Jetty, and was working fine there. However when I deployed the application on a server, the page layout was utterly broken and Firefox complained that it would not load some CSS resources because of the wrong content type application/xml+xhtml.

On the server, a Tomcat is connected to an Apache web server via mod_proxy and mod_proxy_ajp. I found out that the Tomcat itself delivered the CSS resources without a Content-Type header, but the Apache web server returned a Content-Type: application/xml+xhtml. Actually, mod_proxy always adds a Content-Type header if it is missing, and tries to guess the right content type by the file suffix.

I searched the net for a proper solution of this issue, but found none. After some experiments, a working solution was to configure the Apache web server to force the content type of all .css.xhtml files to text/css:

<LocationMatch "\.css\.xhtml$">
    ForceType text/css
</LocationMatch>

However I don’t know if this is the best practice. A likely better solution would be the Mojarra Faces servlet to return a proper content type for the CSS files.

Written by Shred in Java1 comment

Tags: Apache, CSS, English, JSF

How to fetch a random entry with Hibernate

Friday, August 27, 2010 9:32:12 PM

I recently found myself in the situation where I needed Hibernate to query a single, random entry from a table of Picture entities.

There is a simple way. Some DBMS allow to shuffle the result set by bringing the rows into a random order. For instance, in MySQL it is possible to use a query like this:

SELECT id FROM picture ORDER BY rand() LIMIT 1;

Since Hibernate delegates unknown function calls to the underlying DMBS, rand() could be used in a HSQL query as well:

q.createQuery("FROM picture ORDER BY rand()").setMaxResults(1);

However this query would require MySQL, so we would sacrifice the benefit of Hibernate acting as an abstraction layer to the underlying database. HSQL on the other hand does not offer a similar function.

A solution is to use the pagination technique. First we count the number of entries, and then select a random entry using setFirstResult(). With Hibernate Criteria, it would look something like this:

Criterion restriction = yourRestrictions;
Object result = null;  // will later contain a random entity
Criteria crit = session.createCriteria(Picture.class);
crit.add(restriction);
crit.setProjection(Projections.rowCount());
int count = ((Number) crit.uniqueResult()).intValue();
if (0 != count) {
  int index = new Random().nextInt(count);
  crit = session.createCriteria(Picture.class);
  crit.add(restriction);
  result = crit.setFirstResult(index).setMaxResults(1).uniqueResult();
}

restriction contains further restrictions to the result set (like only pictures that have been published). At the end, result contains a random single entry from the Picture entity, or null if the result set was empty.