Wildfly8 上 deployment/starting up war 期间的 Oracle BLOB 异常

Oracle BLOB exception during deployment/starting up war on Wildfly8

我在 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.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.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上。该应用程序使用 Quartz 版本 1.8.6。 Spring 版本是 3.2.5。 我在较低的环境中遇到了类似的(没有提到 EOF)问题,但这是由于缺少 JDBC 驱动程序配置。

quartz 配置与此类似 (http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigJDBCJobStoreClustering),除了数据源是在 wildfly 上配置的。

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.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

现在可以正常使用了。

我也遇到了类似的问题,并且在服务器启动时收到此错误。

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 table 中清除了作业的数据,但我遇到了错误并重新启动了我的服务器。这解决了问题。

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

希望对您有所帮助。