Categories
Tomcat

Disable JSESSIONID in Tomcat

Like PHP also the Servlet Containers try to attach a request to a session. If the client doesn’t support cookies it is realized via an suffix ;JESSSIONID= in every URL. Unfortunately this is not good in relation to SEO. The problem is that Tomcat doesn’t provide any configuration option to disable the use of JSESSIONID in URLs. So the only way is an own Filter, which disables the behaviour. You will find an example at: http://randomcoder.com/articles/jsessionid-considered-harmful

Categories
JBoss

Classloading problems with injected @EJB-Beans

Yesterday I wrote how to define Quartz-Jobs in JBoss AS. Generally such jobs try to use business logic, which is injected via @EJB. Currently in Version 5.1.0.GA this is not possible if you use the classloader-isolation. You will get the following (or similar) exception:

1
2
3
4
5
6
7
8
9
Caused by: java.lang.RuntimeException: Can not find interface declared by Proxy in our CL + BaseClassLoader@92c904{vfsfile:...}
at org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory.redefineProxyInTcl(ProxyObjectFactory.java:343)
at org.jboss.ejb3.proxy.impl.objectfactory.session.SessionProxyObjectFactory.createProxy(SessionProxyObjectFactory.java:134)
at org.jboss.ejb3.proxy.impl.objectfactory.session.stateless.StatelessSessionProxyObjectFactory.getProxy(StatelessSessionProxyObjectFactory.java:79)
at org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory.getObjectInstance(ProxyObjectFactory.java:158)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
at org.jnp.interfaces.NamingContext.getObjectInstance(NamingContext.java:1479)
at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure(NamingContext.java:1496)
... 39 more

The reason for this ist that the Quartz-Service has another classloader as your application and the started job contains to the classloader of the Quartz-Service. There is also a bug posted. Maybe this will be possible in the near future.
One solution is to call a MBean from the job and this MBean injects the business logic via @EJB. The advantage of this solution is that you also can control and monitor the cronjob itselfs and can run the logic on demand via JMX-Console.
An example job would look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@MessageDriven(messageListenerInterface = StatefulJob.class, activationConfig = { @ActivationConfigProperty(propertyName = "cronTrigger", propertyValue = "0 0 0 ? * MON-SAT") })
@ResourceAdapter("quartz-ra.rar")
@Depends(ImportDataManagement.ID)
public class DailyUpdateJob implements StatefulJob {
    private static final Logger log = Logger
            .getLogger(DailyUpdateJob.class);
 
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        try {
            MBeanServer server = MBeanServerLocator.locate();
            ImportDataManagement bp = (ImportDataManagement) MBeanProxyExt
                    .create(ImportDataManagement.class,
                            ImportDataManagement.ID, server);
            bp.importDaily();
        } catch (Exception e) {
            log.error("run", e);
        }
    }
}

Helpful links: