Tuesday, December 8, 2009

Newbie's Guide to using JBoss Cache in JBoss AS


The promise of JBoss Cache is that it makes distributed caching really easy. But it can be hard to figure out how to use it, because many of the docs are concerned with installation and configuration. Yet the promise of JBoss AS is that everything is already installed, configured and integrated together, so how do you skip all that and get straight to The Good Stuff?

So, this is the blog I was looking for:

If Today You Are Running JBoss AS And Have...

public class MyBeanOrControllerOrWhatever {

   private final static Map MY_CACHE = new HashMap();

   public Object lookupSomething( Object key ) {

      Object value = MY_CACHE.get( key );

      if ( value == null ) {
         value = lookupUncached();
         MY_CACHE.put( key, value );
      }

      return value;
   }
}
(ie. you are using a static Map for your cache - which is fine but will not distribute across VMs)

...Then Using JBoss Cache You Can Do

public class MyBeanOrControllerOrWhatever {

   public Object lookupSomething( Object key ) {

      CacheManager cacheManager = CacheManagerLocator.getCacheManagerLocator().getCacheManager( null );
      Cache myCache = cacheManager.getCache( "sfsb-cache", true );


      Fqn fqn = Fqn.fromString( MyBeanOrControllerOrWhatever.class.getName() );
      Object value = myCache.get( fqn, key );

      if ( value == null ) {
         value = lookupUncached();
         myCache.put( fqn, key, value );
      }

      return value;
   }
}

Where:
  • fqn is a unique key in the JBoss Cache tree so that you don't conflict with other caches

  • sfsb-cache is a pre-configured JBoss AS cache that replicates asynchronously and never expires

  • CacheManagerLocator is in common/lib/jboss-ha-server-api.jar

  • CacheManager is in server/all/lib/jbosscache-core.jar

You'll also need to edit server/all/deploy/cluster/jboss-cache-manager.sar/META-INF/jboss-cache-manager-jboss-beans.xml to pre-start the cache:

<!-- Start these caches as part of the start of this CacheManager -->
<property name="eagerStartCaches">
   <set>
      <value>sfsb-cache</value>
   </set>
</property>

This should be enough to get you working and get you excited. All this actually is in the JBoss Cache docs, just waaaay at the back in Chapter 11. After a while you should probably look at configuring your own cache rather than hijacking sfsb-cache, as that's not strictly meant for your own stuff. Here's a simple one that's kind of a 'distributed Map with max 300 entries':

   <entry>
      <key>my-cache</key>
      <value>
         <bean name="MyCache" class="org.jboss.cache.config.Configuration">
            <property name="isolationLevel">NONE</property>
            <property name="cacheMode">REPL_ASYNC</property>
            <property name="evictionConfig">
               <bean class="org.jboss.cache.config.EvictionConfig">
                  <property name="wakeupInterval">5000</property>
                  <property name="defaultEvictionRegionConfig">
                     <bean class="org.jboss.cache.config.EvictionRegionConfig">
                        <property name="regionName">/</property>
                        <property name="evictionAlgorithmConfig">
                           <bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
                              <property name="maxNodes">300</property>
                           </bean>
                        </property>
                     </bean>
                  </property>
               </bean>
            </property>
         </bean>
      </value>
   </entry>


Though note that maxNodes refers to the number of Fqn nodes, rather than the Map entries within one of those nodes. So instead of:

myCache.put( fqn, key, value )


You'll have to start doing:

myCache.getChild( fqn ).addChild( Fqn.fromElements( key )).put( key, value )


(ie. create a full-blown child node based on converting each key to an Fqn)

Improvements welcome!

Thursday, November 26, 2009

Metawidget: King of the Hill


Nice article here (at least I assume it's nice, my German is even worse than Google Translate's):


My thanks to the author.

Wednesday, November 18, 2009

We're Hiring!

Here's the job ad we're posting today. A chance to work from home, and work for me! What a dream job :)


Senior Java EE 5 (J2EE) Developer: $90,000 - $100,000 AUD
  • Small, focused team

  • Modern, well-crafted software

  • Work in city or from home
A rare opportunity to join our small consultancy team. We have recently received substantial investment from a leading Australian financial institution and we must grow to meet demand.

You will work side-by-side with one of Australia's premier Java EE developers, and be intimately involved in all design decisions.

You will be a pragmatic programmer. Software development will be in your blood: a natural instinct. You must be passionate about Open Source and Java EE. You will demonstrate advanced analytical skills; an eye for elegance and craftmanship; a passion for refactoring, unit testing, and delivering secure and robust code.

