Results 1 to 3 of 3

Thread: Spring + Quartz 2.1.x in an OSGi environment problem with SimpleTriggerFactoryBean

  1. #1
    Join Date
    Feb 2008
    Posts
    4

    Default Spring + Quartz 2.1.x in an OSGi environment problem with SimpleTriggerFactoryBean

    I am trying to migrate to use Spring with Quartz 2.0 on the Apache Karaf OSGi environment. I am having trouble using the SimpleTriggerFactoryBean as it tries to instantiate org.quartz.SimpleTrigger (an interface in Quartz 2.x)

    Through the debugger, I have determined that the following line in the SpringTriggerFactoryBean.java

    simpleTriggerClass = getClass().getClassLoader().loadClass("org.quartz. impl.triggers.SimpleTriggerImpl");

    will throw a ClassNotFoundException and make it default to instantiate SimpleTrigger.

    I have confirmed that "org.quartz.impl.triggers" is in the Import-Packages. I have modified an existing code in the package to perform a System.out.println(new SimpleTriggerImpl()) and that works successfully and I have also tried using DynamicImport-Package = * with no luck.

    Full stack trace below:
    Code:
    Exception in thread "SpringOsgiExtenderThread-70" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'healthCheckManagerTrigger' defined in URL [bundleentry://235.fwk1084573260/META-INF/spring/module-context.xml]: Invocation of init method failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.quartz.SimpleTrigger]: Specified class is an interface
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:591)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69)
    	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355)
    	at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
    	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)
    	at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:132)
    	at java.lang.Thread.run(Thread.java:722)
    Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.quartz.SimpleTrigger]: Specified class is an interface
    	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101)
    	at org.springframework.beans.BeanWrapperImpl.<init>(BeanWrapperImpl.java:163)
    	at org.springframework.scheduling.quartz.SimpleTriggerFactoryBean.afterPropertiesSet(SimpleTriggerFactoryBean.java:247)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
    	... 14 more

  2. #2
    Join Date
    Feb 2008
    Posts
    4

    Default

    One way of getting around this that I got working was to create my own version of the FactoryBean but implement it so that it has the Quartz 2.x classes used in compilation.

    Another thing to note is when you are scheduling a trigger, make sure to expose the fact that the trigger is an "OperableTrigger" via the <interfaces> element otherwise it will say that the proxy class cannot be cast to OperableTrigger when scheduling a job.
    Last edited by trajano; Jul 31st, 2012 at 08:59 AM.

  3. #3

    Default

    Quote Originally Posted by trajano View Post
    Through the debugger, I have determined that the following line in the SpringTriggerFactoryBean.java

    simpleTriggerClass = getClass().getClassLoader().loadClass("org.quartz. impl.triggers.SimpleTriggerImpl");

    will throw a ClassNotFoundException and make it default to instantiate SimpleTrigger.

    I have confirmed that "org.quartz.impl.triggers" is in the Import-Packages. I have modified an existing code in the package to perform a System.out.println(new SimpleTriggerImpl()) and that works successfully and I have also tried using DynamicImport-Package = * with no luck.
    The loadClass will use the classloader of the current class (getClass().getClassLoader()), which in this case is SpringTriggerFactoryBean. That means that the spring-context-support bundle must have the org.quartz.impl.triggers package listed as an import, and it does not. Looks like a bug in the Spring packaging caused because this class loading is done dynamically and therefore is not detected by Bundlor. The template.mf would have to be updated to import this class explicitly.

    You could try creating an empty subclass of SpringTriggerFactoryBean in your own bundle, which when used in the context should cause getClass().getClassLoader() to return the classloader of your bundle rather than the spring-context-support bundle.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •