title: ClassNotFoundException when deserializing data from cache
body: <p>I have an EAR application with EJB for web services, deployed at Glassfish 3.0.1 server. All dependencies are loaded by maven, regarding to pom.xml. I am using wsimport for generate classes from WSDL files. Everything worked perfectly.</p>
  
  <p>Then I had to implement caching for mybatis queries because of some performance issues. After I turn caching on, I realize, that my classes need to be serializable. This wasn't a problem.</p>
  
  <pre><code>&lt;xs:annotation&gt;
      &lt;xs:appinfo&gt;
          &lt;jaxb:globalBindings&gt;
              &lt;xjc:serializable uid="1" /&gt;
          &lt;/jaxb:globalBindings&gt;
      &lt;/xs:appinfo&gt;
  &lt;/xs:annotation&gt;
  </code></pre>
  
  <p>Application is compiled and deployed, but when i call web service operation for the second time (first time ok, cache is empty) from soapUI, i get following error.</p>
  
  <pre><code>org.apache.ibatis.exceptions.PersistenceException: 
  ### Error querying database.  Cause: org.apache.ibatis.cache.CacheException: Error     deserializing object. Cause: java.lang.ClassNotFoundException: cz.cpost.esb.cenik.schema.CountryType
  ### Cause: org.apache.ibatis.cache.CacheException: Error deserializing object. Cause: java.lang.ClassNotFoundException: cz.cpost.esb.cenik.schema.CountryType
  ... some code ommited ...
  Caused by: org.apache.ibatis.cache.CacheException: Error deserializing object.  Cause: java.lang.ClassNotFoundException: cz.cpost.esb.cenik.schema.CountryType
  at org.apache.ibatis.cache.decorators.SerializedCache.deserialize(SerializedCache.java:79)
  at org.apache.ibatis.cache.decorators.SerializedCache.getObject(SerializedCache.java:35)
  at org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:35)
  at org.apache.ibatis.cache.decorators.SynchronizedCache.getObject(SynchronizedCache.java:40)
  at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:56)
  at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:78)
  ... 83 more
  Caused by: java.lang.ClassNotFoundException: cz.cpost.esb.cenik.schema.CountryType
  at com.sun.enterprise.loader.ASURLClassLoader.findClassData(ASURLClassLoader.java:713)
  at com.sun.enterprise.loader.ASURLClassLoader.findClass(ASURLClassLoader.java:626)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
  at java.lang.Class.forName0(Native Method)
  at java.lang.Class.forName(Class.java:247)
  at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:604)
  at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1575)
  at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
  at java.util.ArrayList.readObject(ArrayList.java:593)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)
  at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
  at org.apache.ibatis.cache.decorators.SerializedCache.deserialize(SerializedCache.java:76)
  ... 88 more
  </code></pre>
  
  <p>It seems like when app is trying to get data from cache, cannot find object CountryType.
  I don't know how this is possible, I am pretty new in maven and caching.</p>
  
  <p><strong>maven build element:</strong></p>
  
  <pre><code>&lt;build&gt;
      &lt;resources&gt;
          &lt;resource&gt;
              &lt;targetPath&gt;META-INF/wsdl&lt;/targetPath&gt;
              &lt;directory&gt;src/wsdl&lt;/directory&gt;
              &lt;includes/&gt;
              &lt;filtering&gt;true&lt;/filtering&gt;
          &lt;/resource&gt;
          &lt;resource&gt;
              &lt;directory&gt;src/main/resources&lt;/directory&gt;
              &lt;includes/&gt;
          &lt;/resource&gt;
      &lt;/resources&gt;
      &lt;plugins&gt;
          &lt;plugin&gt;
              &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
              &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
              &lt;version&gt;2.3.2&lt;/version&gt;
              &lt;configuration&gt;
                  &lt;source&gt;1.6&lt;/source&gt;
                  &lt;target&gt;1.6&lt;/target&gt;
                  &lt;compilerArguments&gt;
                      &lt;endorseddirs&gt;${endorsed.dir}&lt;/endorseddirs&gt;
                  &lt;/compilerArguments&gt;
              &lt;/configuration&gt;
          &lt;/plugin&gt;
          &lt;plugin&gt;
              &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
              &lt;artifactId&gt;maven-ejb-plugin&lt;/artifactId&gt;
              &lt;version&gt;2.3&lt;/version&gt;
              &lt;configuration&gt;
                  &lt;ejbVersion&gt;3.1&lt;/ejbVersion&gt;
              &lt;/configuration&gt;
          &lt;/plugin&gt;
          &lt;plugin&gt;
              &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
              &lt;artifactId&gt;jaxws-maven-plugin&lt;/artifactId&gt;
              &lt;version&gt;1.12&lt;/version&gt;
              &lt;executions&gt;
                  &lt;execution&gt;
                      &lt;goals&gt;
                          &lt;goal&gt;wsimport&lt;/goal&gt;
                      &lt;/goals&gt;
                      &lt;configuration&gt;
                          &lt;keep&gt;true&lt;/keep&gt;
                          &lt;wsdlFiles&gt;
                              &lt;wsdlFile&gt;CenikServices-v2.0.wsdl&lt;/wsdlFile&gt;
                          &lt;/wsdlFiles&gt;
                          &lt;packageName&gt;cz.cpost.esb.cenik.schema&lt;/packageName&gt;
                          &lt;staleFile&gt;${project.build.directory}/jaxws/stale/cenik.stale&lt;/staleFile&gt;
                          &lt;bindingFiles&gt;
                              &lt;bindingFile&gt;${basedir}/src/main/resources/jaxb-bindings.xml&lt;/bindingFile&gt;
                          &lt;/bindingFiles&gt;
                      &lt;/configuration&gt;
                      &lt;id&gt;wsimport-generate-cenik&lt;/id&gt;
                      &lt;phase&gt;generate-sources&lt;/phase&gt;
                  &lt;/execution&gt;
              &lt;/executions&gt;
              &lt;dependencies&gt;
                  &lt;dependency&gt;
                      &lt;groupId&gt;javax.xml&lt;/groupId&gt;
                      &lt;artifactId&gt;webservices-api&lt;/artifactId&gt;
                      &lt;version&gt;1.4&lt;/version&gt;
                  &lt;/dependency&gt;
              &lt;/dependencies&gt;
              &lt;configuration&gt;
                  &lt;sourceDestDir&gt;${project.build.directory}/generated-sources/jaxws-wsimport&lt;/sourceDestDir&gt;
                  &lt;destDir&gt;${project.build.directory}/classes&lt;/destDir&gt;
                  &lt;xnocompile&gt;true&lt;/xnocompile&gt;
                  &lt;verbose&gt;true&lt;/verbose&gt;
                  &lt;extension&gt;true&lt;/extension&gt;
                  &lt;catalog&gt;${basedir}/src/jax-ws-catalog.xml&lt;/catalog&gt;
                  &lt;target&gt;2.0&lt;/target&gt;
              &lt;/configuration&gt;
          &lt;/plugin&gt;
      &lt;/plugins&gt;
  &lt;/build&gt;
  </code></pre>
  
  <p><strong>cache config in mapper configuration:</strong></p>
  
  <pre><code>&lt;cache type="org.mybatis.caches.ehcache.EhcacheCache"&gt;
      &lt;property name="timeToIdleSeconds" value="7200"/&gt;
      &lt;property name="timeToLiveSeconds" value="28800"/&gt;
      &lt;property name="maxElementsInMemory" value="5000"/&gt;
      &lt;property name="maxElementsOnDisk" value="10000"/&gt;
      &lt;property name="memoryStoreEvictionPolicy" value="LRU"/&gt;
   &lt;/cache&gt;
  </code></pre>
  
  <p>I though my sources is not in classpath and I put archive element to ear pom.xml:</p>
  
  <pre><code>&lt;project xmlns="http://maven.apache.org/POM/4.0.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
  &lt;parent&gt;
      &lt;groupId&gt;cz.cpost.esb&lt;/groupId&gt;
      &lt;artifactId&gt;cenikservices-ear&lt;/artifactId&gt;
      &lt;version&gt;2.0&lt;/version&gt;
      &lt;relativePath&gt;../pom.xml&lt;/relativePath&gt;
  &lt;/parent&gt;
  
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;artifactId&gt;ear&lt;/artifactId&gt;
  &lt;packaging&gt;ear&lt;/packaging&gt;
  
  &lt;dependencies&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;${project.groupId}&lt;/groupId&gt;
          &lt;artifactId&gt;cenikservices-ejb&lt;/artifactId&gt;
          &lt;version&gt;${project.version}&lt;/version&gt;
          &lt;type&gt;ejb&lt;/type&gt;
      &lt;/dependency&gt;
  &lt;/dependencies&gt;
  
  &lt;build&gt;
      &lt;plugins&gt;
          &lt;plugin&gt;
              &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
              &lt;artifactId&gt;maven-ear-plugin&lt;/artifactId&gt;
              &lt;version&gt;2.5&lt;/version&gt;
              &lt;configuration&gt;
                  &lt;defaultLibBundleDir&gt;lib&lt;/defaultLibBundleDir&gt;
                  &lt;modules&gt;
                      &lt;ejbModule&gt;
                          &lt;groupId&gt;${project.groupId}&lt;/groupId&gt;
                          &lt;artifactId&gt;cenikservices-ejb&lt;/artifactId&gt;
                      &lt;/ejbModule&gt;
                  &lt;/modules&gt;
                  &lt;archive&gt;
                      &lt;manifest&gt;
                          &lt;addClasspath&gt;true&lt;/addClasspath&gt;
                      &lt;/manifest&gt;
                  &lt;/archive&gt;
              &lt;/configuration&gt;
          &lt;/plugin&gt;
      &lt;/plugins&gt;
  &lt;/build&gt;
  </code></pre>
  
  <p></p>
  
  <p><strong>EAR file structure:</strong></p>
  
  <p><img src="https://i.stack.imgur.com/FYHVv.png" alt="structure of deployed EAR file"></p>
  
  <p>But problem is not solved. Why application could not find generated sources packaged in cenikservices-ejb-2.0.jar?</p>
  
  <hr />
  
  <p><strong>UPDATE</strong></p>
  
  <p>I added lines to my EJB class into its constructor</p>
  
  <pre><code>import org.apache.ibatis.io.Resources;
  ...
  public CenikEJB() {
      Resources.setDefaultClassLoader(this.getClass().getClassLoader());        // added
      this.sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory();
  }
  </code></pre>
  
  <p>but still get the same error on ASURLClassLoader :-(
  I tested, if class CountryType is available in EJB method and it is. I see <strong>SUCCESS</strong> in log.</p>
  
  <pre><code>@Override
  public List&lt;CountryType&gt; listCountry(Integer codeTask, String langAlfaCode) throws CenikFault {
      methodName = "Cenik.listCountry";
  
      SqlSession session = this.sqlSessionFactory.openSession(); 
      try {
          this.getClass().getClassLoader().loadClass("cz.cpost.esb.cenik.schema.CountryType");
          ccpLogger.info( "SUCCESS    - Pokus o nalezeni tridy CountryType vysel");
      } catch (ClassNotFoundException ex) {
          ccpLogger.info("FAIL        - Pokus o nalezeni tridy CountryType nevysel",ex);
      }
  
      try
      {   
          ListCountryType param = this.of.createListCountryType();
          param.setCodeTask(codeTask);
          param.setLangAlfaCode(langAlfaCode);
  
          // ziskat seznam zemi pomoci SQL procedury
          List seznamZemi = session.selectList("Cenik.getListCountry", param);
  
          return seznamZemi; 
      } catch (IllegalArgumentException ex) {
          ccpLogger.error(methodName,ex);
                      ...
  
      } catch (Exception ex) {
          ccpLogger.error(methodName,ex);
                      ...
      } finally { 
          session.close(); 
      } 
  }
  </code></pre>