JBoss Minimal Configuration Profile

Throughout the last three years and especially after publishing my post JBoss minimal configuration with Tomcat I’ve been asked many times what is actually the idea behind JBoss AS Minimal Configuration profile.

So what exactly you’ll get with following command?

	./run.sh -c minimal

As the name implies, minimal profile consists only from bare configuration set needed to start everything what makes JBoss AS – the microkernel itself. To benefit from its dynamic loading functionality, three services need to be started from JBoss AS code itself:

  • Service Controller to manage dependency and service lifecycle management
  • Main Deployer responsible for deployment process delegation
  • SAR Deployer that accepts JBoss Service Archives (SAR), both packaged and *-service.xml files for already loaded MBean classes.

Although this is enough to call the newly started java process ‘JBoss’, to make it usable, more is still required. From this point rest of the control is handed over to the main configuration file ./conf/jboss-service.xml (via SAR Deployer). Minimal profile has following services configured:

  • Logging service (log4j)
  • Basic Thread Pool
  • Naming service (JNDI)
  • Deployment scanner

As you can see, modulary developed from it’s bones, the JBoss server and all its services are implemented using the component-based approach. For version 4.X this effort is based on Java Management Extensions (JMX). Easy to use MBeans with extended lifecycle, dependency and injection support are registered to the MBean Server, which acts as invocation bus providing ideal decoupling of services.

Having minimal profile allows developers to start developing regular application with added benefit of dynamic redeployment. You can think about this functional set as an powerful application framework. Deployment scanner discovers new archives and Main/SAR deployers will deploy them. What else do we need?

For more information, please, check JBoss JMX Microkernel documentation.

Sounds interesting? It kind of does, but writing this at the end of the year 2008, we need a little bit more to get the right thrill.

And to have some is quite simple, because the long awaited release of JBoss AS 5.0 is going to stir the landscape of application framework market as we know it. Ignoring for now its Java EE 5 certification, the main change involves refactored kernel from it’s JMX origin to pure POJO development and deployment framework. JBoss Microcontainer – project behind the re-implementation – is not just a new backbone of the application server, but either as a standalone library for your application or used as part the JBoss AS minimal configuration profile, it delivers something the competitors are trying to produce for long time – completely modular POJO based application platform.

To see some of it’s features, including dynamic loading, Spring or Guice integration, OSGi support or seamless aspect configuration you can start with the first chapter of the User Guide (Draft) or review basics in the article A Look Inside JBoss Microcontainer from Javalobby.

JBoss minimal configuration with Tomcat (Servlet Contrainer)

For proof of concept I needed to deploy large number of servlet containers. Because I’m lazy and most of the code for main application has already been written for JBoss AS (including Login modules and set of custom services) I really didn’t want to use standalone Jetty or Tomcat. To use different solution for one part of deployment would create significant duplication of some functionality and unnecessary increased administration.Instead of cleaning-up default configuration, I decided to use for first time minimal configuration and add JBossWeb (manually). This is an overview of what has been required to achieve it.

First copy the configuration and create new profile.

    cd server/
    cp -R minimal webserver

Obviously you need to copy original JBoss Web deployer.

    cp -R ./default/deploy/jboss-web.deployer ./webserver/deploy/

And that’s where fun begins. By default JBoss Web relies on several JEE service that needs to be disabled. Edit file

    webserver/deploy/jboss-web.deployer/META-INF/jboss-service.xml

and comment out (delete) following dependencies on unnecessary services:

    <depends>jboss:service=TransactionManager</depends>
    <depends>jboss.jca:service=CachedConnectionManager</depends>

This is based on assumption you don’t need them. Once CachedConnectionManager is gone, you need to delete CachedConnectionValve from

    webserver/deploy/jboss-web.deployer/server.xml

Right now, your new webserver profile is stripped to it’s minimum and you have to add something. First necessary addsecurity related services into jboss-service.xml.

<!-- ==================================================================== -->
<!-- Security                                                             -->
<!-- ==================================================================== -->

<mbean code="org.jboss.security.plugins.SecurityConfig"
   name="jboss.security:service=SecurityConfig">
   <attribute name="LoginConfig">jboss.security:service=XMLLoginConfig</attribute>
</mbean>
<mbean code="org.jboss.security.auth.login.XMLLoginConfig"
   name="jboss.security:service=XMLLoginConfig">
   <attribute name="ConfigResource">login-config.xml</attribute>
</mbean>

<!-- JAAS security manager and realm mapping -->
<mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
   name="jboss.security:service=JaasSecurityManager">
   <attribute name="ServerMode">true</attribute>
   <attribute name="SecurityManagerClassName">org.jboss.security.plugins.JaasSecurityManager</attribute>
   <attribute name="DefaultUnauthenticatedPrincipal">anonymous</attribute>
   <attribute name="DefaultCacheTimeout">1800</attribute>
   <attribute name="DefaultCacheResolution">60</attribute>
   <attribute name="DeepCopySubjectMode">false</attribute>
