在Wildfly8上部署/启动war时Oracle BLOB异常



war java/w spring app启动时出现以下异常

Caused by: java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' defined in "/content/service.war/WEB-INF/classes/META-INF/spring/applicationContext-service.xml": Invocation of init method failed; nested exception is org.quartz.JobPersistenceException: Couldn't retrieve job because the BLOB couldn't be deserialized: null [See nested exception: java.io.EOFException]
    at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:222)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:87)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.start(UndertowDeploymentService.java:72)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948) [jboss-msc-1.2.2.Final.jar:1.2.2.Final]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881) [jboss-msc-1.2.2.Final.jar:1.2.2.Final]
    ... 3 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' defined in "/content/service.war/WEB-INF/classes/META-INF/spring/applicationContext-service.xml": Invocation of init method failed; nested exception is org.quartz.JobPersistenceException: Couldn't retrieve job because the BLOB couldn't be deserialized: null [See nested exception: java.io.EOFException]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:615)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:173)
    at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:193)
    ... 7 more
Caused by: org.quartz.JobPersistenceException: Couldn't retrieve job because the BLOB couldn't be deserialized: null [See nested exception: java.io.EOFException]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1421)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$7.execute(JobStoreSupport.java:1396)
    at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:242)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeWithoutLock(JobStoreSupport.java:3693)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1393)
    at org.quartz.core.QuartzScheduler.getJobDetail(QuartzScheduler.java:1431)
    at org.quartz.impl.StdScheduler.getJobDetail(StdScheduler.java:539)
    at org.springframework.scheduling.quartz.SchedulerAccessor.jobDetailExists(SchedulerAccessor.java:420)
    at org.springframework.scheduling.quartz.SchedulerAccessor.addJobToScheduler(SchedulerAccessor.java:338)
    at org.springframework.scheduling.quartz.SchedulerAccessor.registerJobsAndTriggers(SchedulerAccessor.java:281)
    at org.springframework.scheduling.quartz.SchedulerFactoryBean.afterPropertiesSet(SchedulerFactoryBean.java:508)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
    ... 21 more
Caused by: java.io.EOFException
    at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2328) [rt.jar:1.8.0_45]
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2797) [rt.jar:1.8.0_45]
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802) [rt.jar:1.8.0_45]
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299) [rt.jar:1.8.0_45]
    at org.quartz.impl.jdbcjobstore.oracle.OracleDelegate.getObjectFromBlob(OracleDelegate.java:156)
    at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectJobDetail(StdJDBCDelegate.java:904)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1404)
    ... 33 more

它部署在集群wildfly 8.1.x上。该应用程序使用石英1.8.6版本。Spring的版本是3.2.5。我在低级环境中遇到过类似的问题(没有提到EOF),但这是由于缺乏JDBC驱动程序配置造成的。

石英的配置类似于这个(http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigJDBCJobStoreClustering),除了数据源是在野外配置的。

The DS itslef bounds correctly:
2015-09-25 14:57:21,411 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-4) JBAS010400: Bound data source [java:/quartzDs]

我真的很困惑,因为在另一个(镜像)环境下它工作得很好。

什么线索吗?

我也面临类似的问题,并在服务器启动时得到此错误。

org.quartz.JobPersistenceException: Couldn't retrieve job because the BLOB couldn't be deserialized: null
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1397) ~[quartz-2.3.0.jar:na]

我清除了QRTZ_JOB_DETAILS表中出现错误的作业的数据,并重新启动了服务器。

delete from QRTZ_JOB_DETAILS where job_name = 'MergeEntitiesJob';
commit;

当QRTZ_JOB_DETAILS的JOB_DATA列中包含的BLOB数据损坏时,会发生此问题。清除该行并重新启动应用程序可修复此问题。参考:http://quartz.10975.n7.nabble.com/Couldn-t-retrieve-job-because-the-BLOB-couldn-t-be-deserialized-Error-td5755.html

好的,我已经设法解决了这个问题。原来问题出在org.quartz.impl.jdbcjobstore.oracle.OracleDelegate和Oracle 10.2.x。它在Oracle 11.x上运行良好。问题本身是Oracle 10.2中的作业。X被序列化为空,因此以后不能反序列化,因此上面的堆栈跟踪。

为了解决这个问题,我写了自己的委托扩展OracleDelegate和覆盖getObjectFromBlob方法。

public class CustomDelegate extends OracleDelegate {
    public CustomDelegate(Logger logger, String tablePrefix, String instanceId) {
        super(logger, tablePrefix, instanceId);
    }
    public CustomDelegate(Logger logger, String tablePrefix, String instanceId, Boolean useProperties) {
        super(logger, tablePrefix, instanceId, useProperties);
    }
    protected Object getObjectFromBlob(ResultSet rs, String colName)
            throws ClassNotFoundException, IOException, SQLException {
        byte[] data = rs.getBytes(colName);
        if (data == null || data.length == 0) {
            return null;
        }
        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data));
        try {
            return in.readObject();
        } finally {
            in.close();
        }
    }
}

然后我必须改变石英的性质

org.quartz.jobStore.driverDelegateClass = my.package.CustomDelegate

现在它工作正常。

最新更新