24 May 2012

Eloquent JavaScript - An opinionate guide to programming

Eloquent JavaScript - An opinionate guide to programming - Marijn Haverbeke, 2011

Interesting and useful guide to Javascript, whose "opinionate" approach can reconcile with this loved-heated language. I found extremely interesting the sections about functional programming and object oriented programming: finally I've found a systematic presentation of OOP in Javascript!

21 May 2012

How to automatically test Java Console

Some weeks ago, during a workroom lesson in University, I've faced a typical TDD-addicted dilemma: how can I test driven develop a console-based Java application?
The main problem is clearly how to automatically interact with the application, which relies to System.in for user input and to System.out for user output.
You can use System.setIn and System.setOut methods, of course: but this is IMHO a dirty solution to the console-interaction testability problem, which can be resolved in a cleaner way referring to the dependency inversion principle, ubiquitous in test driven design: rather than directly referring to concrete System.in and System.out streams (this reference is concrete because it's direct, not because it points to a concrete class: InputStream is really an abstract class), the console-based application should reference to some abstraction that encapsulates standard I/O streams dependency - for example to Scanner (for user input) and PrintStream (for user ouput: again, direct reference to System.out is concrete because it's direct, not because it points to something concrete).
So, application behaviour can be encapsulated into a classe having a constructor like this:
 
public HelloApp(Scanner scanner, PrintStream out)

The application main method instances such a class and invokes a method thar triggers application logic execution, simply providing Scanner and PrintStream that wrap standard I/O streams:

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        scanner.useDelimiter(System.getProperty("line.separator"));
        
        HelloApp app = new HelloApp(scanner, System.out);
        app.run();
}

Testing code, however, can provide to HelloApp testing oriented instances of Scanner and PrintStream:

final Scanner scanner = new Scanner("Duke y Goofy y Donald n");
scanner.useDelimiter(" "); 
 
ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream();
PrintStream out = new PrintStream(outputBuffer); 
 
final HelloApp app = new HelloApp(scanner, out);
app.run();
 
final String output = outputBuffer.toString(); 
// Assertions about outputBuffer content:
assertTrue(output.startsWith("Welcome to HelloApp!")); 

So, we have gracefully decoupled application logic from console-based user interactions, providing a solid framework for automated application testing and, even more satisfying for TDD addicted, for Test Driven Development.


Code repository can be cloned using git:
git clone https://bitbucket.org/pietrom/automatically-testing-the-console.git

16 May 2012

JNDI name duplication problem chez WebSphere

Yesterday a colleague and I have faced a subtle problem deploying a suite of enterprise applications on WebSphere Application Server - version 6.1.
The problem manifested itself with a marshalling error when a webapp called a service exposed as an EJB in the same enterprise application: this was very annoying due to two main aspects:
  1. there was no duplication, between webapp and EJB module, fot the classes involved in the call
  2. the issue seemed to occur randomly: not for all calls (and never for some), not always for the same call (apparently depending to application restart)
After a few hours of stop-and-start-and-read-the-log nightmare, we discovered that at the root of the problem was a JNDI name duplication between EJBs published by two different applications of the suite: these applications are based on the same infrastructural framework, and the framework published some framework services using a fixed JNDI name. This was clearly an error in suite packaging, but... WebSphere did not report in any way this name collision, deployed without errors nor warnings both the applications, and the duplicated JNDI name was associated with an implementation of the service or with the other, depending to starting order of the apps. So:
  1. the marshalling problem appeared when the webapp from an EAR called the service published by the other application
  2. the issue occurred only for the EJB with the duplicated name, not for the others; and coccurred or did not depending to the starting order
The solution was quite simple: changing the JNDI name of  one of the twins services.
But... why the application server did not give any error when deploying an EJB using an already-in-use JNDI name, as do for example JBoss and BEA Weblogic application servers?

Definitely something to remember!

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!

12 March 2012

How to clean-up JBoss temporary directories using bash scripting

Repetitive and annoying file system tasks are the natural field of automation through shell scripting - so, here's a script  that can be used to clean up temporary directories created by JBoss Application Server.

You can provide as parameter the name of the node that you want clean up - if launched without parameters, the script cleans up temporary directories in each node under current installation.

Tested on JBoss 4.0.5.GA and JBoss 5.1.0.GA installations.

#!/bin/bash
# Commonly available under GPL 3 license
# Copyleft Pietro Martinelli - javapeanuts.blogspot.com

function cleanTmpDir {
        echo "  Cleaning ${1}/${2}"
        rm -rf "${1}/${2}"

}

function cleanNode {
        echo "Cleaning \"${1}\" jboss node"
        for tmpDir in data log tmp work
        do
                cleanTmpDir ${1} ${tmpDir}
        done
}


if [ $# -eq 0 ]
then
        for dir in $(find server -maxdepth 1 -mindepth 1 -type d)
        do
                cleanNode ${dir}
        done
else
        if [ -e "server/${1}" ]
        then
                cleanNode "server/${1}"
        else
                echo "${1} is not a subdir of server dir"
        fi
fi

Updated: this script is now available on bitbucket.org:
https://bitbucket.org/thecleancoder/javapeanuts-shell-utils/src