Archive for the 'Java' Category

January 5th, 2010
5:34 pm
Java Bean Introspection and dynamic Sorting/Comparison

Posted under Java
Tags , , , , , ,

Whilst this can be done with the Reflection API, there are standard APIs that do this for Beans and which are therefore a better choice.

java.beans.beaninfo is a standard API for bean introspection. Better still for many applications is the Apache Commons BeanUtils library.

This provides a really simple interface for many operations. For example, get/set of simple bean properties dynamically is a single call as in this example :-

Employee employee = ...;
    String firstName = (String)
      PropertyUtils.getSimpleProperty(employee, "firstName");
    String lastName = (String)
      PropertyUtils.getSimpleProperty(employee, "lastName");
    ... manipulate the values ...
    PropertyUtils.setSimpleProperty(employee, "firstName", firstName);
    PropertyUtils.setSimpleProperty(employee, "lastName", lastName);

One of my requirements was a dynamic sort comparator for use in sorting JSF tables by any column. A static comparator is fast, but messy, as you need to hard code switch statements etc. for the property to be compared. BeanUtils has a better option and can create a dynamic comparator for you as in the following code fragment from here :-

List tvShows = new ArrayList< WorldsGreatestTVShow>();
    //group (sort) by actor
    BeanComparator actorComparator = new BeanComparator("actorName");
    Collections.sort(tvShows, actorComparator);
    //group (sort) by producer
    BeanComparator producerComparator = new BeanComparator("producerName");
    Collections.sort(tvShows, producerComparator);

However, there is a performance hit with using this – one comparison cited 16ms using a hard coded static comparator, compared to 400ms using the BeanUtils BeanComparator. Always one to strive for perfection, I said to myself “why can’t I have both” – i.e. a dynamically created comparator for no effort but which performs as well as a static one? Well, after a bit of searching I found one in the form of the Cojen Project. This is a project aimed at supporting dynamic bytecode generation and disassembly. However, the project also provides a number of powerful utility classes which use the bytecode generation to create fast dynamic Bean Comparators with the same peformance as a statically coded comparator, perform fast Bean Property Introspection, and fast Pattern Matching.

Here is an example comparator which orders threads by name, thread group name, and reverse priority :-

 Comparator c = BeanComparator.forClass(Thread.class)
     .orderBy("name")
     .orderBy("threadGroup.name")
     .orderBy("-priority");

I particularly love the fact that the customising methods e.g. orderBy return the comparator instance so that you can chain them together as above. Sorting by multiple properties is supported as the above example shows. All the generated objects are fully serializable. I  also love the fact that you can prefix a property name with a minus sign to reverse the comparison order for that orderBy, which is great for toggling column sort orders with JSF etc.  A brief test had it working correctly in no time, and it does indeed appear to be just as fast as a static comparator and very flexible. In future, I would make Cojen my first port of call for bean pattern matching / introspection / comparison without hesitation, and then look at Apache Commons BeanUtils only if Cojen couldn’t do what I needed, then failing that java.beans.beaninfo or finally the raw reflection API.

I really can have my cake and eat it! Sex on a stick!

No Comments »

January 5th, 2010
4:56 pm
@ManyToMany issues with Eclipselink 1.1.2

Posted under JPA
Tags , , , ,

I found a number of issues when configuring a many to many relationship, but eventually found a working solution.

