Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-5538

Improve configurability for OracleLobHandler (be able to set classloader to use)

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Major
    • Resolution: Won't Fix
    • Affects Version/s: 2.0.7
    • Fix Version/s: None
    • Component/s: Data
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      i get a ClassNotFound even if the class is available for the application classloader (this is verified via the websphere admin console (troubleshooting -> class loader viewer - all the ora classes can be loaded just fine).

      org.springframework.dao.DataAccessResourceFailureException: Could not create Oracle LOB; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Couldn't initialize OracleLobHandler b
      ecause Oracle driver classes are not available. Note that OracleLobHandler requires Oracle JDBC driver 9i or higher!; nested exception is java.lang.ClassNotFoundException: oracle.sql.BLOB
      Caused by:
      org.springframework.dao.InvalidDataAccessApiUsageException: Couldn't initialize OracleLobHandler because Oracle driver classes are not available. Note that OracleLobHandler requires Oracle JDBC driver 9i or
      higher!; nested exception is java.lang.ClassNotFoundException: oracle.sql.BLOB
      Caused by:
      java.lang.ClassNotFoundException: oracle.sql.BLOB
      at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:402)
      at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:347)
      at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:83)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
      at org.springframework.jdbc.support.lob.OracleLobHandler.initOracleDriverClasses(OracleLobHandler.java:150)
      at org.springframework.jdbc.support.lob.OracleLobHandler$OracleLobCreator.createLob(OracleLobHandler.java:339)
      at org.springframework.jdbc.support.lob.OracleLobHandler$OracleLobCreator.setClobAsCharacterStream(OracleLobHandler.java:311)
      at com.te.pwh.services.history.jobs.HistoricalizationItemWriter$1.setValues(HistoricalizationItemWriter.java:116)
      at org.springframework.jdbc.core.support.AbstractLobCreatingPreparedStatementCallback.doInPreparedStatement(AbstractLobCreatingPreparedStatementCallback.java:70)
      at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:538)
      at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:566)
      at com.te.pwh.services.history.jobs.HistoricalizationItemWriter.handleTpwPafios(HistoricalizationItemWriter.java:110)
      at com.te.pwh.services.history.jobs.HistoricalizationItemWriter.write(HistoricalizationItemWriter.java:89)
      at org.springframework.batch.item.support.CompositeItemWriter.write(CompositeItemWriter.java:30)
      at org.springframework.batch.item.support.DelegatingItemWriter.write(DelegatingItemWriter.java:45)
      at org.springframework.batch.core.step.item.BatchListenerFactoryHelper$2.write(BatchListenerFactoryHelper.java:99)
      at org.springframework.batch.core.step.item.SimpleItemHandler.doWrite(SimpleItemHandler.java:105)
      at org.springframework.batch.core.step.item.SkipLimitStepFactoryBean$StatefulRetryItemHandler$1.doWithRetry(SkipLimitStepFactoryBean.java:402)
      at org.springframework.batch.retry.callback.RecoveryRetryCallback.doWithRetry(RecoveryRetryCallback.java:109)
      at org.springframework.batch.retry.support.RetryTemplate.execute(RetryTemplate.java:168)
      at org.springframework.batch.core.step.item.SkipLimitStepFactoryBean$StatefulRetryItemHandler.write(SkipLimitStepFactoryBean.java:419)
      at org.springframework.batch.core.step.item.SimpleItemHandler.handle(SimpleItemHandler.java:71)
      at org.springframework.batch.core.step.item.ItemOrientedStep$3.doInIteration(ItemOrientedStep.java:391)
      at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:346)
      at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:212)
      at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
      at org.springframework.batch.core.step.item.ItemOrientedStep.processChunk(ItemOrientedStep.java:382)
      at org.springframework.batch.core.step.item.ItemOrientedStep$2.doInIteration(ItemOrientedStep.java:259)
      at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:346)
      at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:212)
      at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
      at org.springframework.batch.core.step.item.ItemOrientedStep.doExecute(ItemOrientedStep.java:236)
      at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:172)
      at org.springframework.batch.core.job.SimpleJob.execute(SimpleJob.java:103)
      at org.springframework.batch.core.configuration.support.ClassPathXmlApplicationContextJobFactory$ContextClosingJob.execute(ClassPathXmlApplicationContextJobFactory.java:107)
      at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:86)
      at org.springframework.scheduling.commonj.DelegatingWork.run(DelegatingWork.java:61)
      at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1114)
      at com.ibm.ws.asynchbeans.WorkWithExecutionContextImpl.go(WorkWithExecutionContextImpl.java:195)
      at com.ibm.ws.asynchbeans.CJWorkItemImpl.run(CJWorkItemImpl.java:187)
      at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1473)

      I found that the OracleLobHandles code looks like this:
      this.blobClass = con.getClass().getClassLoader().loadClass(BLOB_CLASS_NAME);

      which is proibably the root cause of the problem (although I have not got around to step-debug this in the container yet to look into that classloader). The CL should probably be configurable, and use con.getClass().getClassLoader() if not configured otherwise explicitly.

      Now you probably tell me to use: http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/support/nativejdbc/WebSphereNativeJdbcExtractor.html
      But this is not recommended by IBM (http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html) and I really don't think it will influence which classloader is in use?

      At any rate we reverted to using the DefaultLobHandler as this should be supported by the 10g drivers when only using CLOBs and no BLOBs.

        Attachments

          Activity

            People

            • Assignee:
              thomas.risberg Thomas Risberg
              Reporter:
              david@davidkarlsen.com David J. M. Karlsen
              Last updater:
              Trevor Marshall
            • Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                5 years, 49 weeks, 4 days ago