2

Im trying to implement a scheduler to schedule 3 jobs, but on first job implementation only im getting incompatible class change error..

The error is on line,

JobDetail jobA = JobBuilder.newJob(JobA.class)
                     .withIdentity(jobKeyA).build();

Any help??

the complete code is as follow..

import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class Scheduler1 {
    public static void main( String[] args ) throws Exception
    {

    JobKey jobKeyA = new JobKey("jobA", "group1");
        JobDetail jobA = JobBuilder.newJob(JobA.class)
        .withIdentity(jobKeyA).build();

        JobKey jobKeyB = new JobKey("jobB", "group1");
        JobDetail jobB = JobBuilder.newJob(JobB.class)
        .withIdentity(jobKeyB).build();

        JobKey jobKeyC = new JobKey("jobC", "group1");
        JobDetail jobC = JobBuilder.newJob(JobC.class)
        .withIdentity(jobKeyC).build();


        Trigger trigger1 = TriggerBuilder
        .newTrigger()
        .withIdentity("dummyTriggerName1", "group1")
        .withSchedule(
            CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
        .build();

        Trigger trigger2 = TriggerBuilder
        .newTrigger()
        .withIdentity("dummyTriggerName2", "group1")
        .withSchedule(
            CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
        .build();

        Trigger trigger3 = TriggerBuilder
        .newTrigger()
        .withIdentity("dummyTriggerName3", "group1")
        .withSchedule(
            CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
        .build();

        Scheduler scheduler = new StdSchedulerFactory().getScheduler();

        scheduler.start();
        scheduler.scheduleJob(jobA, trigger1);
        scheduler.scheduleJob(jobB, trigger2);
        scheduler.scheduleJob(jobC, trigger3);

    }
}

i have three classes jobA,jobB,jobC but when im adding them to above scheduler im getting error as follows,

Exception in thread "main" java.lang.IncompatibleClassChangeError: Implementing class at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:788) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:447) at java.net.URLClassLoader.access$100(URLClassLoader.java:71) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at Scheduler1.main(Scheduler1.java:15)

user2793926
  • 105
  • 3
  • 5
  • 15

3 Answers3

5

I had been having this problem as well. After digging through the bowls of the core Java code we discovred that this simple app produced the problem everytime:

public static void main(String[] args) {
    System.out.println(AssertionBuilderRegistry.class);
    System.out.println(AssertionBuilderRegistryImpl.class);
}

Those classes were determined to be the offenders by putting a Exception breakpoint in the debugger and walking up the call stack until we got some named suspects.

mvn dependency:tree

produces this snippet:

\- org.apache.cxf:cxf-bundle-minimal:jar:2.4.10:compile
[INFO] |  |     +- org.apache.ws.xmlschema:xmlschema-core:jar:2.0.3:compile
[INFO] |  |     +- org.apache.geronimo.specs:geronimo-stax-api_1.0_spec:jar:1.0.1:compile
[INFO] |  |     +- org.apache.geronimo.specs:geronimo-annotation_1.0_spec:jar:1.1.1:compile
[INFO] |  |     +- javax.xml.bind:jaxb-api:jar:2.1:compile
[INFO] |  |     +- org.apache.neethi:neethi:jar:2.0.4:compile

So, Basically,

AssertionBuilderRegistryImpl

must implements/extend

AssertionBuilderRegistry

So, let's go look at CXF version of AssertionBuilderRegistryImpl

public class AssertionBuilderRegistryImpl extends AssertionBuilderFactoryImpl implements
AssertionBuilderRegistry, BusExtension {

and now AssertionBuilderRegistry

public interface AssertionBuilderRegistry extends AssertionBuilderFactory { // intellij highlights red here on the extends 

So, lets look at AssertionBuilderFactory

public class AssertionBuilderFactory

Well, we have a class implements and interface and that interface extends a class?!

But wait, this is the correct version pointed out by maven. So, cxf minimal is depending on something it's incompatible with?!

Let's take a look at the pom for cxf-minimal (snippet):

<dependency>
  <groupId>org.apache.neethi</groupId>
  <artifactId>neethi</artifactId>
  <version>3.0.2</version>
  <scope>compile</scope>
</dependency>

OK, WTF?! maven dependency says it needs 2.0.4 (which is clearly incompatible) and the pom for this artifact says it needs 3.0.2

So, solution:

    <dependency>
        <groupId>org.apache.neethi</groupId>
        <artifactId>neethi</artifactId>
        <version>3.0.2</version>
        <scope>compile</scope>
    </dependency>

explicitly declare the dependency in our main project POM.

Bug. in Maven. Latest version of maven (3.2.1) does the same.

Christian Bongiorno
  • 5,150
  • 3
  • 38
  • 76
  • good explanation about the bug and cause of `IncompatibleClassChangeError: Implementing class`! – Gijs Mar 01 '16 at 10:02
  • Great solution Christian. I ran into the same error when using Apache CXF v3.1.10. I am using Intellij 2018.1 Community Edition with the Maven v3.3.9 plugin. The Maven project was showing that I was including Apache Neethi v3.0.3 only as a dependency, but unfortunately, the WAR was being packaged with both the Neethi v2.0.5 and Neethi v3.0.3 artifacts. Once I excluded Neethi from Apache Axiom and Apache Rampart in my POM file, only the newer version of Neethi was packaged. You've got my upvote for this answer. Thanks! – gburgalum01 Oct 03 '18 at 12:31
3

Include the suitable version of cglib in your class path.For eg

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
Kamlesh Arya
  • 4,864
  • 3
  • 21
  • 28
0

I assume that this question is already answered but providing some more details from my own experience.

I had same java.lang.IncompatibleClassChangeError in the trace and was thrown when cxf-bundle-2.4.0.jar was used with neethi-2.x.jar, which was already existing in the class path. As mentioned in Christian Bongiorno's answer, I could find that neethi-3.x.jar is required by cxf-bundle-2.40.jar (I wanted to up vote the answer, but not having enough points to upvote or comment).

See this link for more details.

I launched the VM with -verbose argument mentioned in Brian's answer to this question. This helped to see the class loader logs in catalina.out and could understand that the issue is when org.apache.cxf.ws.policy.PolicyEngine/Impl classes are loaded, which has dependency to classes from neethi library.

In addition to neethi, I have to replace the XmlSchema-1.3.2.jar with xmlschema-core-2.0.jar as that was also showing conflict. The application is working fine after these changes, however detailed testing is required to confirm. Changes like this are tricky as there can be other run time issues. I wish to rewrite the old code to use latest libraries, but not have time to do so.

Doc Davluz
  • 4,154
  • 5
  • 30
  • 32
Hari Nair
  • 96
  • 1
  • 1
  • 10