January 29th, 2012
3:26 pm
Cannot obtain a class literal for a concrete parameterised type

Posted under Java
Tags , , , , , ,

Update 30/1/2012

After further testing, I have found more issues trying to use a parameterised concrete class in a JPA constructor expression. EclipseLink was throwing MethodNotFoundException complaining that it could not find the constructor method for the class, due to the use of the parameterised type in one of the constructor arguments. The precise circumstances where this does and does not work are not clear.

My solution has been to not use a parameterised class at all in a JPA constructor expression. To avoid most of the code duplication, what I did was to subclass the parameterised class for each concrete type I was using, i.e. I created a concrete subclass which only contained a constructor calling the superclass constructor. This then allowed me to use a typed query in JPA, as the returned class was now non-parameterised and so I could create a class literal for it.

 

Original Post

Whilst in some situations this may be an issue, it is also a statement of fact!

This is due to type erasure at run time, and cannot be done.

It means, for example, that in some cases it is not possible to completely eliminate unchecked warnings.

One example of mine was the use of a parameterised type in a constructor expression class in JPA. I had a requirement to do fetches which involved returning an entity plus another column that could not be handled as a relationship/JPA entity property. The property in question was the count of children for a tree node entity. As I was using path enumeration to describe the tree, I could not use JPA relationships to handle it, and so had to return the child count separately. I had more than one type of tree, all handled polymorphically, and so wanted to re-use the constructor class by making it parameterised.

This all worked fine but the class could not have its class literal passed when created a TypedQuery to fetch the results back. The solution was to use some casting isolated in a specific method, and to suppress the generic warnings via @SuppressWarnings("unchecked").

The following posts detail this issue:-

http://stackoverflow.com/questions/2390662/java-how-do-i-get-a-class-literal-from-a-generic-type

http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html#Why is there no class literal for the concrete instantiation of a parameterized type?

No Comments »

December 18th, 2011
7:58 pm
Eclipse–saving jar creation settings/automating jar export

Posted under Eclipse
Tags , , , ,

Eclipse allows you to export Jars via the Export/Java/Jar File right click option from the package or project explorer on a project.

The export wizard has a number of options. I generally create one jar with the class files in and a second for the sources.

It is obviously somewhat tedious and error prone to select all the options each time, so fortunately on the export wizard, on the Jar Packaging Options page you can select the option to Save the description of this jar in the workspace.

This will then create a .jardesc file with all the options on. Later you can simply right click a previously saved .jardesc  and select Create Jar to recreate the jar with the same options that you saved.

No Comments »

November 8th, 2011
8:02 pm
iMedia Linux– configuration/application install issues

Posted under Linux
Tags , , , , , , ,

This post brings together a number of past issues which I have not posted previously, discovered while setting up and using iMedia embedded Linux on my diskless LinITX Jupiter test box.

A zip of all the customised scripts and various config files (such as the infamous xorg.conf) are in the repository.

Shell Script Usage

1/ The startup scripts for applications and drivers etc. are in /etc/rcS.d/. You just add scripts to that and they are automatically run. They are all run by /etc/rcS in alpha order. They are grouped by a prefix of M05, M10, M20, M30 etc. – this seems just to be an arbitrary grouping that determines the order for dependencies etc. Note that all of rcS.d/ is run at run level 3 as set in /etc/inittab

The general order of startup is therefore (see /etc/inittab):-

  • /etc/rc.init runs, and calls rc.sysinit directly
  • /etc/rc.sysinit iterates init.d and runs everything in it. The order is partly determined by an initial grouping number – note the first to run is 00createvar which creates the /var tree on startup (see later)
  • /etc/rcS runs as above, iterating /etc/rcS.d/

2/ /usr/local/bin/ has the extra shared shell scripts – rlog, rlog-leafpad, sx (start X), sxr (start X as root), plus start/stop scripts for Tomcat and Glassfish.

