17 April 2012

Quick trick: solving an MDB deploy problem on WebLogic

Quick trick about a problem I've faced deploying a Message Driven Bean on BEA WebLogic: MDB's configuration in ejb-jar.xml contained this snippet:

<message-driven>
    <ejb-name>MyEjb</ejb-name>
    <ejb-class>com.my.domain.MyEjbBean</ejb-class>
    <transaction-type>Container</transaction-type>
    <message-driven-destination>
        <destination-type>javax.jms.Queue</destination-type>
    </message-driven-destination>                       
    <acknowledge-mode>auto_acknowledge</acknowledge-mode>
</message-driven>


This configuration worked well on JBoss 4, but causes causes an exception during deployment phase on BEA WebLogic 10:


Caused By: 
org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager
 at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:371)
 at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1341)
 at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
 at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
 at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:132)
 at weblogic.deployment.PersistenceUnitInfoImpl.createEntityManagerFactory(PersistenceUnitInfoImpl.java:355)
 at weblogic.deployment.PersistenceUnitInfoImpl.createEntityManagerFactory(PersistenceUnitInfoImpl.java:333)
 at weblogic.deployment.PersistenceUnitInfoImpl.<init>(PersistenceUnitInfoImpl.java:135)
 at weblogic.deployment.AbstractPersistenceUnitRegistry.storeDescriptors(AbstractPersistenceUnitRegistry.java:336)
 at weblogic.deployment.EarPersistenceUnitRegistry.initialize(EarPersistenceUnitRegistry.java:77)
 at weblogic.application.internal.flow.InitJpaFlow.prepare(InitJpaFlow.java:38)
 at weblogic.application.internal.BaseDeployment$1.next(BaseDeployment.java:1223)
 at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:41)
 at weblogic.application.internal.BaseDeployment.prepare(BaseDeployment.java:367)
 at weblogic.application.internal.EarDeployment.prepare(EarDeployment.java:58)
 at weblogic.application.internal.DeploymentStateChecker.prepare(DeploymentStateChecker.java:154)
 at weblogic.deploy.internal.targetserver.AppContainerInvoker.prepare(AppContainerInvoker.java:60)
 at weblogic.deploy.internal.targetserver.operations.ActivateOperation.createAndPrepareContainer(ActivateOperation.java:208)
 at weblogic.deploy.internal.targetserver.operations.ActivateOperation.doPrepare(ActivateOperation.java:98)
 at weblogic.deploy.internal.targetserver.operations.AbstractOperation.prepare(AbstractOperation.java:217)
 at weblogic.deploy.internal.targetserver.DeploymentManager.handleDeploymentPrepare(DeploymentManager.java:749)
 at weblogic.deploy.internal.targetserver.DeploymentManager.prepareDeploymentList(DeploymentManager.java:1216)
 at weblogic.deploy.internal.targetserver.DeploymentManager.handlePrepare(DeploymentManager.java:250)
 at weblogic.deploy.internal.targetserver.DeploymentServiceDispatcher.prepare(DeploymentServiceDispatcher.java:160)
 at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer.doPrepareCallback(DeploymentReceiverCallbackDeliverer.java:171)
 at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer.access$000(DeploymentReceiverCallbackDeliverer.java:13)
 at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer$1.run(DeploymentReceiverCallbackDeliverer.java:47)
 at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:528)
 at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
 at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)


The problem was the presence of <acknowledge-mode> tag: this has no effect when <transaction-type> is Container (in this case messages ACK coincides with transaction commit). On JBoss the <acknowledge-mode> tag is ignored, but WebLogic validate configuration and raises an Exception when its presence is meaningless.
Removing the tag solved the problem.

13 April 2012

How-to find a class in a JAR directory using shell scripting

The biggest problems in J2EE applications deployment  come often from classloader hierarchies and potential overlapping between server-provided and application-specific libraries. So, searching classes through collection of JARs is oftwen the main activity in order to identifiy and fix classloader issues.
This is surely a tedious and repetitive task: so, here's a shell script you can use to automate JAR collection traversing and tar command's output analysis to search a pattern, which is provided as script parameter.

Credits: Thanks to sirowain for parameter check and return code related contributions.

#!/bin/bash
# Commonly available under GPL 3 license
# Copyleft Pietro Martinelli - javapeanuts.blogspot.com
if [ -z $1 ]
then
        echo "Usage: $0 <pattern>"
        echo "tar xf's output will be tested against provided <pattern> in order\
          to select matching JARs"
        exit 1
else
        jarsFound=""
        for file in $(find . -name "*.jar"); do
                echo "Processing file ${file} ..."
                out=$(jar tf ${file} | grep ${1})
                if [ "${out}" != "" ]
                then
                        echo "  Found '${1}' in JAR file ${file}"
                        jarsFound="${jarsFound} ${file}"
                fi
        done
        echo "${jarsFound}"
        
        echo ""
        echo "Search result:"
        echo "" 
        
        if [ "${jarsFound}" != "" ]
        then
                echo "${1} found in"
                for file in ${jarsFound}
                do
                        echo "- ${file}"
                done
        else
                echo "${1} not found"
        fi
        exit 0
fi

This script is available on github.com:

12 April 2012

grepcode!

grepcode is a very useful web site that allows opensource code reading and navigation in user friendly fashion: it's e.g. very convenient to compare different version of an opensource class to investigate about bugs and their resolution, but to simply navigate through code when no sources' jars in maven repositories are available, too.
And... the search engine look for classes, by name, across all the available packages...

I like it!