Category Archives: J2EE

ANT could not find home… variables

Ant lost, could not find home

I was tring to compile scoop using the “ant package” command when I ran into the following error:

Error:

Could not find or load main class org.apache.tools.ant.launch.Launcher

Debug:

ant –execdebug

exec “/usr/lib/jvm/jdk1.7.0_79//bin/java” -classpath “/usr/bin/build-classpath: error: JVM_LIBDIR /usr/lib/jvm-exports/jdk1.7.0_79 does not exist or is not a directory:/usr/bin/build-classpath: error: JVM_LIBDIR /usr/lib/jvm-exports/jdk1.7.0_79 does not exist or is not a directory:/usr/lib/jvm/jdk1.7.0_79//lib/tools.jar” -Dant.home=”/usr/share/ant” -Dant.library.dir=”/usr/share/ant/lib” org.apache.tools.ant.launch.Launcher -cp “”
Error: Could not find or load main class org.apache.tools.ant.launch.Launcher

Quick fix:

Missing directory, create an empty one.

             mkdir /usr/lib/jvm-exports/jdk1.7.0_79

SMSC Integration Troobleshooting

This post is just a reminder for me. It may be useful one day for someone else too.
I worked on an application that sends short text messages (SMS) through an SMS gateway based on SMPP3.4 protocol; The work is based on a Java library called SMSLib (v3), which is based on JSMPP itself. The SMS library introduced the “Service” idea on top of the AbstractJSMPP gateway already specified on JSMPP. This “Service” allows many other capabilities such as redundunt and load balanced gateways.
However, the integration with different plateforms was not as easy as I thought because of specific features and configuration on each SMSC.
For instance, I was facing a weird “Session not bound exception” while dealing with Nokia SMSC 8.1. Actually, the server answer was:

Bind Response header (31, 80000002, 00000450, 1)

The server response code is 0x000000450. The first step to solve this issue is to understand this error. The problem is, that this code does not belong to standard SMPP 3.4 protocol standard errors!

vendor specific errors

Vendor specific errors

I gathered the vendor documentation for the client SMSC (Nokia SMSC Center 8.1), and the error mentioned is “Too many users with this login ID”.

Nokia Vendor Documentation

Actually the process of sending messages was a background scheduled task using Quartz. It gathers a queue from an oracle table¬†and tries to send items one by one. When it fails to send and the application gets no more connected to the SMSC, it tries to reconnect. It seems that the SMSC is not handling correctly the disconnection on session unbind event(send failure). So, the number of opened session with the same ID keeps growing until it fails to create a new session. The administrator of the SMSC told me after a while(4 months approximately!), that the maximum number of session to open with same ID is 10 ūüôā

Another ambiguous error received from another type of SMSC (I don’t know even the vendor of this one) is 0x00000008 (System Error – ESME_RSYSERR) . In this type of errors, only the SMSC logs can help you. I want to thank the guy on the other side who was very helpful to get rid of it quickly. Actually, it was related to numbering format and to mandatory params. This is a specific configuration too. In this case, the SMSC is configured to reject any SMS without a source phone¬†number. So, adding the instruction (setFrom) to the outgoing message solved the issue. In the first SMSC, the parameter was not mandatory, and it was gathered by the SMSC from the client ID.

I also added a custom implementation of JSMPPGatway to handle variable transaction timer; Due to some network latency, the transaction time was exceeding the default value assigned on Jsmpp abstract definition (on session creation); The default value is 2000 ms(=2s).  I managed to get it longer by overriding the constructor of JSMPPGateway to handle the transaction timer parameter.

 

Quartz Cron with Spring Framework

Quartz

Quartz is an open source for job scheduling wich may be easily plugged in any working java project.

  • Step 1

In the applicationContext.xml, add the job details (class and target method). Target method should be a public method without parameters.


<bean name="aBackgroundJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" class="net.slm.BackgroundWorkerClass"/>
<property name="targetMethod" value="methodToCallOnQuartzEvent"/>
<!-- This job maybe concurrent (default) or exclusive -->
<property name="concurrent" value="false"/>

 </bean>

  • Step 2

Now, there are two ways to run this job using Quartz library, either a simple cron scheduled after server start and having a repeat interval (simpleTrigger) :


<bean id="dailyCronTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="aBackgroundJob"/>
<!-- 2 minutes after server starting -->
<property name="startDelay" value="120000"/>
<!-- repeat every 24 hours (1000*60*60*24)-->
<property name="repeatInterval" value="86400000"/>
 </bean>

The second option is to use quartz specific regular expressions to schedule fire time. Those regular expressions are explained in details here.


<bean id="dailyCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="aBackgroundJob"/>
<!-- run every day at 9:30 AM -->
<property name="cronExpression" value="0 30 9 * * ?"/>
<property name="concurrent" value="false"/>
 </bean>

  • Step 3

To get those events fired, you must subscribe crons to a schedular:


<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="dailyCronTrigger" />
</list>
</property>
 </bean>

  • Step 4

Some java code for the job.


package net.slm;

import java.util.Date;

public class BackgroundWorkerClass {

public void methodToCallOnQuartzEvent(){
System.out.println("Quartz job started at "+new Date());
//or do whatever you want
}

}

There are similar libraries here but I think that quartz is the richest.

The annoying transaction journey

When moving to production environment, I encoutered some problems with a specific patch of IBM WAS (7.0.0.25). Then I discovered it was not really related to that particualr patch because that makes no sens. Later in the same week, when we went back to development environment, ¬†we encountered the same errors… That was a bit wierd because the whole application was tested for more than one month without throwing anyone of those errors. Error List contains:

  • org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
  • java.lang.IllegalArgumentException: Cannot convert value of type […]¬†no matching editors or conversion strategy found
  • org.hibernate.TransactionException: Transaction not successfully started
  • [BlazeDs] serilization: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role

At the same time, I discovered prezi and I wanted to test it. Here’s the result*:

 

* To integrate prezi presentation, please go here.

ADMN0022E: Access denied due to insufficient or empty credentials.

While trying to monitor Websphere programmatically via its AdminClient framework, I faced many problems that can be easily solved by reading the documentation carefully. But this one, seems to be quite misleading.

ADMN0022E: Access denied for the getStatsObject operation on Perf MBean due to insufficient or empty credentials.

If you get this error while trying to read PMI data using admin client on websphere, and you are sure about username and password, be sure that the user you are tring to connect has Monitor privileges in the administrative role. You can check it from WAS administrative console > Users and Groups > Administrative User Role ¬†and then see if the “Monitor” role is assigned.

Something else that might help, params to connect my WAS 7 instance are (administrative security enabled):

String hostname = "localhost";
String soapport = "8882";
String username = "salem";
String password = "salem";
String truststore = "D:/WAS7/profiles/etc/DummyClientTrustFile.jks";
String keystore = "D:/WAS7/profiles/et/DummyClientKeyFile.jks";
String truststorepass = "WebAS";//default for WAS 7, but for WAS 6.1 it's the node name
String keystorepass = "WebAS";
String truststoretype = "jks";
String keystoretype = "jks";

You may start working on Java admin client from here; If you couldn’t figure out using IBM documentation, you may use this…

Measuring distance to stars

Just kidding you… will tell you how to do it sooner ūüôā

Spring/Hibernate Search on WAS 7: The Impossible Jar Combination



Instead of spending hours and hours in jars conflicts resolution, I suggest this combination which is working under Websphere:

Sping Framework 2.5.6 (with dependencies)
Hibernate 3.6.8
Hibernate Search 3.4.1
Lucene 3.1

This might be insignificant at first sight, but once you start getting

Error creating bean with name ‘propertyConfigurer’ defined in ServletContext resource [/WEB-INF/classes/webApplicationContext.xml]: Initialization of bean failed; nested exception is java.lang.NullPointerException (Solution)

and

Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org.hibernate.annotations.common.reflection.MetadataProvider(Solution)

you will start focusing on this listing :