In Thunar, you can add file associations for scripts by right clicking in the file and selecting open with other application – for each app you can add a custom launch command below. (I added rlog and rlog-leafpad). If you add an incorrect one (I added beaver by mistake) Thunar may not let you remove it from the list. Just edit ~/.local/share/applications/defaults.list and remove it from there. Note that /usr/local/bin/ is already on the path so all the script in it are visible – good place to put other global scripts.

Note that you can add scripts to e.g. a program launcher on the top panel bar – right click and create a program launcher, then add items to it – useful for scripts which run without parameters (unlike the rlog and rlog-leafpad above which act on files and therefore are Thunar’s context menu for the files they operate on). When adding a script as an item to a program launcher, the ‘startup notification’ just gives a wait cursor while the script is running (useful). Running in an explicit terminal window is WEIRD – for example for glassfish I set the middle icon on the RHS pane to “terminal”, and set the command to be “aterm -e start-glassfish”. I did not tick “Run in Terminal” as this did not work however!

Logging under iMedia Linux

1/ Logs are stored under the /var tree which is recreated at startup each time see above, so log files are purged as we are running on a small flash based distro. Therefore, Tomcat and Glassfish for example are set to use sym links to link their log directories from their normal install directories to be under /var/log/. There is some trickery to this – for Glassfish I make sure that the *normal* log folder is not present (renaming it with a date/time stamp if required) else the sym link is set up wrongly.

2/ Some logs (but by no means all) in /var/logs/ are circular buffers handled by emlog  – see here for details. They show in Thunar as ‘character type devices’ and  need copying to be visible – /usr/local/bin/rlog does this using nbcat as per the emlog site. I also added /usr/local/bin/rlog-leafpad which does the copy and fires up leafpad on the result. Note that as the emlog site states, you cannot list such a log when active using cat as a non blocking read is required – hence the need for nbcat as used by rlog and rlog-leafpad.

Installing new Applications

1/ Installing new apps is a pain, as rpm installs don’t appear to be supported etc. I tried installing various zipped tarballs of VNC/RDP alternatives for remote desktop but they all needed dependant libraries I did not have, so I had to give up. I think you can build from source to add things but did not go that far! The apps I did install successfully – java 1.6.0_29, tomcat 6.0.29 and Glassfish 3.0.1 – was all installed in folders under /opt as this appeared to be the correct place. Note that for Tomcat, I placed the config files under /etc/apache-tomcat-6.0.20/conf/ and sym-linked them from the ‘expected’ place, /opt/apache-tomcat-6.0.20/opt/, as this appeared to be correct protocol – other apps placed their config under /etc/ and linked to it from their install directory under /opt/. However I did not go to the trouble of doing this for Glassfish – it would be possible (I did do it for the log directory) but the directory structure is more complex.

2/ I did have success with Java – I just ran the .bin install kit of the latest Linux version of the sun Java SE (jdk6u29), and it all unzipped properly and ran fine. Thankfully there were no library problems – probably because there had already been an earlier working jdk6 already installed by default. I added a shell script /etc/profile.d/java-jdk1.6.0_29.sh which created the JAVA_HOME and added the bin directory to the path, but note that this did not work for init time shell scripts for either Tomcat or Glassfish, so their startup scripts had to add their own definitions to work.

3/ I successfully installed Glassfish 3.0.1 (from the zip kit download). To get it to work I had to upgrade Java as above as I got errors otherwise, and the old jdk was below the minimum certified version. However, it worked fine after upgrading java. Note that to stop it checking for updates on startup I just renamed /opt/glassfish-3.0.1-web/glassfish/modules/console-updatecenter-plugin.jar by adding “.disabled” on the end. You can achieve the same thing using the updatetool, but this failed to install properly due to a python error/dependency. I also removed the default jsf-api.jar and jsf-impl.jar from the same folder as above, and added the Mojarra 2.0.4 FCS jars to the folder instead, as my apps needed this version. Note that this also speeds up the startup of the Glassfish admin tool. See my notes here about clearing the osgi cache if you do this.

