Un buen motivo para No utilizar Java 6 en producción

Llevo algunos meses utilizando Java 6, testeando la estabilidad y de paso comprobando la compatibilidad del código de nuestros proyectos con la nueva versión de la plataforma, y hoy me he encontrado con un extraño BUG que descarta Java 6(versión 1.6.0) para entornos de producción.

El problema es fácilmente reproducible al ejecutar el siguiente código, que funciona perfectamente en Java 5 y que lanza una excepción de java.lang.ClassNotFoundException: [Ljava.lang.String; al ser ejecutada en Java6:


public class TestJava6BugClassLoader extends TestCase {
      public void testTest() {
          String[] s = new String[] { "Viavansi" };
          String clName = s.getClass().getName();
          try {
              TestJava6.class.getClassLoader().loadClass(clName);
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
          }
     }
}

El problema esta provocado por una modificación en el funcionamiento del ClassLoader, que hace que en determidanas ocasiones( Ej: al recuperar un Array) el método ClassLoader.forName no localice la clase. La recomendación de Sun es que se utilice el método Class.forName() en vez del ClassLoader.loadClass(). El bug ya ha sido reportado( ids:6446627 , 6466061 , 6500212 ,6434149 ), esta en estudio, y probablemente sea solucionado en la próxima versión de la plataforma.
Por otro lado, los principales proyectos están adaptando su código al nuevo comportamiento del cargador de clases.

En resumen, mientras este bug no este solucionado o hasta que todas las librerías que utilicemos tengan en cuenta la modificación en el comportamiento del cargador de clases. no es recomendable utilizar Java6 para entornos de Producción.

Indico la excepción concreta que me ha llevado a encontrar este problema, por si a alguien mas le es de utilidad, como se puede ver es un bug( o comportamiento extraño) que afecta a todo el proceso de serialización/deserialización.


java.lang.ClassNotFoundException: [Lorg.drools.rule.Declaration;
	at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
	at org.drools.rule.PackageCompilationData$PackageClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
	at org.drools.common.ObjectInputStreamWithLoader.resolveClass(Unknown Source)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1575)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
	at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1624)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1323)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1945)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1869)
	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 java.util.HashMap.readObject(HashMap.java:1029)
	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:1846)
	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.drools.rule.PackageCompilationData.readExternal(Unknown Source)
	at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
	at org.drools.rule.Package.readExternal(Unknown Source)
	at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
	at java.util.HashMap.readObject(HashMap.java:1029)
	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:1846)
	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.drools.common.AbstractRuleBase.doReadExternal(Unknown Source)
	at org.drools.reteoo.ReteooRuleBase.readExternal(Unknown Source)
	at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1945)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1869)
	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 net.sf.ehcache.store.DiskStore.loadElementFromDiskElement(DiskStore.java:283)
	at net.sf.ehcache.store.DiskStore.get(DiskStore.java:238)
	at net.sf.ehcache.Cache.searchInDiskStore(Cache.java:845)
	at net.sf.ehcache.Cache.get(Cache.java:656)
	at net.sf.ehcache.Cache.get(Cache.java:631)
	at com.viavansi.motorreglas.repositorio.simple.RepositorioReglasSimpleImp.getRuleBase(RepositorioReglasSimpleImp.java:112)
	at com.viavansi.motorreglas.repositorio.TestRepositorioSimple.testRepositorioCache(TestRepositorioSimple.java:80)

Comentarios

Comments are closed.