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:

Categories
JBoss

Cronjobs using Quartz in JBossAS

With the introduction of EJB3 a new method for implementing cronjobs was added. These jobs uses quartz as framework and there are two ways to setup:

1. Variant: Defining a MDB-Consumer

The preferred way is the definition of an MDB-Consumer. The only thing you need is to implement the Job-Interface (org.quartz.Job) and add some Annotations to it:

1
2
3
4
5
6
7
8
9
@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "cronTrigger", propertyValue = "0/2 * * * * ?") })
@ResourceAdapter("quartz-ra.rar")
public class MySampleCronJob implements Job {
 
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("job is called");
    }
 
}

If this job should only be called once at a specific time, you can use the interface StatefulJob. When the job is called is defined in the property cronTrigger. A full documentation can be found at the Quartz-API-Documentation.
Pay attention that the Component only implements one interface or you have to define the property “messageListenerInterface” at @MessageDriven. Otherwise the deployer cannot find the using type. Especially if you use AspectJ this is important.

2. Variant: Using a Quartz-Service

This is the old version. You can define a managed-bean via an XML which instantiate a Quartz-Service.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
< ?xml version="1.0" encoding="UTF-8"?>
<server>
  <mbean code="org.quartz.ee.jmx.jboss.QuartzService" name="user:service=QuartzService,name=QuartzService">
    <attribute name="Properties">
      org.quartz.scheduler.instanceName = DefaultQuartzScheduler
      org.quartz.scheduler.rmi.export = false
      org.quartz.scheduler.rmi.proxy = false
      org.quartz.scheduler.xaTransacted = false
      org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
      org.quartz.threadPool.threadCount = 5
      org.quartz.threadPool.threadPriority = 4
    </attribute>
  </mbean>
</server>

Then you can use this managed bean to add a new trigger and to assign a job to this trigger. This code can be used in an own managed bean, which setups the application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class CronManagementBean {
    @Resource(mappedName = "/Quartz")
    private Scheduler scheduler;
 
    public void start() {
        try {
            Trigger trigger = new CronTrigger("myTrigger",
                    "mygroup",
                    "0 0 4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 ? * *");
 
            JobDetail jobDetail = new JobDetail("myJob",
                    "myjobgroup", StatusJob.class);
            scheduler.scheduleJob(jobDetail, trigger);
 
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
 
    public void stop() {
        try {
            scheduler.deleteJob("myJob", "myjobgroup");
        } catch (SchedulerException e) {
            log.warn("shutdown fails", e);
        }
    }
}
Categories
Java JBoss

Using multiple PersistenceUnits with same name

To be really flexible in my CMS I decided to use a persistence unit with one name which will be configured in the final webapplication. This means I have a persistence unit “cms” in my business-components in my cms.jar and this unit is configured via persistence.xml in the including web-application, which uses my “cms.jar”. So every webapplication has its own database and I can reuse my businesslogic for the cms (retrieve content, or images and so on).
The problem now is that I have some problems with deploying two applications on JBoss 5.1.0.GA which includes my cms, because there is a bug in this application-server. I hope this will be fixed in the one of the next versions.

Categories
Javascript

CKEditor – events like onComplete

Currently I develop a CMS in Java using Seam and JSF. Target of the CMS is a simple CMS-Structure which can easily be added to a existing Seam-Application and then provide the editable content via simple JSF-Components. Maybe I will later write some more informations about this CMS.

To easily edit text-content I include the Javascript RTE-Texteditor CKEditor. This editor transform a simple Textarea into a full featured RTE-Editor. The simple include-code looks like:

?View Code JAVASCRIPT
1
CKEditor.replace('idoftextarea');

But you can also define some configuration properties. Especially the events are not fully documented yet for version 3.0. A really interesting event is the onComplete-event or other called the instanceReady-event. This event is called if the editor is fully loaded.

A sample definition could be:

?View Code JAVASCRIPT
1
2
3
4
5
6
7
CKEditor.replace('idoftextarea', {
    on: {
        instanceReady: function(ev) { 
            window.alert('I am ready loaded'); 
        }
    }
});

A use case for such an event could be automatic resize of the editor, for example maximize.
You can also define a global event for every CKEDITOR-instance in this way:

?View Code JAVASCRIPT
1
2
3
CKEDITOR.on( 'idoftextarea', function( ev ) {
    window.alert('Im a ready loaded');
});

Idea’s for this blog

Welcome to my new blog. Here I want to post some tips & tricks all around java-development. These tips will be difficult problems I had to solve during my own developing. Currently I develop mostly standalone or web applications using java. For the web I use JBoss-JEE-Stack with Seam and JSF as Viewhandler. I hope you will enjoy my blog and find my tips useful.