1/  This example for a many to many uses referencedColumnName when it does not need to – it was a hangover from an example using multiple join columns. If you do this with Eclipselink 1.1.2 and Oracle (in my case XE 10g), the columns are created with data types of varchar2(255) instead of the default of number(19)  :-

      @ManyToMany
      @JoinTable(name="AppUserRole",
                 joinColumns =@JoinColumn(name="AppUserID",
                                          referencedColumnName="AppUserID"),
                 inverseJoinColumns=@JoinColumn(name="AppRoleID",
                                          referencedColumnName="AppRoleID”))

The referencedColumnName attribute is the cause of this issue. Leaving it out causes correct column types. It is only needed for multiple column joins (which break anyway see 2/), and so should not be used. This therefore works correctly and is the recommended format to use  :-

      @ManyToMany
      @JoinTable(name="AppUserRole",
                 joinColumns =@JoinColumn(name="AppUserID"),
                 inverseJoinColumns=@JoinColumn(name="AppRoleID"))

2/ Using a many to many as in 1/ but with multiple join columns causes eclipselink bug 300485. (Although listed as a one to many bug it also happens with many to many). This is not due to be fixed until eclipselink 2.1. The bug gives a query parameter not found error for an internally generated query used when eclipselink lazily loads a relationship collection.

3/ Leaving out the @JoinTable and only having the @ManyToMany annotation works ok, but gives an XML column name resolution error from eclipse for one of the join columns. This is purely an ‘invalid validation’ however, as the code runs fine against a database created from it.

4/ using the xml annotations in orm.xml along with just an @ManyToMany annotation in the code works fine, but you do get some validation errors from Eclipse as the validation does not appear to merge the annotations and xml correctly when validating :-

<entity>
  <attributes>
   <many-to-many name="appRoles">
    <join-table name="AppUserRole">
     <join-column name="AppUserID" column-definition="number(19)"/>
     <inverse-join-column name="AppRoleID" column-definition="number(19)"/>
    </join-table>
   </many-to-many>
  </attributes>
 </entity>

This would be the preferred route if anything database specific  was needed, such as the column-definition attributes for Oracle in the example.  The “@ManyToMany” annotation on the entity may be superfluous in this case but is a helpful label. A comment in the code that there are overrides in orm.xml would be helpful. The above fragment was tested but without the column-definition attributes on the columns – these are shown as examples of how to add database specific column definitions without having to pollute the code with them via annotations.

The intention here would be to use xml in conjunction with annotations, with annotations used for all the standard metadata. Different versions of orm.xml and persistence.xml could then be swapped in and out for different back end databases, keeping the code standard. The same approach has been advocated to permit using Oracle sequences here.

No Comments »

January 5th, 2010
9:05 am
JPQL Query Editing Tools

Posted under JPA
Tags ,

Not too many of these around…

The plan is to donate the Oracle Weblogic Workshop JPQL Query Editor but haven’t seen a release of that yet.

jpaquerytool looks like a possible – a stand alone query tool. You need to feed it your jars in order to give it your entity definitions, then off you go. It mentions Toplink Essentials but not Eclipselink, and it has to use proprietary apis to get the entity mapping metadata so may have issues but worth a look.

No Comments »

December 18th, 2009
10:26 pm
Using CVS with Eclipse CVS / TortoiseCVS / CVSNT

Posted under CVS
Tags , , , ,

This post details the installation I use for CVS based source control, together with some usage points and gotchas I came across. My preferred installation consists of the Eclipse CVS plugin and TortoiseCVS on the client side. This gives the flexibility of CVS access both inside and outside Eclipse. In my experience both CVS clients coexist well, and changes in one are immediately  reflected correctly in the other as would be expected. My server side consists of CVSNT running on a separate repository server.

I have broken this tutorial down into linked sub-posts as it was becoming too monolithic and covered multiple topics. The steps are as follows :-

1/ Server Installation using CVSNT

3/ Client Installation, Configuration and usage notes- TortoiseCVS

4/ Client Installation, Configuration and Usage notes – Eclipse CVS Plugin

5/ Branching and Merging in Eclipse CVS and TortoiseCVS

No Comments »

December 18th, 2009
8:10 pm
Tomcat as a service under Windows 7 64 Bit / 32 bit JVM

Posted under Tomcat
Tags , ,

See the Tomcat 6 Download Page

If you use the Windows service installer (self installing Exe) to install Tomcat 6.0.24 under Windows 7 64 bit, it insists on a 64 bit JVM. I am using a 32 bit JVM and if you try to use that, Tomcat will not start.

You can do this by using the 32 bit Windows zip version, which still allows you to run Tomcat as a service. It also allows you access to the Tomcat Configuration/Monitor utility which you can also run in the System Tray, but you have to set this up manually.

The following steps will do this install :-

1/ Download the 32 bit Zip installation above, and unzip to the desired target installation location.

2/ Edit <Tomcat Home>\conf\server.xml to change the default http port from 8080 if required

3/ Edit  <Tomcat Home>\conf\tomcat-users.xml to add an admin user if desired, by inserting the following in the <tomcat-users> section :-

<role rolename=”manager”/>
<role rolename=”admin”/>
<user name=”admin” password=”mypassword” roles=”manager,admin”/>

4/ Issue the command Service install from an administrator privileged command window pointing at the <Tomcat Home>\bin directory.

5/ Create the following shortcuts to run the Tomcat Configuration Utility and the System Tray Monitor Utility.
Substitute your device and directory for <Tomcat Home>.

Configuration Utility – Target “<Tomcat Home>\bin\tomcat6w.exe”  //ES//Tomcat6
System Tray Monitor – Target:  “<Tomcat Home>\bin\tomcat6w.exe”  //MS//Tomcat6
(Both Cases) – Start In: may be left blank
(Both cases) – Tick the Run as Administrator check box under either the Shortcut or compatibility tab.

6/ Note that you will have to OK running as administrator each time you run one of the shortcuts, assuming you have User Account Control turned on in Windows 7. This is also true if you try to run the tray monitor automatically in the startup group. Windows 7 insists that each time you log in, you have to OK the administrator usage(!) This is supposed to happen by adding such autostarted tray applications to a “blocked startup” group which have a tray icon to display and then selectively “OK” them to unblock them/OK the administrator usage. This never worked for me – anything I placed in the startup folder which needed administrator access just plain did not run at all, and I never saw this “blocked” icon. As it would mean OKing at each login anyway, it seemed to me that there is no point trying to autostart tray icons that need administrator access as it was more hassle to unblock them (even if it did work) rather than just run them as needed from the super bar or quick launch bar (and of course OK them).

No Comments »

December 18th, 2009
7:45 pm
Installing the Glassfish Eclipse Plugin

Posted under Eclipse
Tags , ,

The process is a workaround for this eclipse bug, which seems to have been around for some time.

  1. In Eclipse, enter Help/Add new software
  2. Click the Add button to add a new update site, and enter the url https://ajax.dev.java.net/eclipse (I have also used http://ajax.dev.java.net/eclipse instead as suggested by other forums, but some users state that this does not work).
  3. Wait for the screen to populate (this may take some time), then select “Glassfish Java EE 5 and Java EE 6 support” and hit next
  4. Proceed with the installation as directed by the wizard.

No Comments »

December 18th, 2009
7:38 pm
Running CVSNT as a limited account under Windows XP Pro

Posted under CVS
Tags , , ,

To set this up, I gave the designated user full permissions on the repository root, with full inheritance to all subfolders and files. I also made the user the owner, but this may not have been required. I also gave full access to the designated temp directory (the one set up in CVSNT admin) to this user.

When I tried to use a dedicated ‘limited’ (non administrator) account under windows XP pro I received the following error when I tried a checkout of CVSROOT :-

CVSNT user does not have read access to CVSROOT

Initially I thought this was an issue blocking all checkouts, as with the user set as an administrator, this checkout is allowed. However, the error only occurs on CVSROOT – all other operations on other modules appear to work normally. As CVSROOT is created internally by CVSNT as part of the repository, we should not be checking it out anyway so this should not be a problem.

Setting up this way minimises security issues especially when saving an explicit password parameter in TortoiseCVS (with the pserver protocol) to get around the lack of password caching.

The CVSNT admin utility, under the Server Settings tab, allows an anonymous user to be specified, allowing anonymous access from the clients. I did test this briefly, but could not get it to play ball with TortoiseCVS – tortoise always seemed to get demands for a password and gave an error if I tried anonymous access. I googled for answers to no avail – no info was available on this setting. I combed the documentation but this all seems to be aimed at the command line interface to CVS rather than the GUI control panel interface used in CVSNT.

My final solution therefore was to use an explicit limited (non administrator) account, which works fine.

No Comments »

December 18th, 2009
6:46 pm
Installing the IceFaces Eclipse Plugin

Posted under Eclipse
Tags , ,

At the time of writing, the latest plugin version is 3.6.2. The zip of this version does not contain the installation instructions which were present in version 3.6.1, explaining how to download to a local repository and install from that within Eclipse.

The instructions may be found in ReadMe.pdf here.

No Comments »

December 18th, 2009
5:38 pm
Eclipse JPA out of synch with newly fetched CVS project

Posted under Eclipse
Tags , ,

I had this issue when deleting and refetching a project from CVS into Eclipse.

It reported that it was unable to resolve a number of the persistence classes such as EntityManager and EntityManagerFactory, even though the libraries and the imports were all present correctly.

This was solved by removing the Java persistence facet from the project facets page, applying the change, and adding persistence back and reconfiguring it. The problem then disappeared.

This was one of several Eclipse ‘gotchas’ I have found where Eclipse reports errors which do not exist. Often, a reconfigure such as the above, or a restart/reload will sort it.

No Comments »

December 18th, 2009
5:25 pm
Eclipse error “Class is listed in persistence.xml but not mapped”

Posted under Eclipse
Tags , , ,

Sometimes eclipse lists the following error in the problem view :-

Class xxx is listed in the persistence.xml file but is not mapped

This appears to be a synchronisation problem within Eclipse, as deleting the classes from persistence.xml and then adding them back by browsing with Eclipse’s own persistence.xml editor eliminates the problem, even though the resulting file is identical. Validating the original file did not solve the problem.

Even with the error listed, projects still run and build successfully, so the problem is not serious.

I have also had other cases where Eclipse has whinged about a perfectly good persistence.xml, and have in general just lived with it as it is not serious.

This is an important issue to be aware of though to prevent much head scratching when such a problem is believed to be a real error and is not!

No Comments »