¿Qué significa el mensaje de error de "Intento de división larga o doble en la pila", indican?
-
09-09-2020 - |
Pregunta
Recibo el siguiente error en mi código:
Intento de división larga o doble en la pila
Estoy desorientado sobre el origen de este error y no sabes cómo depurar.¿Qué tipo de problema ¿indica esto?¿Cómo puedo solucionarlo?
[ERROR] [Mon May 23 14:29:46 IST 2011] [(class: org/apache/jsp/dashboard_jsp, method: _jspService signature: (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V) Attempt to split long or double on the stack] [10.97.34.222] hddlntdsz2350 [ session not set ]
java.lang.VerifyError: (class: org/apache/jsp/dashboard_jsp, method: _jspService signature: (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V) Attempt to split long or double on the stack
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
at java.lang.Class.getConstructor0(Class.java:2699)
at java.lang.Class.newInstance0(Class.java:326)
at java.lang.Class.newInstance(Class.java:308)
at org.jboss.web.tomcat.service.TomcatInjectionContainer.newInstance(TomcatInjectionContainer.java:273)
Código De Problema :He creado un Modelo como se indica a continuación
public class DashboardViewModel implements Serializable {
/** defalut serialization id */
private static final long serialVersionUID = 1L;
/**
* Collection representing all the services
*/
private Map<Long, ServiceCustomerModel> serviceDataMap;
}
En una determinada página JSP, estoy haciendo lo siguiente.
for (Long serviceId : dashboardViewModel.getServices()) {
Service service = dashboardViewModel.getService(serviceId);
}
El getServices
método en el por encima del objetivo de la clase es la siguiente.
public Set<Long> getServices() {
return this.serviceDataMap.keySet();
}
Cuando se incluye el código anterior en el jsp.Me pongo el error.De lo contrario, funciona.
Más Investigataions :
He actualizado el tablero de instrumentos.archivo jsp con el siguiente fragmento de código.Yo no soy capaz de identificar el por qué, Pero este código es de trabajo.
ArrayList<Long> test = new ArrayList<Long>();
test.addAll(dashboardViewModel.getServices());
for (long serviceId : test) {
Service service = dashboardViewModel.getService(serviceId);
}
¿Este código hace alguna diferencia en los datos?
Solución
La máquina virtual Java realiza una verificación adicional sobre las operaciones que involucran tipos de datos largos y dobles, para el Muy simple razón de que
un valor de tipo largo o tipo doble ocupa dos locales consecutivos Variables. Tal valor solo puede ser Dirigido utilizando el índice menor. Para Ejemplo, un valor de tipo doble almacenado en la matriz de variables local en el índice n En realidad ocupa las variables locales. con los índices N y N +1; sin embargo, el La variable local en el índice n +1 no puede ser cargado de. Puede ser almacenado en. Sin embargo, hacerlo invalida el Contenido de la variable local n.
Cuando el verificador determina que se usa una instrucción incorrecta para acceder a una variable larga o doble (por ejemplo, una instrucción que intenta tratar la variable local en el índice N, como un entero o un flotador, que divide el doble / largo variable), luego se marca dicho error.
No se puede hacer mucho en este caso, excepto para arreglar el generador de código de byteCode que generó este código de bytes. Este puede ser el propio compilador de Java, o cualquiera de los marcos de manipulación de código de bytes como ASM, CGLIB o Javassist.
Editar:
Después de ver el StackTrace, parece que la clase en cuestión ocurre un servlet generado (desde Dashboard.jsp). Valía la pena verificar si una actualización del JDK que involucra la compilación del JSP traducido resolverá el problema.
Otros consejos
Este parece ser un error de verificación que indica que el código de byte que se está cargando no es completamente compatible con su VM / Compilador.Lo más probable es que venga de la biblioteca externa. que use o puede generarse en el proceso de su construcción e indicar un error.
¿Usas (directa o indirectamente) cualquier código de bytecode generado?A menudo se usa con AOP.
También Google le da muchos hits para este error.Léalos, vea si algo se ajusta a la factura.
Puedo pensar en un caso que implica AutoBoxing: ¿Está intentando usar AutoBoxing para almacenar los flotadores?Si estos terminan automáticamente en doble, cuando se retira de la pila (posiblemente debido a un error de JVM) porque el flotador toma menos bytes que el doble de la verificación del tamaño de byte falla y este error se emite.Este parece ser el caso de OpenJDK que mira (algunos de) su código fuente, supongo que lo mismo se aplicaría al sol (lo siento, ¡Oracle!) JDK.
Este es un mensaje de un java.lang.VerifyError
, que se produce cuando el "verificador" detecta que un archivo de clase, aunque bien formado, contiene algún tipo de incoherencia interna o problemas de seguridad.
La JVM especificación de notas (4.4.5):
Todos los 8 bytes constantes tomar hasta dos entradas en el
constant_pool
la tabla de la clase de archivo.Si unCONSTANT_Long_info
oCONSTANT_Double_info
la estructura es el elemento en elconstant_pool
tabla de índice n, entonces el siguiente artículo utilizable en la piscina se encuentra ubicada en el índice den+2
.Elconstant_pool
índicen+1
debe ser válido, pero se considera inservible.
Así que, en realidad, supongo, que en la clase de archivo que tiene una constante de la piscina que se rompe esta regla.Esto no (no) ocurrir con un compilador de java, pero hay más formas de crear y modificar classfiles (AOP, BCEL, ofuscación o otros lenguajes de programación).Trate de obtener un stacktrace, se debe dar una pista a los infractores classfile.
Leer Más
¿Se puede reparar el problema cambiando su código:
for (long serviceId : test) {
Service service = dashboardViewModel.getService(serviceId);
}
en:
for (Long serviceId : test) {
Service service = dashboardViewModel.getService(serviceId);
}