[rfc] [icedtea-web] better error reporting for LaunchException in plugin
Adam Domurad
adomurad at redhat.com
Tue Jan 29 08:01:09 PST 2013
On 01/21/2013 06:35 AM, Jiri Vanek wrote:
> Launch errors are thrown from netx, and printed out .. somewhere. At
> the end plugin (correctly) fails with NPE.
> It Is not nice. Eg in SplashError dialogue they can not be shown.
>
> I have added static accumulator for LaunchErrors (== all errors
> preceding npe in plugin) and then I'm adding this chain of exception
> to Splash error report.
>
> It is quite useful - see example - but there is one pitfall. As
> accumulator being static, it is cumulating errors from all running
> applets :(
> However I have not found a way how to distinguish between individual
> applets :( (any idea welcomed!)
Hmm. Well each applet has an associated thread-group -- you could use
that to determine the current applet.
As well, I do not like adding a static accumulator to each constructor
-- I would prefer a special launch error utility class that is always
used, that takes a JNLPFile (in cases where its available) -or- tries to
determine one by the current ThreadGroup. This will unfortunately need
some additional 'infrastructure'.
> I have added small warkaround with timestamps and localised
> explanation.. and.. it is still better then nothing :)
>
>
> J.
I know you want this in as 'better than nothing' but it does seem too
hackish to me :-/ IMO constructors should not have such side-effects.
However I am all for LaunchException's capturing a time-stamp in their
constructor.
>
>
> **example**
>
> So now instead of plain, nothing saying
> "IcedTea-Web Plugin version: 1.4pre+rb646c8b9c2e2+
> Mon Jan 21 12:29:17 CET 2013
> java.lang.NullPointerException
> at net.sourceforge.jnlp.NetxPanel.runLoader(NetxPanel.java:130)
> at sun.applet.AppletPanel.run(AppletPanel.java:380)
> at java.lang.Thread.run(Thread.java:679)"
>
> Is there:
>
> IcedTea-Web Plugin version: 1.4pre+rb646c8b9c2e2+
> Mon Jan 21 12:29:17 CET 2013
> java.lang.NullPointerException
> at net.sourceforge.jnlp.NetxPanel.runLoader(NetxPanel.java:130)
> at sun.applet.AppletPanel.run(AppletPanel.java:380)
> at java.lang.Thread.run(Thread.java:679)
>
> Chain:
> 1) at Mon Jan 21 12:27:27 CET 2013
> net.sourceforge.jnlp.LaunchException: Fatal: Application Error: The
> applet was unsigned. The applet was unsigned, and the security policy
> prevented it from running.
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.initializeResources(JNLPClassLoader.java:680)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.<init>(JNLPClassLoader.java:240)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:374)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:347)
> at net.sourceforge.jnlp.Launcher.createApplet(Launcher.java:751)
> at net.sourceforge.jnlp.Launcher.getApplet(Launcher.java:713)
> at net.sourceforge.jnlp.Launcher$TgThread.run(Launcher.java:942)
> 2) at Mon Jan 21 12:27:27 CET 2013
> net.sourceforge.jnlp.LaunchException: Fatal: Initialization Error:
> Could not initialize applet.
> at net.sourceforge.jnlp.Launcher.createApplet(Launcher.java:784)
> at net.sourceforge.jnlp.Launcher.getApplet(Launcher.java:713)
> at net.sourceforge.jnlp.Launcher$TgThread.run(Launcher.java:942)
> Caused by: net.sourceforge.jnlp.LaunchException: Fatal: Application
> Error: The applet was unsigned. The applet was unsigned, and the
> security policy prevented it from running.
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.initializeResources(JNLPClassLoader.java:680)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.<init>(JNLPClassLoader.java:240)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:374)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:347)
> at net.sourceforge.jnlp.Launcher.createApplet(Launcher.java:751)
> ... 2 more
> 3) at Mon Jan 21 12:27:29 CET 2013
> net.sourceforge.jnlp.LaunchException: Fatal: Application Error: The
> applet was unsigned. The applet was unsigned, and the security policy
> prevented it from running.
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.initializeResources(JNLPClassLoader.java:680)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.<init>(JNLPClassLoader.java:240)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:374)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:347)
> at net.sourceforge.jnlp.Launcher.createApplet(Launcher.java:751)
> at net.sourceforge.jnlp.Launcher.getApplet(Launcher.java:713)
> at net.sourceforge.jnlp.Launcher$TgThread.run(Launcher.java:942)
> 4) at Mon Jan 21 12:27:29 CET 2013
> net.sourceforge.jnlp.LaunchException: Fatal: Initialization Error:
> Could not initialize applet.
> at net.sourceforge.jnlp.Launcher.createApplet(Launcher.java:784)
> at net.sourceforge.jnlp.Launcher.getApplet(Launcher.java:713)
> at net.sourceforge.jnlp.Launcher$TgThread.run(Launcher.java:942)
> Caused by: net.sourceforge.jnlp.LaunchException: Fatal: Application
> Error: The applet was unsigned. The applet was unsigned, and the
> security policy prevented it from running.
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.initializeResources(JNLPClassLoader.java:680)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.<init>(JNLPClassLoader.java:240)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:374)
> at
> net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:347)
> at net.sourceforge.jnlp.Launcher.createApplet(Launcher.java:751)
> ... 2 more
>
Comments inline.
> diff -r b646c8b9c2e2 netx/net/sourceforge/jnlp/LaunchException.java
> --- a/netx/net/sourceforge/jnlp/LaunchException.java Fri Jan 18
> 12:49:37 2013 +0100
> +++ b/netx/net/sourceforge/jnlp/LaunchException.java Mon Jan 21
> 12:20:20 2013 +0100
> @@ -16,6 +16,10 @@
>
> package net.sourceforge.jnlp;
>
> +import java.util.Date;
> +import java.util.LinkedList;
> +import java.util.List;
> +
> /**
> * Thrown when a JNLP application, applet, or installer could not
> * be created.
> @@ -25,6 +29,29 @@
> */
> public class LaunchException extends Exception {
>
> +
> + public static class LaunchExceptionWithStamp{
> + private final LaunchException ex;
> + private final Date stamp;
> +
> + private LaunchExceptionWithStamp(LaunchException ex) {
> + this.ex=ex;
> + this.stamp=new Date();
> + }
> +
> + public LaunchException getEx() {
> + return ex;
> + }
> +
> + public Date getStamp() {
> + return stamp;
> + }
> +
> +
> +
> + }
> + public static final List<LaunchExceptionWithStamp>
> launchExceptionChain = new LinkedList<LaunchExceptionWithStamp>();
> +
> private static final long serialVersionUID = 7283827853612357423L;
>
> /** the file being launched */
> @@ -54,6 +81,7 @@
> this.summary = summary;
> this.description = description;
> this.severity = severity;
> + saveLaunchException(this);
Bit too much of a hack, for me.
> }
>
> /**
> @@ -61,6 +89,7 @@
> */
> public LaunchException(Throwable cause) {
> super(cause);
> + saveLaunchException(this);
> }
>
> /**
> @@ -68,6 +97,7 @@
> */
> public LaunchException(String message, Throwable cause) {
> super(message, cause);
> + saveLaunchException(this);
> }
>
> /**
> @@ -78,6 +108,7 @@
> */
> public LaunchException(String message) {
> super(message);
> + saveLaunchException(this);
> }
>
> /**
> @@ -117,4 +148,9 @@
> return severity;
> }
>
> + private void saveLaunchException(LaunchException ex) {
Should be synchronized, surely ?
> + launchExceptionChain.add(new LaunchExceptionWithStamp(ex));
> +
> + }
> +
> }
> diff -r b646c8b9c2e2
> netx/net/sourceforge/jnlp/resources/Messages.properties
> --- a/netx/net/sourceforge/jnlp/resources/Messages.properties Fri Jan
> 18 12:49:37 2013 +0100
> +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties Mon Jan
> 21 12:20:20 2013 +0100
> @@ -478,3 +478,4 @@
> SPLASHdefaultHomepage = Unspecified homepage, verify source rather
> SPLASHerrorInInformation = Error during loading of information
> element, verify source rather
> SPLASHmissingInformation = Information element is missing, verify
> source rather
> +SPLASHchainWas = There is list of exceptions which provided start of
> you applet. Please note, those exceptions can be from multiple
> applets. For good bug report, it is wothy to run your applet isolated.
Hm, s/wothy/worthy/, but probably better is:
'This is the list of exceptions that occurred launching your applet' ...
'For a good bug report, be sure to run only one applet.'
> diff -r b646c8b9c2e2
> netx/net/sourceforge/jnlp/resources/Messages_cs_CZ.properties
> --- a/netx/net/sourceforge/jnlp/resources/Messages_cs_CZ.properties
> Fri Jan 18 12:49:37 2013 +0100
> +++ b/netx/net/sourceforge/jnlp/resources/Messages_cs_CZ.properties
> Mon Jan 21 12:20:20 2013 +0100
> @@ -468,4 +468,5 @@
> SPLASHanotherInfo= Dal\u0161\u00ed dostupn\u00e9 informace
> SPLASHdefaultHomepage = Nespecifikovan\u00e1 domovsk\u00e1
> st\u00e1nka, je doporu\u010deno zkontrolovat zdroj
> SPLASHerrorInInformation = Chyba na\u010d\u00edt\u00e1n\u00ed
> informa\u010dn\u00edho elementu, je doporu\u010deno zkontrolovat zdroj
> -SPLASHmissingInformation = Informa\u010dn\u00ed element chyb\u00fd,
> je doporu\u010deno zkontrolovat zdroj
> \ No newline at end of file
> +SPLASHmissingInformation = Informa\u010dn\u00ed element chyb\u00fd,
> je doporu\u010deno zkontrolovat zdroj
> +SPLASHchainWas = N\u00ed\u017ee je seznam v\u00fdjimek, kter\u00e9
> prov\u00e1zely start appeltu. Tento seznam ale m\u016f\u017er
> poch\u00e1zet z n\u011bkolik\u00e1 r\u016fzn\u00fdch applet\u016f. Pro
> dob\u00e9 chybo\u00e9 hl\u00e1\u0161en\u00ed stoj\u00e9 za to pustit
> applet izolovane.
> \ No newline at end of file
> diff -r b646c8b9c2e2
> netx/net/sourceforge/jnlp/splashscreen/parts/JEditorPaneBasedExceptionDialog.java
> ---
> a/netx/net/sourceforge/jnlp/splashscreen/parts/JEditorPaneBasedExceptionDialog.java
> Fri Jan 18 12:49:37 2013 +0100
> +++
> b/netx/net/sourceforge/jnlp/splashscreen/parts/JEditorPaneBasedExceptionDialog.java
> Mon Jan 21 12:20:20 2013 +0100
> @@ -42,6 +42,8 @@
> import java.awt.event.WindowEvent;
> import java.io.PrintWriter;
> import java.io.StringWriter;
> +import java.text.DateFormat;
> +import java.util.Date;
> import java.util.List;
> import javax.swing.BorderFactory;
> import javax.swing.GroupLayout;
> @@ -60,6 +62,7 @@
> import javax.swing.WindowConstants;
> import javax.swing.event.HyperlinkEvent;
> import javax.swing.event.HyperlinkListener;
> +import net.sourceforge.jnlp.LaunchException;
> import net.sourceforge.jnlp.runtime.Translator;
>
> public class JEditorPaneBasedExceptionDialog extends JDialog
> implements HyperlinkListener {
> @@ -78,15 +81,19 @@
> // End of components declaration
> private final String message;
> private final Throwable exception;
> + private final Date shown;
> + private final String anotherInfo;
>
> /** Creates new form JEditorPaneBasedExceptionDialog */
> public JEditorPaneBasedExceptionDialog(java.awt.Frame parent,
> boolean modal, Throwable ex, InformationElement information, String
> anotherInfo) {
> super(parent, modal);
> + shown = new Date();
> initComponents();
> htmlErrorAndHelpPanel.setContentType("text/html");
> htmlErrorAndHelpPanel.setEditable(false);
> + this.anotherInfo=anotherInfo;
> List<String> l = infoElementToList(information);
> - this.message = getText(ex, l, anotherInfo);
> + this.message = getText(ex, l, anotherInfo, shown);
> this.exception = ex;
> if (exception == null) {
> closeAndCopyButton.setVisible(false);
> @@ -199,7 +206,7 @@
> private void
> copyAndCloseButtonActionPerformed(java.awt.event.ActionEvent evt) {
> if (exception != null) {
> try {
> - StringSelection data = new
> StringSelection(getExceptionStackTraceAsString(exception));
> + StringSelection data = new
> StringSelection(anotherInfo+"\n"+shown.toString()+"\n"+getExceptionStackTraceAsString(exception)+addPlainChain());
> Clipboard clipboard =
> Toolkit.getDefaultToolkit().getSystemClipboard();
> clipboard.setContents(data, data);
> } catch (Exception ex) {
> @@ -241,7 +248,7 @@
> });
> }
>
> - static String getText(Throwable ex, List<String> l, String
> anotherInfo) {
> + static String getText(Throwable ex, List<String> l, String
> anotherInfo,Date shown) {
> StringBuilder s = new StringBuilder("<html><body>");
> String info = "<p>"
> + Translator.R(InfoItem.SPLASH + "mainL1", createLink())
> @@ -258,9 +265,11 @@
> + Translator.R(InfoItem.SPLASH + "mainL4")
> + " </p>\n"
> + info + formatListInfoList(l) +
> formatInfo(anotherInfo)
> + +"<br>"+DateFormat.getInstance().format(shown)+"<br>"
> + "<p>"
> + Translator.R(InfoItem.SPLASH + "exWas")
> - + " <br/>\n" + "<pre>" +
> getExceptionStackTraceAsString(ex) + "</pre>";
> + + " <br/>\n" + "<pre>" +
> getExceptionStackTraceAsString(ex) + "</pre>"
> + + addChain();
>
>
> } else {
> @@ -354,4 +363,47 @@
> }
>
>
> + private static String addChain() {
> + if (LaunchException.launchExceptionChain.isEmpty()) {
> + return "";
> + }
> + return Translator.R(InfoItem.SPLASH + "chainWas")
> + + " <br/>\n" + "<pre>" + getChainAsString(true) +
> "</pre>";
> +
> + }
> +
> + private static String addPlainChain() {
> + if (LaunchException.launchExceptionChain.isEmpty()) {
> + return "";
> + }
> + return "\n Chain: \n" + getChainAsString(false);
> +
> + }
> +
> + private static String getChainAsString(boolean formatTime) {
> + return getChainAsString(LaunchException.launchExceptionChain,
> formatTime);
> + }
> +
> + private static String
> getChainAsString(List<LaunchException.LaunchExceptionWithStamp>
> launchExceptionChain, boolean formatTime) {
> + String s = "";
> + if (launchExceptionChain != null) {
> + int i = 0;
> + for (LaunchException.LaunchExceptionWithStamp
> launchException : launchExceptionChain) {
> + i++;
> + s = s + i + ") at " +
> formatTime(launchException.getStamp(), formatTime) + "\n" +
> getExceptionStackTraceAsString(launchException.getEx());
> + }
> + }
> + return s;
> + }
> +
> + private static String formatTime(Date dateTime, boolean formatTime) {
> + if (dateTime == null) {
> + return "unknown time";
> + }
> + if (formatTime) {
> + return DateFormat.getInstance().format(dateTime);
> + } else {
> + return dateTime.toString();
> + }
> + }
> }
More information about the distro-pkg-dev
mailing list