antlr-2.7.6.jar
antlr-runtime-3.0.jar
aopalliance.jar
apache-solr-core-1.4.0.jar
asm-2.2.3.jar
asm-attrs.jar
asm.jar
backport-util-concurrent.jar
c3p0-0.9.1.jar
cfgatewayadapter.jar
cglib-2.2.jar
cglib-nodep-2.1_3.jar
commons-beanutils-1.8.3.jar
commons-beanutils-1.8.3-sources.jar
commons-beanutils-bean-collections-1.8.3.jar
commons-beanutils-core-1.8.3.jar
commons-codec-1.3.jar
commons-collections-3.1.jar
commons-dbcp.jar
commons-digester-2.0.jar
commons-digester-2.0-sources.jar
commons-discovery-0.4.jar
commons-fileupload-1.2.1.jar
commons-httpclient-3.0.1.jar
commons-io-1.4.jar
commons-lang.jar
commons-logging1.1.jar
commons-pool.jar
compass-2.2.0.jar
concurrent.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
flex-messaging-common.jar
flex-messaging-core.jar
flex-messaging-opt.jar
flex-messaging-proxy.jar
flex-messaging-remoting.jar
hibernate3.jar
hibernate-commons-annotations-3.2.0.Final.jar
hibernate-core-3.6.7.Final.jar
hibernate-entitymanager.jar
hibernate-search-3.4.1.Final.jar
iText-2.1.7.jar
jasperreports-3.7.2.jar
jasperreports-applet-3.7.2.jar
jasperreports-fonts-3.7.2.jar
jasperreports-javaflow-3.7.2.jar
javassist-3.9.0.GA.jar
javassist.jar
javax.persistence-2.0.0.jar//under websphere should be moved somewhere else (see http://bit.ly/JprRim)
jdbc2_0-stdext.jar
jgroups-2.8.0.GA.jar
jms.jar
jsr173_1.0_api.jar
jsr250-api.jar
jstl-1.2.jar
jta-1.1.jar
junit-4.4.jar
log4j-1.2.15.jar
lucene-analyzers-3.1.0.jar
lucene-core-3.1.0.jar
lucene-highlighter-3.1.0.jar
lucene-memory-3.1.0.jar
lucene-misc-3.1.0.jar
lucene-queries-3.1.0.jar
lucene-spellchecker-3.1.0.jar
mysql-connector-java-5.1.6-bin.jar
naming-resources.jar
ojdbc14.jar
poi-3.0.1-FINAL-20070705.jar
quartz.jar
richfaces-api-3.2.2-SNAPSHOT.jar
richfaces-impl-3.2.2-SNAPSHOT.jar
richfaces-ui-3.2.2-SNAPSHOT.jar
servlet-api.jar
slf4j-api-1.5.8.jar
slf4j-api.jar
slf4j-log4j12-1.5.0.jar
solr-common.jar
solr-core-1.4.0.jar
solr-solrj-1.4.0.jar
spring-aop.jar
spring-beans.jar
spring-context.jar
spring-context-support.jar
spring-core.jar
spring.jar
spring-jdbc.jar
spring-jms.jar
spring-orm.jar
spring-test.jar
spring-tx.jar
spring-web.jar
spring-webmvc.jar
spring-webmvc-portlet.jar
spring-webmvc-struts.jar
sqljdbc.jar
standard.jar
xalan.jar
xml-apis-1.0.b2.jar

Hope that helps and avoid humanity torture on jar conflicts resolution ūüėÄ

OrphanRemoval on WAS 7

WAS 7

While migrating from Apache Tomcat 6 to IBM Websphere 7, in a Spring Hibernate project, you will certainly face this error:

nested exception is java.lang.NoSuchMethodError: javax/persistence/OneToMany.orphanRemoval()Z

There are many posts on the net about it. But, when dealing with IBM Websphere, it seems to be a bit different from other environments. All the issue is about persistence. All you have to do is :

1) Move your javax.persistence-2.0.0.jar to ${WAS_INSTALL_DIR}/APPSERVER/java/jre/lib/ext

2) Open configuration console and navigate to Applications->Application Types-> Websphere Entreprise Applications -> ${youApplication}

3) Click on the link “Class loading and update detection”

Webpshere 7 project details

4) In Class Loader Order, select “Classes loaded with local class loader first (parent last)”

Class loading and update detection

5) Restart WAS 7 and check if the  javax.persistence-2.0.0.jar was correctly loaded.

Websphere view - lodade classes

In the WAS 7 Redbook(WebSphere Application Server V7 Administration and Configuration Guide), they say :

The default value for class loading mode is Classes loaded with parent class
loader first. This mode causes the class loader to first delegate the loading of
classes to its parent class loader before attempting to load the class from its local
class path. This is the default policy for standard Java class loaders.
If the class loading policy is set to Classes loaded with local class loader first
(parent last), the class loader attempts to load classes from its local class path
before delegating the class loading to its parent. This policy allows an application
class loader to override and provide its own version of a class that exists in the
parent class loader.

Looks like Websphere 7, then, contains old JPA definition, without OneToMany.OrphanRemoval (which is specified in JPA 2.0).

Mykong also suggested adding hibernate-jpa-2.0-api-1.0.0.Final.jar instead of javax.persistence-2.0.0.jar