validar una ubicacion solucion solicitando siguiente seguridad podido permite permisos permiso iniciar firma esta error ejecutara ejecutar certificado bloqueo bloquea aplicacion java exception gwt serialization stack-trace

java - solucion - una aplicacion sin firma de la siguiente ubicacion esta solicitando permiso



Serializar java.lang.Throwable junto con el seguimiento de la pila, provoca cadena y restos de pila relacionados (3)

Estoy escribiendo la aplicación GWT donde necesito enviar instancia de java.lang.Throwable (con la cadena de sus causas y todos los rastreos de pila respectivamente) utilizando GWT RPC que usa el mecanismo de serialización Java estándar (en lo que a mí respecta).

El problema es que cuando paso la siguiente excepción de muestra del cliente :

java.lang.RuntimeException (message=null, stacktrace A) caused by java.io.IOException (message="Problems with io", stacktrace B) caused by java.lang.IllegalStateException (message="Some error text", stacktrace C), cause=null

en el servidor obtengo lo siguiente:

java.lang.RuntimeException (message="java.io.IOException: Problems with io", stacktrace X) cause=this

donde stacktrace X es simplemente un seguimiento de la pila que lleva al lugar donde esta excepción se deserializó en el servidor, es decir, sin tener en cuenta los restos originales de la pila A, B o C. Por lo tanto, la información de la pila se pierde junto con la cadena de causas.

Después de leer el excelente artículo 7 Consejos para el manejo de excepciones en GWT , se descubrió que

el seguimiento de la pila dentro de una excepción es transitorio y, por lo tanto, se pierde de un cliente a otro (por lo tanto, si lo necesita del lado del servidor, envíelo como un parámetro separado)

Después de buscar en Google, llegué a la conclusión de que el tema de la serialización completa / deserialización de instancias de java.lang.Throwable utilizando la técnica de serialización Java estándar no es tan popular . En realidad, no pude encontrar ni bibliotecas ni blogs con una descripción detallada sobre cómo lograr esto.

Alguien ha abordado y resuelto ese problema antes? ¿Hay alguna solución sugerida para este problema?

¡Gracias por adelantado!


Incluso si funciona, no creo que sea aconsejable hacerlo. En la serialización, necesitamos mantener el toque de los elementos adjuntos al objeto y asegurarnos de que, cuando se deserializaron, obtuvieron todas las versiones correctas de las clases que de otro modo fallarían. Por lo tanto, dependiendo del entorno en el que se ejecuta, la pila de excepciones es diferente, plataforma, versión jvm, bibliotecas adicionales diferentes ... Por lo tanto, piense en stacktrace como una instantánea a tiempo para ese entorno y no se puede reintroducir a menos que se restaure el último tiempo para el mismo ambiente. Pero en su requerimiento, es la intención de enviar desde el cliente a un servidor por lo que, ¡esto nunca funcionará! Lo mejor que puedes hacer es capturarlo como una cadena y guardarlo como tal:

public static String getStackTrace(Throwable t) { if (t == null) { return "Exception not available."; } else { StringWriter stackTraceHolder = new StringWriter(); t.printStackTrace(new PrintWriter(stackTraceHolder)); return stackTraceHolder.toString(); } }

Y si no puede usar StringWriter, intente esto:

public static String getStackTrace(Throwable t) { if (t == null) { return "Exception not available."; } else { StringBuilder sb = new StringBuilder(); for (StackTraceElement element : t.getStackTrace()) { sb.append(element.toString()); sb.append("/n"); } return sb.toString(); } }


Ok, encontré una solución elegante y simple para mi problema: en GWT 2.5.1 hay una clase diseñada específicamente para esas necesidades llamada com.google.gwt.core.client.impl.SerializableThrowable con el siguiente JavaDoc:

La clase Throwable emulada no serializa Throwables recursivamente y no serializa el seguimiento de la pila. Esta clase es una alternativa y se puede usar escribiendo un serializador personalizado para la clase que contiene un Throwable. Ver LogRecord_CustomFieldSerializer como ejemplo.

Entonces, el fragmento de código que resuelve mi problema es el siguiente:

// client-side LogServiceAsync logService = GWT.create(LogService.class); GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() { @Override public void onUncaughtException(final Throwable ex) { // wrapping throwable in SerializableThrowable to preserve // causes and stack traces upon serialization SerializableThrowable serializableEx = new SerializableThrowable(ex); // sending instance of SerializableThrowable to server logService.log(serializableEx, callbackCodeDoesntMatter); } } // server-side public class LogServiceServlet extends RemoteServiceServlet implements LogService { @Override public void log(final SerializableThrowable ex) { // getting original instance Throwable with preserved // causes and stack traces Throwable originalThrowable = ex.getThrowable(); originalThrowable.printStackTrace(); } }

Si se implementa de esta manera, imprime la información correcta de rastreo de pila junto con las causas correctas.

NOTA En la clase GWT 2.6.0 , com.google.gwt.core.client.impl.SerializableThrowable está en desuso en favor de com.google.gwt.core.shared.SerializableThrowable, que difiere ligeramente del anterior y debería funcionar de manera similar.


Pruebe RemoteLoggingService para enviar los registros del lado del cliente al servidor. Aquí hay un código de muestra:

web.xml:

<servlet> <servlet-name>remoteLogServlet</servlet-name> <servlet-class>com.x.y.z.server.servlet.GwtRemoteLogging</servlet-class> </servlet> <servlet-mapping> <servlet-name>remoteLogServlet</servlet-name> <url-pattern>/context_path/remote_logging</url-pattern> </servlet-mapping>

GwtRemoteLogging.java:

import java.util.logging.Level; import java.util.logging.LogRecord; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import com.google.gwt.logging.server.StackTraceDeobfuscator; import com.google.gwt.logging.shared.RemoteLoggingService; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import org.apache.log4j.Logger; /** * The Class GwtRemoteLogging. */ @SuppressWarnings("serial") public class GwtRemoteLogging extends RemoteServiceServlet implements RemoteLoggingService { /** The Constant logger. */ private StackTraceDeobfuscator deobfuscator = null; private final static Logger logger = Logger.getLogger("logger_name"); @Override public void init(ServletConfig config) throws ServletException { super.init(config); } /** * Logs a Log Record which has been serialized using GWT RPC on the server. * * @return either an error message, or null if logging is successful. */ public final String logOnServer(LogRecord lr) { try { if (lr.getLevel().equals(Level.SEVERE)) { logger.error(lr.getMessage(),lr.getThrown()); } else if (lr.getLevel().equals(Level.INFO)) { logger.info(lr.getMessage(),lr.getThrown()); } else if (lr.getLevel().equals(Level.WARNING)) { logger.warn(lr.getMessage(),lr.getThrown()); } else if (lr.getLevel().equals(Level.FINE)) { logger.debug(lr.getMessage(),lr.getThrown()); } else { logger.trace(lr.getMessage(),lr.getThrown()); } } catch (Exception e) { logger.error("Remote logging failed", e); return "Remote logging failed, check stack trace for details."; } return null; } /** * By default, this service does not do any deobfuscation. In order to do server side * deobfuscation, you must copy the symbolMaps files to a directory visible to the server and * set the directory using this method. * * @param symbolMapsDir */ public void setSymbolMapsDirectory(String symbolMapsDir) { if (deobfuscator == null) { deobfuscator = new StackTraceDeobfuscator(symbolMapsDir); } else { deobfuscator.setSymbolMapsDirectory(symbolMapsDir); } } }

gwt.xml (heredar registro y establecer propiedades):

<inherits name="com.google.gwt.logging.Logging"/> <set-property name="gwt.logging.logLevel" value="FINE"/> <set-property name="gwt.logging.enabled" value="TRUE"/> <!-- This handler sends log messages to the server, where they will be logged using the server side logging mechanism. --> <set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" /> <!-- Logs by calling method GWT.log. These messages can only be seen in Development Mode in the DevMode window. --> <set-property name="gwt.logging.developmentModeHandler" value="ENABLED" /> <!-- These messages can only be seen in Development Mode in the DevMode window. --> <set-property name="gwt.logging.systemHandler" value="ENABLED" /> <!-- Logs to the popup which resides in the upper left hand corner of application when this handler is enabled. --> <set-property name="gwt.logging.popupHandler" value="DISABLED" /> <!-- Logs to the javascript console, which is used by Firebug Lite (for IE), Safari and Chrome. --> <set-property name="gwt.logging.consoleHandler" value="DISABLED"/> <!-- Logs to the firebug console. --> <set-property name="gwt.logging.firebugHandler" value="DISABLED" />

código del lado del cliente:

public void log(String message,Throwable e) { Logger logger = java.util.logging.Logger.getLogger("class_name"); logger.fine(name + ":" + message); logger.info(name + ":" + message); logger.log(Level.SEVERE, message, e); logger.warning(message); }