Your skills will include many of the following:
  • JBoss

  • JSF/RichFaces

  • XSL (T and FO) and XPath

  • EJB 3/JMS

  • JPA/SQL

  • Metawidget

  • HtmlUnit

  • HTML/CSS
In addition, you will have excellent communication skills and be comfortable interacting with stakeholders at all levels.

Work from home will be offered providing that you can demonstrate an appropriate working environment. You must be a citizen or permanent resident of Australia.

To help us sort applicants, include your CV and a 1 page overview highlighting your suitability for the role. Links to examples of your work (eg. web sites you have built, blogs you have written, Open Source contributions etc) will be highly regarded.

Please send your application to jobs@kennardconsulting.com.

Wednesday, November 11, 2009

Safely manipulating the component tree with JSF 2

The information in this blog post has been superseded. Please see Safely manipulating the component tree with JSF 2, revisited

The Problem

A common problem encountered by writers of dynamic JSF 1.x components (like Metawidget) was "at what point in the lifecycle can I safely manipulate the component tree"?

For a page's initital GET request, there weren't many lifecycle methods you could hook into - you basically had encodeBegin. For subsequent POST-backs there were a slew of hooks, including decode, processValidators and processUpdates, but none were at exactly the right place in the lifecycle to do safe component tree manipulation. What would be 'exactly the right place'? Namely:
  1. the component tree should be fully realized (ie. all parents and children should be set)

  2. the component tree should not have been serialized yet
Because there was no 'official' place, writers of dynamic JSF 1.x components had to resort to all kinds of tricks. As Ken Paulson wrote "...people use constructors, bindings, action methods... people create their own renderer which dynamically adds children each request". To which Jacob Hookum opined "what's actually needed is post component tree creation hooks, providing the ability to then modify the component tree".


The Saviour

Enter JSF 2. From the spec "System Events are introduced in version 2 of the specification and represent specific points in time for a JSF application". They are like the old PhaseEvents, but much more fine-grained. For the purposes of this blog, the SystemEvent we are interested in is PostAddToViewEvent.

To use it, first subscribe to the event in your UIComponent's constructor...