4/ For Tomcat and Glassfish I separated out the log directory creation from the actual startup, using separate scripts. The log creation is always run, and so sits under /etc/rcS.d/, and the auto startup is optional and may sit under /etc/rcS.disabled/ as a placeholder if it is not autostarted. However, as the log directories under /var/ are always setup, you can then manually start them if desired and they will still work. This is done with the scripts in /usr/local/bin/start-glassfish/stop-glassfish/start-tomcat/stop-tomcat. As this directory is on the path, the scripts can be directly run from a terminal window OR from a remote SSH window BUT you would need to be logged in as root to do it.

Graphical Remote Desktop

Re remote desktop, it is in theory possible to use a windows based X server and connect in that way. To do this, you need to run an X display manager on the Linux box to handle the xdmcp protocol etc. imedia linux does have /usr/bin/xdm which is an old display manager. I did manage to run it from the initial login prompt before typing startx, just by typing xdm, and it popped a login screen. However it would not connect to xfce. It recognised a valid login and tried to do something, failed, and redisplayed itself. An invalid login gave a login failure. I also managed to run the launcher from XMING under windows, and got as far as connecting to xdm. to do this I edited /etc/X11/xdm/Xaccess to enable the “*” entry to allow all comers. I also experimented with editing /etc/X11/xdm/xdm-config and set DisplayManager*authorize to false, and tried commenting out the last line as follows :-

! SECURITY: do not listen for XDMCP or Chooser requests
! Comment out this line if you want to manage X terminals with xdm
!DisplayManager.requestPort:    0

I managed to get XMING to display the same xdm login screen that I got locally, which was a good start – I knew I had a connection working. However, I realised in the end that xfce does not appear to be using a display manager – it simplifies things and bypasses it, and to set up xdm to link properly to xfce and to work remotely looked like loads of setting up with no instructions on how to do it properly.

I therefore sadly gave up on this and admitted defeat on installing any kind of graphical remote desktop!

Samba

I got the samba server to share folders successfully – I added the shares in /etc/samba/smb.conf. Security was set to user (security = user). I tried setting “valid users=” to a list of users, to allow restriction of users e.g. to glassfish/tomcat log folders, but could not get this to work, so I left it out.

Note that I did need to use “smbpasswd -a username” to add an existing linux user to the samba user list, and give it a password. You need to run as root to do this, or it merely allows you to change your own password. smbusers allows you to map external users (used by windows clients) to linux users – see here. Note that you don’t need to do this – you can just use the linux names. Note also that when adding/setting passwords with smbpasswd, you *always* use the Linux name, not the samba alias. Some other useful links for Samba follow:-

Ftp, Telnet and SSH

1/ ftp is enabled by default via vsftp. The config file is in /etc/vsftpd/vsftpd.conf. The default settings are pretty sensible in opening it up for use in a secur local lan. ftp works via all the local linux accounts including root. The log is in /vat/log/vsftpd.log.

2/ Telnet works but does not allow root access (presumably as too insecure). utelnetd is the daemon but there is no documentation for it on the net I could find. SSH works fine via the sshd and allows root access, but could not find any config files or logging for it, although it is documented on the net – the man pages are here, however the config files mentioned for the daemon do not appear to be present under imedia Linux. No problem, it is set up fine for LAN use and works well from putty in ssh mode.

No Comments »

September 23rd, 2011
1:21 pm
JPA – Using a mapped superclass to hold Ids and Version Numbers for all Entities

Posted under JPA
Tags , , , ,

All my entities have a numeric ID as a primary key, except in very exceptional cases. In particular, I never used business data as part of the primary key, nor do I ever use a primary key for any business purposes (such as an invoice number). I consider that primary and foreign keys are only used to define relationships, i.e. they are metadata as far as the domain model is concerned.

The problem of using business data in primary keys is that if the business data format for a primary key changes in any way, all the foreign keys referring to this primary key column must also be changed. This can result in massive changes throughout the data model for what started as a simple business change. Taking the above invoice number for example, the business may decide to add an alphanumeric branch prefix to the invoice number.

If instead all primary keys are kept as separate numeric IDs, changes to the format of business data should typically only require changes to one table.