</mbean>

Last remaining task is to copy additional JAR files and that’s it!

    cd default/lib/
    cp jboss.jar jboss-j2ee.jar jbosssx.jar servlet-api.jar jsp-api.jar jbossws* el-api.jar jboss-ejb3x.jar ../../webserver/lib

Back in bin folder you can test new configuration profile

    run -c webserver

Don’t expect miracles, you’ll get only what you configure. In this case is basic application server, with full support for customer services and webserver. To perform more tests you need to deploy some WAR file to deploy/ folder in order to get any output, as there are no context by default.This guide has been tested on JBoss AS 4.2.2

UPDATED. New post about details of JBoss Minimal is available.

AJP13 made easy with mod_proxy

For a long time mod_jk has been preferred Apache HTTPD plug-in that allowed integration with Tomcat’s JK connectors. It’s certainly perfect solution and still the recommended one for mission critical and highly loaded scenarios.

In case your setup is more relaxed and you looking to do first setup with AJP, there is another solution – mod_proxy. More precisely mod_proxy_ajp that provides ability of handling AJP 1.3 protocol. These modules are enjoying comeback since they have been rewritten for Apache HTTPD 2.2.

Main benefit behind using mod_proxy is the fact that most of the Apache HTTPD installations already come with this module precompiled. Very often not only with HTTP support, but AJP as well. In such a situation administrators feel more tempted to experiment with HTTP based load-balancing scenarios, and therefore more likely to experiment with different protocol.

Let’s have a look how sample configuration would look like:

# Enable Reverse Proxy
ProxyRequests Off

<Proxy balancer://mycluster>
        Order deny,allow
        Allow from all

        # loadfactor = worker load factor
        # route = jvmRoute appended to SESSIONID, reflecting setting in server.xml
        # min = minimum number of connections to backend server
        # max = maximum number of connections to backend server
        BalancerMember ajp://192.168.10.33:8009/ loadfactor=10 route=33 min=10 max=50 keepalive=On
        BalancerMember ajp://192.168.10.34:8009/ loadfactor=2 route=34 min=10 max=50 keepalive=On
</Proxy>

ProxyPass /proxy balancer://mycluster STICKYSESSION=JSESSIONID|jsessionid nofailover=On
ProxyPassReverse /proxy balancer://mycluster
ProxyPassReverseCookieDomain backend.server public.server

In this case two nodes are created to participate in load-balancer using AJP as connector to backend Tomcat; session affinity enabled with STICKSESSION configuration.

Overall the configuration corresponds with the one you would normally create using mod_jk. Now you’re probably asking what’s the catch. And answer is simple – you loosing dynamic options (periodic reload of mapping), only simplified balancing features and generally the performance is slightly behind mod_jk. My tests during last few months (both with experimental and production grade setups) show difference approximately about 6 – 7% drop down. Something not really worrying if you’re running medium sized intranet solution and you already need clustered solution, or if you just discovering world of load balancing.

For more information, please, check following resources:

Aggregation vs Composition

Not just while using UML, but in general object design discussions I’m often facing situation when somebody doesn’t really understand different ways how to design new objects. This blog post is my attempt to summarize the differences between aggregation and composition, and provide examples accompanied by UML diagrams. 

Answer for this confusion is in ownership. When composition is used the destruction of the object will result in destruction of it’s contained objects. When aggregation is used, this is not necessarily the case.As far as it’s only Java code concern, there is no difference what method you will use.

The significance of the need to distinguish them starts with introduction of mapping Java classes into other environments. Easiest example could be Hibernate mapping. Following POJO is not providing any information if aggregation or composition is used for homeAddress or department:

	class Employee {
		private Long id;
		private String name;
		private Department department;
		// ...
		private NextOfKin nextOfKin;
		// ...
	}

In this example department is obviously independent of the Employee class life cycle and therefore it’s aggregation, as the department will be there even when Employee record is not longer necessary. On other side it’s very unlikely nextOfKin will be referenced by any other component of the domain model, so it’s composition.Database design then could look like this:

Notice that department is referenced using foreign key, whereas next of kin is just component created using multiple columns from this table.When visualized using UML, only thing you have to remember is different in diamond representing association. Black diamond represent composition and white diamon aggregation. Example follows:

Hope this example will help.

Extending Seam Components

An important characteristic of every framework is a level of possible extensibility. JBoss Seam scores top marks in this perspective. Reason for it is simple. The main goal, to introduce consistent programming model that will make various frameworks to work together, is not just promoted for application developer, but also used through-out Seam itself. So with knowledge how to use component model and a quick insight behind the scene, you can easily start extending built-in components.

Mechanism you need to understand is component deployment process. Seam application start-up is triggered by the context listener which instantiates the Initialization object responsible for building configuration metadata. That is accomplished by collection of data from standard configuration files (WEB-INF/components.xml and deprecated WEB-INF/events.xml), configuration properties (supplied both from servlet context and file name seam.properties in the root of the classpath) and eventually by scanning archives in the application classpath for classes annotated with @Name which implies the Seam component.

