Issue 1:
Manuel Dominguez Sarmiento opened SPR-8887 and commented

This is the exception we get when using the latest Spring 3.1 RC2 together with Quartz 2.1.1

[ERROR] 2011-11-29 14:33:57 [JobRunShell-scheduler_Worker-1] - Job DEFAULT.deviceIndexerJob threw an unhandled Exception:

java.lang.IncompatibleClassChangeError: Found interface org.quartz.JobExecutionContext, but class was expected

at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:79)

at org.quartz.core.JobRunShell.run(JobRunShell.java:213)

at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557)

[ERROR] 2011-11-29 14:33:57 [JobRunShell-scheduler_Worker-2] - Job DEFAULT.shortCodeIndexerJob threw an unhandled Exception:

java.lang.IncompatibleClassChangeError: Found interface org.quartz.JobExecutionContext, but class was expected

at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:79)

at org.quartz.core.JobRunShell.run(JobRunShell.java:213)

at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557)

The source for QuartzJobBean does not seem to indicate any kind of problem. Even though JobExecutionContext was a class in Quartz 1.x and is now an interface in Quartz 2.x, the methods invoked on it are present in both.

The problem is that the Spring binary has been compiled against Quartz 1.x, and changing a class into an interface (or viceversa) is an incompatible change according to the Java spec, so we get IncompatibleClassChangeError even if the source compiles fine against both Quartz versions.

Recompiling QuartzJobBean against Quartz 2.x solves the issue, however this is an undesirable solution. I guess the solution would be to invoke the offending methods using reflection.

Our workaround was simply creating an alternative MethodInvokingJobDetailFactoryBean simplified for our use and compiled directly against Quartz 2.x, but this should be solved for the general public.

BTW, #13081 is somehow related but is clearly a different issue, which in fact has already been solved in 3.1 RC2

Affects: 3.1 RC2

Issue Links:

#13530 QuartzJobBean doesn't work with Quartz 2.0 at runtime ("duplicates")

Issue 2:
Wim Deblauwe opened SPR-5402 and commented

I saw a NullPointerException in the logs of my tomcat (started using maven cargo):

[INFO] [talledLocalContainer] java.lang.NullPointerException
[INFO] [talledLocalContainer]	at java.lang.String.indexOf(String.java:1734)
[INFO] [talledLocalContainer]	at java.lang.String.indexOf(String.java:1716)
[INFO] [talledLocalContainer]	at org.springframework.jms.JmsException.getMessage(JmsException.java:87)
[INFO] [talledLocalContainer]	at java.lang.Throwable.getLocalizedMessage(Throwable.java:267)
[INFO] [talledLocalContainer]	at java.lang.Throwable.toString(Throwable.java:343)
[INFO] [talledLocalContainer]	at java.lang.String.valueOf(String.java:2827)
[INFO] [talledLocalContainer]	at java.io.PrintWriter.println(PrintWriter.java:710)
[INFO] [talledLocalContainer]	at java.lang.Throwable.printStackTrace(Throwable.java:509)
[INFO] [talledLocalContainer]	at org.apache.log4j.spi.ThrowableInformation.getThrowableStrRep(ThrowableInformation.java:76)
[INFO] [talledLocalContainer]	at org.apache.log4j.spi.LoggingEvent.getThrowableStrRep(LoggingEvent.java:407)
[INFO] [talledLocalContainer]	at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:305)
[INFO] [talledLocalContainer]	at org.apache.log4j.WriterAppender.append(WriterAppender.java:160)
[INFO] [talledLocalContainer]	at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
[INFO] [talledLocalContainer]	at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)
[INFO] [talledLocalContainer]	at org.apache.log4j.Category.callAppenders(Category.java:206)
[INFO] [talledLocalContainer]	at org.apache.log4j.Category.forcedLog(Category.java:391)
[INFO] [talledLocalContainer]	at org.apache.log4j.Category.error(Category.java:322)

The problem can be seen by looking at the code of JmsMessage.java:

public String getMessage() {
String message = super.getMessage();
Throwable cause = getCause();
if (cause instanceof JMSException) {
Exception linkedEx = ((JMSException) cause).getLinkedException();
if (linkedEx != null && cause.getMessage().indexOf(linkedEx.getMessage()) == -1) {
message = message + "; nested exception is " + linkedEx;
}
}
return message;
}

The line that does the indexOf() can give a NPE if linkedEx.getMessage() returns null

Affects: 2.5.6

Issue Links:

#9948 JmsUtils.buildExceptionMessage throws NPE if the linked exception doesn't have a message ("duplicates")