blog.smart-java.nl
Ordina J-Technologies – Java Blog

Archief ‘Middleware’ categorie




Websphere classloading issues

Door: Sander Abbink, 18 September 2009

Most of us who deploy on Websphere have at some point encountered classloading issues. Websphere provides a lot of libraries which are loaded by default (parent first) before the libraries supplied by the application. IBM explains the classloading order on this site:
http://www.ibm.com/developerworks/websphere/library/techarticles/0112_deboer/deboer.html

At my current position some Websphere installations have installed feature packs while others have not. You can view which feature packs are installed by running:
versionInfo.bat/sh from the Profile directory (e.g.: /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/bin).
This can also cause version mismatches.

The following examples are from Websphere 6.1

Viewing classloader order:
You can view the order in which the libraries are loaded by following these links in the admin console:
Enterprise Applications > [ear module] > Manage Modules > [ war module] -> view module classloader.

You can expand the tree or export the contents of the Classloader viewer to a XML-file. Here you can easily tell if a library is provided by Websphere or your application.

Changing classloader order:
To change the classloading order follow the following link:
Enterprise Applications > [ear module] > Class loader

You can set the value of Class loader order to parent-last or application-first (depends on Websphere version) to make sure the jar-files of your application are loaded first. If the jar-files are also present in WEB-INF/lib you can alter the setting in:
Enterprise Applications >[ear module] > Manage Modules > [war module] (again parent-last or application-first)

If you cannot change these settings and you are deploying through WTP then you must change the file: application.xml.  You can enter these settings at the deployment tab (maybe only in RAD?)

Creating your own classloader
Another way of preventing Websphere to load its own libraries first is to use a shared library.Jar-files in the shared-library are automatically placed on the classpath. You can create a special classloader to make sure certain libraries are loaded before anything else:

Application servers > server1 > Class loader

Select ‘new classloader’ and choose ‘Classes loaded with application class loader first’. After you have created this classloader you can attach your shared library to this loader.  After this you can restart your application server for these changes to take effect. For me this is the cleanest solution but remember this affects all applications deployed on the server. The benefit is that you can change the classloading order on a per-library basis i.s.o. changing the order for all the libraries in the application.




Getting on the cloud!

Door: Roy van Rijn, 5 June 2009

Google App Engine

You’ve probably heard people talking before about ‘cloud computing’.
But what exacly is this cloud computing you might ask?

To figure this out I decided to create my own Google App Engine project and find out about cloud computing along the way.

Wikipedia states that cloud computing is:

Cloud computing is a style of computing in which dynamically scalable and often virtualized resources are provided as a service over the Internet. Users need not have knowledge of, expertise in, or control over the technology infrastructure in the “cloud” that supports them”

So, cloud computing doesn’t only have a vague name, the description isn’t very helpful either. But the key ingredients are “scalable” and “virtualized” and “as a service”. And you don’t have control over the infrastructure…

Lets take a look at Google App Engine. It was released in April 2008 as a platform for developing (Python)cloud applications. App Engine hosts these applications virtually on many machines, the programs are distributed and scaled across a vast amount of servers. And now, since the beginning of this year Google App Engine also supports Java!

The concept is simple, you get to build an application, preferably using Google’s App Engine-eclipse-plugin. And the JRE you build on is a slightly stripped-down version to make it usable on a cloud, like a sandbox.

Because you don’t know on what kind of servers your application will run on, or on how many servers, Google has decided you can’t do the following:

  • Start threads
  • Go to the Filesystem, no I/O
  • Open sockets directly, but you can open connections through HTTP/HTTPS
  • Make calls to System (like exit();, gc(); etc)

And there is more. Because of these restrictions you can’t access a database! So you can’t use something like Hibernate and some Oracle/MySQL/Postgress machine. To still be able to save/persist objects Google has teamed up with Datanucleus. Using JDO or (a stripped down version of) JPA you can persist and retrieve objects on the cloud.

With this in mind I started making my own application. And the frameworks I wanted to use are:

  • Wicket (Web Framework)
  • Spring IOC
  • Spring ORM (for transaction management, using annotations)
  • JPA (instead of the default JDO)

The first problems I encountered was getting Wicket to load. Because of the sandbox-restrictions there are a couple of things you can’t do. For example, Wicket can’t save temporary data to disk (what it normally does). And there are problems with Wicket being in ‘development-mode’ where is wants to start Threads to poll for changed resources.