Dependency Manager is then responsible for evaluation of component dependency to determine which components are to be installed.

And that’s the place where Seam utilizes another annotation – @Install. It does not only specify whether or not the component should be installed (this might be overridden by configuration files) and its dependencies, but also specifies precedence of the component. If two components with the same name are present, Dependency Manager will offer for installation only the one with higher precedence.

The precedence is specified integer value and following pre-defined constants are available:

  • BUILT_IN [0] used for built-in components
  • FRAMEWORK [10] to be used by frameworks which extend Seam
  • APPLICATION [20] default precedence, to be used by application components
  • DEPLOYMENT [30] used for overriding components for particular deployment
  • MOCK [40] for objects used in testing

Further control over the components deployment process is provided by following two annotations:

  • @BypassInterceptors which disables all Seam interceptors on particular class or method.
  • @Startup to control initialization of component depending of scope its available in

With this overview you’re ready to extend any provided component, either Seam built-in or available within 3rd party framework or application.

Extending Identity object

As example I’ll show you how to extend built-in identity object to support custom JAAS Login Module that requires custom callback handler to be used to obtain/provide further information. This particular implementation adds functionality to support NTLM as other authentication method (together with customized jCIFS library) and NTLM support iself is not part of this code snapshot.


@Name("org.jboss.seam.security.identity")
@Scope(SESSION)
@Install(precedence = APPLICATION)
@BypassInterceptors
@Startup
public class NTLMIdentity extends Identity {

  //
  // custom code
  //

  @Override
  public String login() {
    try {
       retrieveNTLMAuthenticationDetails();
    } catch (LoginException le) {
       log.error("Unable to retrieve NTLM authentication details!", le);
       return null;
    }
  }

  @Override
  protected CallbackHandler getDefaultCallbackHandler() {
     return new CallbackHandler() {
       public void handle(Callback[] callbacks)
          throws IOException, UnsupportedCallbackException {
          for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof NameCallback) {
              ((NameCallback) callbacks[i]).setName(getUsername());
            } else if (callbacks[i] instanceof PasswordCallback) {
              ((PasswordCallback) callbacks[i]).setPassword(getPassword() != null ?
                  getPassword().toCharArray() : null);
            } else if (callbacks[i] instanceof SFSIdentityCallbackHandler) {
               processSFSCallbackHandler((SFSIdentityCallbackHandler) callbacks[i]);
            } else {
               throw new UnsupportedCallbackException(callbacks[i], "Unsupported callback");
            }
         }
       }
     };
   }

   //
   // custom code
   //
  }

Where @Name is specified to override Seam built-in Identity component, and precedence set higher than BUILT_IN. If you run application, the result of #{identity} and Identity.instance() will always be NTLMIdentity object.

Running multiple instance of JBoss AS

Either setting up clustered environment for development/testing, need to isolate different application, or necessity of running different version of JBoss AS on the same machine. No matter what is the reason for running multiple instances of JBoss AS, for most users it’s quite a daunting task. Most common technique how to achieve it is complicated manual change of all ports numbers to be different. But what to do during upgrade? Do you really want to go through it all over again?

Read More »

Dual MF Film Holder for Epson V750

I love my Epson V750. It’s a remarkable scanner with price tag that won’t ruin your budget. For a little bit over £500 you can’t get anything better. With one exception, the original film holders are difficult too
use and way to flimsy for scanner’s professional ambitions. Luckily, there is a solution for this problem – Dual MF Film Holder (120/200) from betterscanning.com.

After superb communication with Doug Fisher, I expected to wait eight days for new parts to arrive as recent huge demand depleted his inventory of components. Exactly as promised, nine days later I received shipment details and not very long afterwards Royal Mail delivered my new film holder and ANR Insert.

I won’t exaggerate if I say the film holder is everything I was hoping for. Its solid and very well made construction is easy to use. T-Lock insert system provides necessary support to keep film almost perfectly flat.

Many users of V700/V750 scanners reported unsatisfactory quality of scans. Unlike dedicated models there is no option to adjust and focus the scanner’s internal lenses. That may result in lack of sharpness in the final image. Original holder provides height adjusters to change default height between the film holder and document table for about 1mm.

Doug Fisher’s Dual MF Film Holder allows highly improved adjustment. I haven’t tried the maximum height you can achieve, as the optimum height for my scanners is between 1.6 and 1.8 mm. Although the process requires a bit of patience, it’s still pretty easy and once you get your focus right you’ll be rewarded by adequate sharpness.

Well, I can continue going through the rest of the features, but it will be just repeating what is already written on the original pages for this fantastic product. I haven’t got chance to try ANR Insert, but expecting it to be perfect for longer panoramic film.

If you have V700/V750 and scanning 120 films, don’t wait and get one. You won’t regret it. Only thing I can do is to express thanks once more again to Doug Fisher for very smooth transaction and perfect product