With that rant out of the way, the main point of this post is that, given the above, plus the need to hold version numbers on all entities to support optimistic locking, it is desirable to hold all the primary keys and version numbers in a mapped abstract superclass. This has the following benefits:-

  • the entities are simplified and the key/version number implementation is encapsulated and centralised, which is a good design principle
  • the mechanism allows for a standard mechanism to get the primary key/version of any entity polymorphically via the mapped superclass. This is especially useful when you need to do comparisons between entities and you do not want to override equals on the entities. It is also useful for other polymorphic situations – in my case I also have a polymorphic tree implementation which makes use of this

Note the following points about the implementation:-

  • As I have discussed here, I always annotate getters rather than fields, to permit inheritance. In this case, I provide fields plus polymorphic getters/setters in the mapped superclass for getEntityId and setEntityId which are marked transient and are not annotated. They are purely to allow polymorphic access to the primary key.
  • Each entity defines its own getters/setters with a mnemonic name for the primary key. These getters/setters call the base polymorphic ones. The reason for this is that as well as improving the key naming,  it allows each entity to annotate its primary key differently, for example to use a specific generator for sequences etc.
  • As the primary keys are annotated in the subclasses, this permits the base superclass IDs to be generic. In my case, this caters for both Long and Integer primary keys using a generic base superclass. Note that it would not be possible to annotate in the superclass if the ID is a parameterised type – JPA spits this out and will not allow it.
  • Due to the above generic issue, the type for the version number must be fixed, as this is annotated in the superclass. In my case I settled for an int for version numbers.
  • Note that as the primary key is generic, it must therefore be a reference type rather than a primitive type (e.g. Long rather than long). In my case, primary keys are normally Long
  • In some cases, I have other mapped superclasses, such as Tree and TreeNode classes. In this case, Tree and TreeNode extend the EntityBase class, and Tree and TreeNode subclasses then just extend Tree and TreeNode respectively.

The following code illustrates a simple example of the superclass and an entity subclass:-

 

EntityBase

/**
* Entity implementation class for Entity: EntityBase
* This mapped superclass defines the primary key and locking version number for all entities.
* The getters/setters are marked transient so they are not mapped here. This allows polymorphic access to primary key (and version),
* but still allows the subclass to define its own (mapped) getter/setter names for the primary key, and to annotate for specific generators etc.
* This allows meaningful names for primary keys, normally <tableName>Id
*/
@MappedSuperclass
@Access(AccessType.PROPERTY)
public abstract class EntityBase<C> implements Serializable {
    private static final long serialVersionUID = 8075127067609241095L;

    private C entityId;
    private int version;
   
    @Transient public C getEntityId() {
        return entityId;
    }
    @Transient public void setEntityId(C entityId) {
        this.entityId = entityId;
    }
    /*
     * The version cannot be generic as it is annotated here (unlike the primary key)
     * If you do, Eclipselink throws a tantrum. In practice, an int is plenty –
     * it would allow continuous version changes once a second for over 68 years for example.
     */
    @Version
    public int getVersion() {
        return version;
    }
    public void setVersion(int version) {
        this.version = version;
    }
}

 

Address

@Entity
@Access(AccessType.PROPERTY)
public class Address extends EntityBase<Long> implements Serializable {
    private static final long serialVersionUID = 3206799789679218177L;
   
    private int latitude;
    private int longitude;   
    private String streetAddress1;
    private String streetAddress2;
    private String locality;
    private String postTown;
    private String county;
    private String postCode;
       
    public Address(){}

    @Id
    @GeneratedValue(generator="AddressId")   
    public Long getAddressId() {return super.getEntityId();}
    public void setAddressId(Long addressId) {super.setEntityId(addressId);}
   
    public int getLatitude() {return latitude;}
    public void setLatitude(int latitude) {this.latitude = latitude;}
    public int getLongitude() {return longitude;}
    public void setLongitude(int longitude) {this.longitude = longitude;}
   