A good overview on what it takes to get Wicket working is explained here:
http://www.danwalmsley.com/2009/04/08/apache-wicket-on-google-app-engine-for-java/

Next up was installing and running Spring. This was relatively easy at first. The core Spring code ran pretty much as expected. I added the JARs to my project and added this to the web.xml:

	<!-- Spring -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationcontext-*.xml</param-value>
	</context-param>
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>
	<listener>
		<listener-class>
			org.springframework.web.context.request.RequestContextListener
		</listener-class>
	</listener>

As you can see, I load up multiple XML files. I decided to go with the all-out-annotations method using Spring ORM. This proved to be pretty challenging…

With these annotations you are able to do the following in the code:

@Repository("loginDao")
@Transactional
public class LoginDaoImpl implements LoginDao {
 
	@PersistenceContext
	private EntityManager entityManager;
	... (and more)

As you can see I’m using Spring to inject my EntityManager into the DAO. But you can’t just load the entity manager in Google App Engine, you need a specific piece of configuration. I used the following XML:

	<bean id="data.emf"
		class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="transactions-optional" />
	</bean>

	<bean class="org.springframework.orm.jpa.JpaTemplate">
		<property name="entityManagerFactory" ref="data.emf" />
	</bean>

	<bean id="transactionManager"
		class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="data.emf" />
	</bean>

To tell Spring to scan for these annotations you need to add the following lines in your applicationcontext:

	<context:annotation-config />
	<context:component-scan base-package="nl.redcode.*" />

And now the problems start… The first problem is that Google App Engine doesn’t support all core classes. When loading these annotations Spring will load its PersistenceAnnotationBeanPostProcessor. But it contains the following piece of code:

try {
	return (EntityManagerFactory) lookup(jndiName, EntityManagerFactory.class);
}
catch (NamingException ex) {
	throw new IllegalStateException("Could not obtain 
		EntityManagerFactory [" + jndiName + "]from JNDI", ex);
}

And the Exception we get is:

org.springframework.beans.factory.BeanCreationException: Error creating
bean with name
'org.springframework.context.annotation.internalPersistenceAnnotationProcessor':
Initialization of bean failed; nested exception is
java.lang.NoClassDefFoundError: javax/naming/NamingException
	at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
	at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
	at java.security.AccessController.doPrivileged(Native Method)
	at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
	at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
	at
...etc

And when I looked at the white-list it was clear, NamingException isn’t part of the sandbox Google App Engine uses. So I started to google how to solve this. The first thing I encoutered was somebody who added the following lines to his/her applicationContext:

	<bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
		class="java.lang.String" />

This piece of code, when executed before the annotation-scan, loads a String in the Spring Container under the name “internalPersistenceAnnotationProcessor”. This causes Spring to ignore its own instantiation of the PersistenceAnnotationBeanPostProcessor and we don’t get the Exception anymore.

But this causes some more damage we don’t want in the application. Before my Dao’s received a valid EntityManager, but they are Null now…!

So I took the code of the original Spring PersistenceAnnotationBeanPostProcessor and replaced all the instances of NamingException with just Exception. This removed the dependency to NamingException. I called this new bean “AppEngineJPAPostProcessor”. This is how I configured it in the applicationContext:

	<bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
		class="nl.redcode.springhack.AppEngineJPAPostProcessor" />

The EntityManager(Factory) is now created, it gets injected into the DAO’s, they have transactions using annotations and everybody is happy!

When I got a little further in my project I decided to deploy my application to the cloud and test it online. Deploying your application to App Engine is very simple, just push the “Deploy” button in the Eclipse plugin and you only need to enter your credentials and a version-number of your release!

But then the old BeanPostProcessor bit me in the back again. On the server I got the following Exception when deploying:

java.lang.SecurityException: Unable to get members for class org.springframework.jndi.JndiLocatorSupport
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:357)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:347)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getMembers(Class_.java:347)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getDeclaredMethods(Class_.java:174)
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:460)
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:443)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:299)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(AutowiredAnnotationBeanPostProcessor.java:179)

It seems the runtime is a bit more strict then the development server Google App Engine uses. For some reason it doesn’t like the JndiLocatorSupport. This is excepted because Google App Engine, due to the nature of the cloud, prohibits the use of JNDI.

Soon I found the problem, the only reference to JndiLocatorSupport is my own BeanPostProcessor:

/**
 * Rewritten for use in Google AppEngine
 *
 * @author Roy van Rijn
 */
