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

Posteado por Felix G. Borrego el 2 de Marzo de 2007

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)
Comparte esta entrada:
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Meneame
  • RSS
  • Twitter


Escriba un comentario

Tomate un momento para comentar y contar lo que piensas sobre el post. Puedes usar un HTML básico para formatear

Comentarios leidos

Ya esta tardando el API de compatibilidad que prometen para Java7…

Gracias por el post, me he encontrado con el problema en preproducción, que susto. Merci. ;-)