    public String getStreetAddress1() {return streetAddress1;}
    public void setStreetAddress1(String streetAddress1) {this.streetAddress1 = streetAddress1;}
    public String getStreetAddress2() {return streetAddress2;}
    public void setStreetAddress2(String streetAddress2) {this.streetAddress2 = streetAddress2;}
    public String getLocality() {return locality;}
    public void setLocality(String locality) {this.locality = locality;}
    public String getPostTown() {return postTown;}
    public void setPostTown(String postTown) {this.postTown = postTown;}
    public String getCounty() {return county;}
    public void setCounty(String county) {this.county = county;}
    public String getPostCode() {return postCode;}
    public void setPostCode(String postCode) {this.postCode = postCode;}   
}

No Comments »

September 23rd, 2011
12:18 pm
Re-queuing JSF Events

Posted under JSF
Tags , , , ,

This is a very simple and powerful technique which can provide an easy solution to a number of event issues.

The case in point was where I wanted a value change event on an input component (a check box) to behave like an action event.

The value change event will normally fire after validation (after the Process validations phase). In my case, I wanted the event to be fired at the Invoke Application phase, as would happen with a button click. In other words, I wanted my checkbox to behave more like a button.

Whilst there are other ways around this  kind of issue, they often involve messing with the JSF life cycle by using immediate components/calling render response early etc. and typically have other side effects. For example, in a Value change event you will not see the results of the bean setters being called as this has not happened yet, so you end up having to make JSF calls to manually update values early etc.

Instead, a value change event can easily be re-queued to occur in the Invoke Application phase. The beauty of this is that you are relocating the event rather than messing with the JSF lifecycle, which means that the event happens in the context you want it to, and everything is set up correctly.

To requeue an event, you must detect when it fires the first time, and then requeue it. When it fires the second time, you detect this again and perform the action that you desire.

Here is a code sample which does this:-

    public void showInheritedListener(ValueChangeEvent event) {

        /*
         * Requeue this event to the Invoke Application phase so it behaves like an action
         * This ensures that all the model values have been updated.
         */
        if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
               log.fine(this+":showInheritedListener: oldValue="+event.getOldValue()+", newvalue="+event.getNewValue());       
            boolean newValue = (Boolean)event.getNewValue();
            changeInherited(newValue);
        }
        else {
            event.setPhaseId(PhaseId.INVOKE_APPLICATION);
            event.queue();
        }       
    }   

An important point to note is the use of event.getPhaseId() to detect which phase the event is currently being called in. In particular, when it is first called after the Process Validations phase, it is important to note that event.getPhaseId() will return PhaseId.ANY_PHASE, which is not expected or intuitive. You will see from the above code that by handling the first call to the event in the else clause of the if, we only have to test for the second call, when event.getPhaseId() will return PhaseId.INVOKE_APPLICATION as you would expect.

This technique is clean and simple to use, and does not suffer from unwanted side effects that other solutions have. It is well worth taking note of.

No Comments »

July 19th, 2011
10:14 pm
Accessing JSF Resource Bundles from Java Code

Posted under JSF
Tags , , ,

This is useful to be able to do. Typically you will want to declare a resource bundle in faces-config.xml to load it once for the application. You then refer to it from any JSF page that needs it.

However, you often want to also load messages from code. An example might be the generation of custom faces messages or other error messages generated by the code.

It is clearly therefore desirable to access the same message bundle that JSF has loaded, so that it is specified centrally, loaded once for the application, and reused by both JSF and Java.

This post here by Andy Gibson details how to do this. The code fragments are shown below, in case the link ever becomes broken:-

 

Resource File

firstName=First Name
lastName=Last Name
forgotPassword=Forgot Password?
usernameTaken={0} is already taken

 

faces-config.xml

<application>
    <resource-bundle>
        <base-name>org.fluttercode.resourcedemo.MessageResources</base-name>
        <var>msgs</var>
    </resource-bundle>
</application>

 

Class MessageProvider

public class MessageProvider {

    private ResourceBundle bundle;

    public ResourceBundle getBundle() {
        if (bundle == null) {
            FacesContext context = FacesContext.getCurrentInstance();
            bundle = context.getApplication().getResourceBundle(context, “msgs”);
        }
        return bundle;
    }