public class AppEngineJPAPostProcessor extends JndiLocatorSupport implements
		InstantiationAwareBeanPostProcessor, BeanFactoryAware {
 
	private Map persistenceUnits;
	...

When I removed the ‘extends’ part there were two pieces of code that stopped working, they both look like this:

	try {
	return (EntityManagerFactory) lookup(jndiName, EntityManagerFactory.class);
}

It seems this PostProcessor always does a JNDI lookup to find the correct EntityManager! But we can’t do this if we don’t have access to the JndiLocatorSupport methods anymore. So I decided to hack a little bit in this code, my solution was to load the EntityManagerFactory and EntityManager from the Spring container:

try {
	return ((JpaTransactionManager)beanFactory
		.getBean("transactionManager"))
		.getEntityManagerFactory();
/*	return (EntityManagerFactory) lookup(jndiName,
		EntityManagerFactory.class);*/
} catch (Exception ex) {
...

This solved all the problems and with the changes to the BeanPostProcessor I’m now able to use all the Spring annotations, for persistency and transactions, in Google AppEngine.

I’m now still in the middle of developing my application on Google App Engine, but it seems that Google App Engine works like a charm. The problem is, most frameworks can’t really cope with the sandbox out-of-the-box. But with (some) minor patches and tweaking most frameworks will run using Google App Engine. The only major problem I’m having (which can’t be solved) is Datanucleus. I chose to use JPA because it is much richer and has more features then JDO, but Datanucleus hasn’t implemented much of these features yet.

For example, I had the following annotation on a field: @Column(unique=true)
Datanucleus threw “java.lang.UnsupportedOperationException: No support for uniqueness
constraints
“.

Also, I created a query with this: “username = :username OR emailAddress = :emailAddress
But Datanucleus doesn’t support the operator “OR”.

Other things DataNucleus can’t currently do:

  • Many-to-many relationships
  • Joins in a query (WHAT??)
  • Aggregation queries (group by, having, sum, avg, max, min)
  • Polymorphic queries. You cannot perform a query of a class to get instances of a subclass. Each class is represented by a separate entity kind in the datastore.

So, we’ve seen what a cloud is, what Google App Engine is, and I explained some tweaks/patches needed to get Wicket and Spring working.

Why use Google App Engine? It is free (up to some CPU/mail/data limits) and your project runs on a cloud, and thus is very scalable. You don’t have to worry about the environment or server. Your application will scale when its needed and everything is pre-installed and ready to run.
But be prepared for difficult classloading issues and missing classes. You just can’t expect all frameworks to be working out-of-the-box with the sandbox-limitations. Also don’t expect much support with persisting, the JPA-support is very minimal and won’t let you do much more then persisting and retrieving single objects.

Enough blogging, now its time for me again to tinker on my application, maybe I’ll tell about it here in the future!




JBoss komt (te laat?) met de eerste Release Candidate van AS5.0

Door: Martijn Blankestijn, 10 July 2008

Eindelijk dan weer eens een geluid uit het JBoss kamp bij het vrijgeven van de Release Candidate 1 van hun applicatieserver versie 5.0. Uit het artikel worden allemaal redenen genoemd, waarom de huidige versie zo vertraagd is: een complete refactoring, modularisering en toekomstvisie zijn kort door de bocht de aangedragen redenen.

De vraag is alleen of JBoss niet gewoon te laat is en te lang niets van zich heeft laten horen. Ruim anderhalf jaar om van een eerste beta tot een release candidate te komen is wel wat veel van het goede. Andere open-source applicatieservers hebben in de tussentijd druk aan de weg getimmerd. Denk hierbij aan onder andere Glassfish, dat ten tijde van de eerste beta nog maar een paar maanden gereleased was.

Hopelijk zal na inspectie van de applicatieserver blijken dat ze zich eindelijk hebben gericht op iets wat ze in mijn ogen duidelijk hebben laten liggen. En dat is de ondersteuning van systeembeheer. Ben benieuwd of die af zijn van configuratie-geneuzel in xml-files of op andere technologisch uitdagende manieren de applicatieserver mogen configureren af zijn.

Wie denkt dat JBoss in deze de boot heeft gemist?




Webservices over MQ (2)

Door: Jethro Bakker, 5 June 2008

Een tweede deel over het gebruik van Spring Webservices en JMS transport.

Ons uitgangspunt is dat er meerdere type berichten (SOAP, POX) binnen komen op dezelfde queue. In een grote organisatie is het voordeel hiervan dat je maar 1x een queue hoeft aan te vragen en daar alle berichten op zet. Eventuele nieuwe berichtsoorten kunnen dan vrij gemakkelijk toegevoegd worden. Nadeel is dat we meerdere type berichten moeten kunnen afhandelen. Een uitdaging om dit efficient en met zoveel mogelijk bestaande code te kunnen doen. We willen namelijk zo min mogelijk infrastructuur code schrijven.

Standaard biedt Spring Webservices een WebServiceMessageListener aan die je kunt gebruiken om berichten te consumeren van de queue. Deze listener ondersteunt een type bericht. Je kunt namelijk maar een message factory definieeren op een WebserviceMessageListener.

In eerste instantie had ik daar een oplossing voor bedacht die er als volgt uit ziet:

class MyWebserviceMessageListener extends WebServiceMessageListener {
  private PoxMessageFactory poxMessageFactory;
  private SaajSoapMessageFactory soapMessageFactory;

  public void onMessage(Message message, Session session) {
    if ("applicatie1".equals(message.getStringAttribute("afzender"))) {
      setMessageFactory(poxMessageFactory);
    } else {
      setMessageFactory(soapMessageFactory);
    }
  }
}

Afhankelijk van een attribuut van het JMS bericht wordt besloten welke message factory gebruikt wordt. Bovenstaande code blijkt niet te werken omdat de WebServiceMessageListener initieel een message factory nodig heeft. Maar het gaat me nu even om het idee. Waarom is het niet verstandig dit zo op te lossen?

Een message driven pojo (MDP), zoals de MyWebserviceMessageListener, draait in een container. (DefaultMessageListenerContainer) Op deze container kun je het aantal consumers instellen. Bijvoorbeeld 3 of 10. Je kunt dit doen door de properties: maxConcurrentConsumers en concurrentConsumers te gebruiken. Zoals de namen van de properties al aangeven hebben we hier te maken met concurrency en onze MDP moet daarom thread safe zijn! In de referentie documentatie staat dat ook heel duidelijk:

Please also be aware that in the case where your POJO will be receiving messages on multiple threads, it is important to ensure that your implementation is thread-safe.

De oplossing zoals hier boven beschreven is niet thread safe en kan de prullenbak in omdat we meerdere concurrent consumers gaan gebruiken. De oplossing is niet thread safe omdat meerdere threads gebruik maken van dezelfde MDP. Er kunnen dus twee threads actief zijn en tegelijk een bericht verwerken. De ene thread een SOAP bericht en de andere een POX bericht. Dan gaat een van beide threads de mist in omdat het een verkeerde message factory gebruikt.

We zullen op basis van de bericht inhoud moeten beslissen of het bericht een SOAP bericht is of een standaard XML bericht. Dit doen we door de message factories in de MDP te verwijderen en te vervangen door twee JMSMessageReceivers die we zelf moeten schrijven. Zo’n receiver heeft een dependency op een message factory. In de MDP beslissen we nu naar welke receiver we gaan op basis van de bericht inhoud.

Een JMSMessageReceiver is een:

Convenience base class for JMS server-side transport objects. Contains a WebServiceMessageReceiver, and has methods for handling incoming JMS BytesMessage and TextMessage requests. Also contains a textMessageEncoding property, which determines the encoding used to read from and write to TextMessages. This property defaults to UTF-8.

Voorbeeld:

public class PoxJmsReceiver extends JmsMessageReceiver {
    public void invoke(Message message, Session session) throws JMSException {
        try {
            handleMessage(message, session);
        } catch (Exception ex) {
            JMSException jmsException = new JMSException(ex.getMessage());
            jmsException.setLinkedException(ex);
            throw jmsException;
        } 

    }
}

Deze oplossing heeft als nadeel dat het bericht twee keer gelezen wordt. Een keer in de MDP om te checken of het SOAP bericht is en een keer in het Spring Webservices framework. Bij kleine berichten maakt dit niet zoveel uit maar bij grote berichten kan dit geheugen problemen gaan geven. Een mogelijke oplossing voor dit probleem is om de eerste zoveel bytes van het bericht in te lezen in de MDP en op basis daarvan te besluiten of het een SOAP bericht is. Andere ideeen zijn uiteraard welkom.




Webservices over MQ

Door: Jethro Bakker, 8 May 2008

In een vorig project heb ik kennis gemaakt met het Spring Webservices framework. Met dit framework is het eenvoudig om een POJO als webservice beschikbaar te stellen over HTTP. In versie 1.5 is er ondersteuning toegevoegd voor MQ en SMTP. Hoe werkt dat?

Je definieert allereerst een DefaultMessageListenerContainer. De container heeft o.a. een connection factory en een destination als parameter. Daarnaast geeft je een messageListener op:

<property name="messageListener">
  <bean class="org.springframework.ws.transport.jms.WebServiceMessageListener">
    <property name="messageFactory" ref="messageFactory"></property>
    <property name="messageReceiver" ref="messageDispatcher"></property>
  </bean>
</property>

De WebServiceMessageListener komt zoals je ziet uit het Spring Webservices framework en heeft twee parameters, een message factory en een dispatcher.

Message Factory
De message factory kan bijvoorbeeld een SoapMessageFactory zijn. In ons geval niet want we gebruiken geen SOAP maar Plain Old XML (POX). Spring Webservices biedt hiervoor een DomPoxMessageFactory. Zoals de naam al aangeeft is deze implementatie gebaseerd op een DOM XML parser. Bij grote documenten kan dit veel geheugen opslokken. Mijn voorkeur gaat daarom uit naar Stax of Sax implementatie. Helaas zijn deze niet out of the box beschikbaar. Daarom heb ik er zelf eentje geschreven. De StaxMessageFactory implementeert de interface WebServiceMessageFactory. Deze interface bevat twee methoden om een WebServiceMessage te creeeren. Een methode creeert een leeg bericht en de andere een bericht op basis van een InputStream.

Message Dispatcher & Endpoint Mappings
De message dispatcher wordt wel out of the box geleverd. De dispatcher bevat een lijst van endpoint mappings. Voorbeelden van endpoint mappins zijn:
SoapActionEndpointMapping – dispatchen op basis van Soap Action
PayloadRootQNameEndpointMapping – dispatchen op basis van root XML element

De klant waar ik voor werkzaam ben heeft een specifieke wens. Er moet gedispatcht worden op basis van een attribuut van het root element. Hiervoor moet er zelf een EndpointMapping geschreven worden. Dat is gelukkig heel eenvoudig. Op basis van de AbstractMapBasedEndpointMapping kun je snel je eigen implementatie schrijven. Deze klasse dwingt af dat je twee methoden implementeert: validateLookupKey en getLookupKeyForMessage. Uiteindelijk configureer je het als volgt in Spring.

<bean id="endpointMapping" class="*MyOwnEndpointMapping">
  <property name="rootElementName" value="MyMessage"></property>
  <property name="rootAttributeName" value="MyAttribute"></property>
  <property name="mappings">
  <props>
    <prop key="A">EndpointA</prop>
    <prop key="B">EndpointB</prop>
    <prop key="C">EndpointC</prop>
  </props>
</property>
</bean>

De MyOwnEndpointMapping is nog te configureren met twee extra parameters: rootElementName en rootAttributeName. Deze parameters worden gebruikt om het attribuut te selecteren en te controleren of de root element naam klopt.De endpoints die we gebruiken overerven van AbstractMarshallingPayloadEndpoint omdat we Castor gebruiken om objecten te marshallen. Een voorbeeld van een endpoint:

public class EndpointC extends AbstractMarshallingPayloadEndpoint {
  public EndpointC(Marshaller marshaller) {
    super(marshaller);
  }
 
  public Object invokeInternal(Object request) {
    MyObject myObject = (MyObject) request;
    return myObject;
  }
}

Het aardige van deze aanpak is dat het niet uitmaakt voor de onderliggende implementatie welk transport mechanisme je gebruikt. Daarnaast is het ook niet van belang wat voor Marshaller er gebruikt wordt. Castor, JAXB het maakt voor de onderliggende implementatie niet uit. Hierdoor zijn de Endpoints makkelijk te unittesten en ook eenvoudig.

Door deze aanpak krijgen we nu ook functionaliteit cadeau. Bijvoorbeeld validatie en log functionaliteit. Door middel van interceptors kan dit eenvoudig ingeregeld worden. Aan de MyOwnEndpointMapping voeg je een property interceptors toe:

  <property name="interceptors">
    <list>
      <ref bean="loggingInterceptor" />
    </list>
  </property>
  ...
  <bean id="loggingInterceptor" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />

Mocht in de toekomst toch SOAP gebruikt gaan worden dan is dit eenvoudig aan te passen door een andere message factory te gebruiken. De endpoint mapping zal dan ook aangepast moeten worden.