public class UITestComponent
   extends UIComponentBase
   implements SystemEventListener {

   public UITestComponent() {
      FacesContext ctx = FacesContext.getCurrentInstance();
      ctx.getViewRoot().subscribeToViewEvent(PostAddToViewEvent.class, this);
   }

...then, when it gets fired, you can safely manipulate the component tree ...

public void processEvent( SystemEvent event ) throws AbortProcessingException {

   FacesContext ctx = FacesContext.getCurrentInstance();
   UIComponent dynamicallyGenerated = ctx.getApplication().createComponent( "javax.faces.HtmlInputText" );
   getChildren().add( dynamicallyGenerated );
}


The Gotchas

While working through this solution, there were a number of gotchas I encountered. Huge thanks to Ryan Lubke for holding my hand through them:

First, you should use subscribeToViewEvent, not subscribeToEvent. The latter will mean the event subscription itself get serialized into the component tree, so you'll keep doubling up subscribers every time the page refreshes.

Second, you must hook into UIViewRoot's PostAddToViewEvent, not UITestComponent's. This is because, at the time UITestComponent's PostAddToViewEvent is fired, its children will not be initialized yet.

Third, you cannot use the @ListenerFor annotation to hook into SystemEvents from a UIComponent. This is because UIComponent implements ComponentSystemEventListener, and @ListenerFor is designed to ignore the SystemEventListener interface for any class that implements ComponentSystemEventListener.


The Ugly

There is, unfortunately, still a problem for certain types of dynamic component.

If your component, in its processEvent method, dynamically creates not just simple HtmlInputText components but nested components that are themselves dynamic, we have a problem. This is because the 'official' way to safely manipulate the component tree is through SystemEvents, but there is no official way to safely manipulate the SystemEvent list.

In the current release of the JSF Reference Implementation (2.0.1), attempting to dynamically create a component that in turn tries to subscribe to a SystemEvent will get you a ConcurrentModificationException. In future releases, there will not be an exception but the newly added SystemEvent will simply not fire, so your newly added dynamic component will never get an opportunity to populate itself.

This new issue is being tracked by the JSF RI team. Until it is resolved, JSF 2 can safely create dynamic components (a big step forward), but it cannot safely create dynamic components that themselves create dynamic components.

Suggestions welcome!

Friday, October 30, 2009

XSL-FO number-columns-spanned="remainder"

Every so often when developing some XSL-FO I get the dreaded...

column-number or number of cells in the row overflows the number of fo:table-column specified for the table

...these tend to be a nightmare to track down, and very fiddly to fix, because often you need to add a number-columns-spanned attribute to one of the fo:table-cell elements, and in a dynamic world you have to figure out exactly how many cells to span. Agh!

It'd be much easier if XSL-FO let you just say number-columns-spanned="remainder". So today I wrote a little XSLT that you can put after your XSL-FO and before you try to serialize it (with something like Apache FOP).

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
            xmlns:fo="http://www.w3.org/1999/XSL/Format">

   <!-- number-columns-spanned: remainder -->
   
   <xsl:template match="fo:table-cell[@number-columns-spanned = 'remainder']" mode="#all">
   
      <xsl:copy>
         <xsl:attribute name="number-columns-spanned">
            <xsl:variable name="number-columns-in-table" as="xs:integer">
               <xsl:value-of select="count(ancestor::fo:table[1]/fo:table-column)"/>
            </xsl:variable>
            <xsl:variable name="number-columns-in-row" as="xs:integer">
               <xsl:value-of select="count(preceding-sibling::fo:table-cell[not(@number-columns-spanned)]) + count(following-sibling::fo:table-cell[not(@number-columns-spanned)])"/>
            </xsl:variable>
            <xsl:variable name="number-spanned-columns-in-row" as="xs:integer">
               <xsl:value-of select="sum(preceding-sibling::fo:table-cell[@number-columns-spanned ne 'remainder']/@number-columns-spanned) + sum(following-sibling::fo:table-cell[@number-columns-spanned ne 'remainder']/@number-columns-spanned)"/>
            </xsl:variable>
            <xsl:value-of select="$number-columns-in-table - $number-columns-in-row - $number-spanned-columns-in-row"/>
         </xsl:attribute>
         <xsl:apply-templates select="@*[not(local-name() = 'number-columns-spanned')]|node()"/>
      </xsl:copy>
      
   </xsl:template>


   <!-- identity transform -->
   
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

I should've done it years ago. Note unfortunately it won't work if you've got other rows that are using number-rows-spanned. Improvements welcome!

Thursday, October 15, 2009

User Interface Generator: Metawidget v0.85

Version 0.85 of Metawidget, the user interface generator, is now available! This release has something for everyone:

For first time users, we have updated and improved the User Guide. For intermediate users, we have greatly expanded the architecture documentation, with lots more diagrams and detailed explanations. And for advanced users, we have substantially refactored the internals, including introducing new pluggable WidgetProcessors to handle more demanding requirements. Please note there are unfortunately some breaking changes, as covered in the Migration Guide.

In addition we have improved our support for RichFaces (now includes SuggestionBox, TabPanel and RichPanel), ExtGWT (now includes Slider), Swing (now includes configurable labels), and have added XML schemas for every component and lots more unit tests.

Special thanks to Girolamo Violante and Illya Yalovyy for their help with this release!

As always, the best place to start is the Reference Documentation:

http://metawidget.org/doc/reference/en/pdf/metawidget.pdf

Your continued feedback is invaluable to us. Please download it and let us know what you think.

Friday, October 2, 2009

Metawidget 0.8 to 0.85 Migration Guide

The next release of Metawidget (v0.85, due in late October) will represent a significant refactoring of the Metawidget internals, aimed at increasing API clarity and consistency, code reuse, type safety and extensibility - all in preparation for our 1.0 release. As such, there will be a number of breaking changes.

We apologise for this disruption and provide this Migration Guide to help in moving from v0.8 to v0.85. All of the existing documentation and examples have already been migrated, as a reference point.

WidgetProcessors

The big new change is the concept of a 'widget processor'. These are lightweight, pluggable classes who can 'process' a widget just after its building (by the WidgetBuilder) and before it is laid out (by the Layout).


The interface is simply:

W processWidget( W widget, String elementName, Map<String, String> attributes, M metawidget )

This is great because:

  • It allows you to plug-in arbitrary processing of a widget without touching the Metawidget class itself. For example you could write a widget processor to add a tooltip to every component:

    JComponent processWidget( JComponent widget, String elementName, Map attributes, SwingMetawidget metawidget ) {
       widget.setToolTipText( attributes.get( NAME ));
       return widget;
    }

  • It provides more ways to identify and process a widget than getComponent( String... names ), for situations where you don't know the component's name in advance

  • It allows you to attach Event Handlers as inner classes that have connections to their parent class:

    final Object someObject = ...;

    metawidget.addWidgetProcessor( new BaseWidgetProcessor() {
    JComponent processWidget( JComponent widget, String elementName, Map<String, String> attributes, SwingMetawidget metawidget ) {
       ...decide whether to attach event handler...

       widget.add( new AbstractAction() {
          public void actionPerformed( ActionEvent event ) {
             someObject.doSomething();
          }
       }
    }
    }

  • Standardizing this concept allows us to refactor a lot of previously ad-hoc functionality. For example all binding and validation functionality are now implemented as widget processors:


    They can be chained together either programmatically or in metawidget.xml:

    <widgetProcessors>
       <list>
          <processor:requiredAttributeProcessor />
          <processor:immediateAttributeProcessor />
          <processor:standardBindingProcessor />
          <processor:readableIdProcessor />
          <processor:labelProcessor />
          <processor:standardValidatorProcessor />
          <processor:standardConverterProcessor />
       </list>
    </widgetProcessors>

Refactored save(), rebind(), validate()

As mentioned, binding and validation have now been refactored into WidgetProcessors. This has the advantage of moving methods such as save() and validate() out of the Metawidget (where they weren't always applicable) and into the responsible WidgetProcessor (where they will always be applicable, by definition).

This unfortunately means a slightly more cumbersome API. Instead of...

metawidget.save()

...you now have to do...

metawidget.getWidgetProcessor( BeansBindingProcessor.class ).save( metawidget )
...however we think the tradeoff is worth it.

metawidget.xml now supports (and mostly uses) <array>

ConfigReader now natively supports an <array> element. This allows it to natively call vararg methods, removing the need for some of the overloaded methods in the xxxConfig classes.

Most current usages of <list> should be replaced with <array>. Lists (and Sets) are still supported for your custom use-cases.

Refactored setCreateHiddenFields

JSF hidden field creation has also been refactored into a WidgetProcessor. For example:

<widgetProcessors>
   <list>
      <hiddenFieldProcessor />
   </list>
</widgetProcessors>

Layouts must now be immutable

Layouts are now a standardized part of the Metawidget pipeline. They must implement the new org.metawidget.layout.iface.Layout interface, and must be threadsafe and immutable just like Inspectors, WidgetBuilders and WidgetProcessors. Custom Layouts that are currently thread-unsafe or mutable need to be refactored in a couple of ways:

  • Configuration settings, that do not change over the lifetime of the Layout and would previously have been retrieved via metawidget.getParameter (and possibly saved into member variables), should now be configured by an external xxxConfig class. For example:

    public GridBagLayout() {
       this( new GridBagLayoutConfig() );
    }

    public GridBagLayout( GridBagLayoutConfig config ) {
       mNumberOfColumns = config.getNumberOfColumns();
       mLabelAlignment = config.getLabelAlignment();
       mSectionStyle = config.getSectionStyle();
       mLabelSuffix = config.getLabelSuffix();
       mRequiredAlignment = config.getRequiredAlignment();
       mRequiredText = config.getRequiredText();
    }

    ...and configured either programmatically or in metawidget.xml:

    <layout>
       <htmlTableLayout xmlns="java:org.metawidget.jsp.tagext.html.layout" config="HtmlTableLayoutConfig">
          <tableStyle>
             <string>aTableStyle</string>
          </tableStyle>
       </htmlTableLayout>
    </layout>

  • Internal state that changes during layout and was stored in member variables should now be stored in the parent Metawidget. For example:

    State state = (State) metawidget.getClientProperty( GridBagLayout.class );
    state.currentRow++;

No more metawidget.setParameter or m:param

The previously (type unsafe) metawidget.setParameter methods and m:param tags have now been removed, in favour of typesafe configuration objects on the WidgetProcessors and Layouts. So instead of...

metawidget.setPropertyBindingClass( BeansBinding.class )
metawidget.setParameter( "updateStrategy", UpdateStrategy.READ )

...you now do...

metawidget.addWidgetProcessor( new BeansBindingProcessor(
   new BeansBindingProcessorConfig()
      .setUpdateStrategy( UpdateStrategy.READ )));

...or equivalent in metawidget.xml.

ConfigReader Moved

ConfigReader has now been moved out of org.metawidget.inspector and into the new org.metawidget.config. This reflects it outgrowing its roots as a purely Inspector-focussed mechanism, into a general purpose way to configure Metawidgets.

XSDs

Existing XSDs have now been moved under http://metawidget.org/xsd. In addition, all the XSDs for the Inspectors, WidgetBuilders etc have been generated.

PropertyStyles and ActionStyles are now objects

ConfigReader is now smart enough to reuse PropertyStyle and ActionStyles instances between Inspectors. This means they are now specified on the Inspector as an object, not their class. This opens the door to people writing their own, configrable property styles if they need to.

Ant Build

The formerly monolithic build.xml has been split into several smaller ones. The original (/build.xml) now only builds Metawidget itself. There is a separate /examples/build.xml (builds examples), /test/build.xml (runs unit tests), /src/doc/build.xml (builds documentation) and /src/web/build.xml (builds Web site).

Similarly, the lib folder has now been split into /lib, /examples/lib and /test/lib.