    public String getValue(String key) {

        String result = null;
        try {
            result = getBundle().getString(key);
        } catch (MissingResourceException e) {
            result = “???” + key + “??? not found”;
        }
        return result;
    }

}

Backing Bean

@Named
@RequestScoped
public class SomeBean {

    public String getMessage() {
        String msg = new MessageProvider().getValue(“someMessage”);
        return MessageFormat.format(msg, “SomeValue”);
    }
}

Example Code to generate a custom FacesMessage (from CoreJSF Edition 3, Page 332)

public void validateDate(ComponentSystemEvent event) {
    UIComponent source = event.getComponent();
    UIInput dayInput = (UIInput) source.findComponent(“day”);
    UIInput monthInput = (UIInput) source.findComponent(“month”);
    UIInput yearInput = (UIInput) source.findComponent(“year”);
    int d = ((Integer) dayInput.getLocalValue()).intValue();
    int m = ((Integer) monthInput.getLocalValue()).intValue();
    int y = ((Integer) yearInput.getLocalValue()).intValue();

    if (!isValidDate(d, m, y)) {
       FacesMessage message = com.corejsf.util.Messages.getMessage(
            “com.corejsf.messages”, “invalidDate”, null);
        message.setSeverity(FacesMessage.SEVERITY_ERROR);
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(source.getClientId(), message);
       context.renderResponse();
    }

}

No Comments »

July 19th, 2011
5:35 pm
Calling a utility POJO from a Session Bean

Posted under EJB
Tags , , , ,

Update 17/10/2013

This StackOverflow Post here is by David Blevins, EJB 3.1 expert group member among many other things. It confirms my original post below that plain CDI beans can be freely mixed with EJBs etc. and that you use what you need based on the features offered. It confirms that an @ApplicationScoped bean is pretty much an @Singleton but does not have the @Startup capability to run a method when the application starts. There is a javax.inject.Singleton as well as a javax.ejb.Singleton, however this post here points out that javax.inject.Singleton is not part of the official CDI spec. Therefore, it suggests (as does David Blevins in the above post) that you use @ApplicationScoped if you don’t need the special transactional/locking features of @Singleton (javax.ejb.Singleton that is), as it can be a lot faster.

In my case, there are a number of places where I may now end up replacing intermediate @Stateless beans with @Application scoped ones for simplicity and performance.

Original Post

A number of blog posts on this maintain that you need to create an EJB singleton for this, and set it to readonly, perhaps with Transactionattribute  set to unsupported to suspend the transaction whilst in the utility POJO/EJB.

Assuming the utility POJO did no database access and had no transaction involvement, I could see no reason for this. After all, an EJB can create and use an ArrayList for example without having to take any special actions. Why should my utility POJO be any different? In my case, the POJO was using the Apache Base64 encoder to encode an ID in Base64. When I subsequently read the CDI spec for info on this, it came to the rescue. CDI states that you can pretty much inject anything into anything else.

In particular, on P13 of the weld spec, Section 2.2.2 “SessionBeans” it states :-

“You can inject one session bean into another session bean, a managed bean into a session bean, a session bean into a managed bean, have a managed bean observe an event raised by a sessionbean, and so on.”

Therefore, if I just have a plain utility class which has nothing to do with session beans, the DB, or transactions, I can just inject it with CDI and call it from a session bean. I do not have to make it a singleton session bean/with readonly locking/transactions not supported etc.

The restriction would be that unlike session beans it could not be called remotely with all the clever EJB remote stuff, however this is absolutely not required in cases like this, I would just deploy it as a utility library in the local container along with the rest of the application. Each application server would therefore have its own copy.

This finally makes sense. In my case, it also works perfectly well when I inject an application scoped POJO into a stateless session bean.

No Comments »

June 3rd, 2011
2:14 pm
Version Manager Facility

Posted under Java
Tags , , ,

This utility was developed to allow JSF and Java software to dynamically manage dependency issues caused by interface changes across differing versions of dependant libraries, by querying the utility at runtime with rule based match checks about the versions actually deployed. Typically interfaces to software are consistent for a range of versions, and then change whereupon they remain the same for a further range of versions. The Version
Manager thus allows rule based checks to match a contiguous range of versions, as well as matching a single specific version.

The utility was developed in response to issues caused by changes between Primefaces versions. A particular case in point was that some custom Javascript and CSS was implemented for V2.2.M1 to fix common issues concerning header alignment and column width for scrolling tables. These changes were encapsulated in .css and js files in a TableCC composite component which decorates the standard Primefaces p:dataTable.
These fixes of necessity used css and jQuery selectors referring to underlying Primefaces structural css classes – this exposes such code to risk of change, but in this case the risk was justified as the code was there to fix issues.

The css in Primefaces changed late on in the V2.2 cycle – the class names changed and the HTML was simplified to remove a div container layer. These changes broke the above code. It was felt that this would in general not be an isolated issue. Primefaces is a fast moving development project, which has its upsides in that new features and new versions come onstream regularly. The downside in a fast moving environment can be issues such as the
above one. In fairness to Primefaces, it is very difficult to develop a generic Table component using current HTML standards which allows fixed column headers with a scrolling data table. Some things such as dynamic resizing of columns just cannot play ball in the current scenario, and scroll bars coming and going with different data volumes add further challenges of their own! In practice it is not possible to cover every possible use case. My approach is to narrow down a particular set of use cases I need to work with, and then come up with the necessary fixes/decorator components as above to handle those particular use cases.

In order to mitigate the effect of this kind of issue when versions change, and to avoid proliferation of a number of different code versions each matched to a set of dependant library (e.g. Primefaces) versions, a Version  Manager facility was developed.

The Version Manager including PDF documentation and an example may be found in the repository here.

No Comments »

May 31st, 2011
6:42 pm
Iterating CDI Bean Types

Posted under CDI
Tags , , ,

When developing plugin architectures with IOC, it is useful to be able to iterate over the available beans of a given type which are known to the IO container.

In CDI, this is easy to do, but it is not obvious how from the Weld documentation unless you do a bit of digging and searching.

This post here gives a sample application which does it. The crucial code snippet which does the business is here:-

private @Named @Produces ArrayList<String> wilsons = new ArrayList<String>();
@Inject
void initWilsonRacquets(@Any Instance<WilsonType> racquets) {
    for (WilsonType racquet : racquets) {
        wilsons.add(racquet.getWilsonRacquetType());
    }
}

The intance keyword (used with @Any) exposes an iterator which lets you iterate the available beans. In the above sample they are added to a collection, but you could equally call methods on them as you iterate if you don’t need to keep them.

The Weld documentation describes this on page 25, with the following sample fragment:-

@Inject
void initServices(@Any Instance<Service> services) {
    for (Service service: services) {
        service.init();
    }
}

No Comments »

April 12th, 2011
3:28 pm
Action, Listener and Validator Retargeting in a JSF composite component

Posted under JSF
Tags , , , ,

Update 6/7/2011

There appear to be major issues with the design of retargeting when using it in nested composite components – it fundamentally does not work. See this JSF JIRA issue here for details on this. There is quite a robust debate in the comments on the post as to whether to deprecate and redesign retargeting completely, but it looks like that will not happen.

Original Post

This is very much an undocumented feature of JSF 2, but it is possible for the action method for a command component such as a button or link to be passed in to the CC by its client.

You might think that you can just pass in a method expression string as an attribute and use that attribute within the CC on the action attribute of a button, but this fails as there is more that needs to go on behind the scenes. To make it work, you use the targets= attribute when declaring the action attribute on the CCs interface using composite:attribute – note that the attribute in the CC interface must be called action.

This is discussed in a comment (by Cay Horstmann no less) in this StackOverflow post here.

Note that according to the link here from the above post, you can also retarget actionListeners, validators and valueChangeListeners in the same way. In these cases, the attribute name must be called actionListener, validator or valueChangeListener respectively in the same manner as is done with action above. Check the link out for full details – its not exactly clear on its own but it is easier to understand once you have the concepts from Cay Horstmann’s post above.

No Comments »