changeset 1493:7f00f3fc1cf6

reworked showDocument logic * netx/net/sourceforge/jnlp/config/BasicValueValidators.java: added special validator for browser * netx/net/sourceforge/jnlp/config/Defaults.java: used this validator * netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java: declared browser's constants and environment variable * netx/net/sourceforge/jnlp/resources/Messages.properties: removed invalid lines, added new lines * netx/net/sourceforge/jnlp/resources/Messages_cs.properties: removed invalid lines, * netx/net/sourceforge/jnlp/resources/Messages_de.properties: removed invalid lines, * netx/net/sourceforge/jnlp/resources/Messages_pl.properties: removed invalid lines, * netx/net/sourceforge/jnlp/runtime/AppletEnvironment.java: showDocument now works * netx/net/sourceforge/jnlp/runtime/Translator.java: added shortcut method to call call VVPossibleBrowserValues * netx/net/sourceforge/jnlp/runtime/html/browser/LinkingBrowser.java: split creation from stand alone launch * netx/net/sourceforge/jnlp/services/XBasicService.java: fully reworked showDocument. Focus on standard desktop api and customization * tests/reproducers/signed/ShowDocument/resources/ShowDocumentApplet.jnlp: test jnlp for applet's context.showDocument * tests/reproducers/signed/ShowDocument/resources/ShowDocumentMain.jnlp: test jnlp for application's basicService.showDocument * tests/reproducers/signed/ShowDocument/resources/document.txt: document to be shown in test * tests/reproducers/signed/ShowDocument/srcs/ShowDocument.java: body of applet/jnlp-app * tests/reproducers/signed/ShowDocument/testcases/ShowDocumentTest.java: two testcases - one for applet, second for app. Both running on headless.
author Jiri Vanek <jvanek@redhat.com>
date Fri, 12 Oct 2018 13:30:42 +0200
parents 4c5b1717ab43
children e19639f572c4
files ChangeLog netx/net/sourceforge/jnlp/config/BasicValueValidators.java netx/net/sourceforge/jnlp/config/Defaults.java netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java netx/net/sourceforge/jnlp/resources/Messages.properties netx/net/sourceforge/jnlp/resources/Messages_cs.properties netx/net/sourceforge/jnlp/resources/Messages_de.properties netx/net/sourceforge/jnlp/resources/Messages_pl.properties netx/net/sourceforge/jnlp/runtime/AppletEnvironment.java netx/net/sourceforge/jnlp/runtime/Translator.java netx/net/sourceforge/jnlp/runtime/html/browser/LinkingBrowser.java netx/net/sourceforge/jnlp/services/XBasicService.java tests/reproducers/signed/ShowDocument/resources/ShowDocumentApplet.jnlp tests/reproducers/signed/ShowDocument/resources/ShowDocumentMain.jnlp tests/reproducers/signed/ShowDocument/resources/document.txt tests/reproducers/signed/ShowDocument/srcs/ShowDocument.java tests/reproducers/signed/ShowDocument/testcases/ShowDocumentTest.java
diffstat 17 files changed, 677 insertions(+), 146 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Oct 02 10:36:29 2018 +0200
+++ b/ChangeLog	Fri Oct 12 13:30:42 2018 +0200
@@ -1,3 +1,23 @@
+2018-10-12  Jiri Vanek <jvanek@redhat.com>
+
+	reworked showDocument logic
+	* netx/net/sourceforge/jnlp/config/BasicValueValidators.java: added special validator for browser
+	* netx/net/sourceforge/jnlp/config/Defaults.java: used this validator
+	* netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java: declared browser's constants and environment variable
+	* netx/net/sourceforge/jnlp/resources/Messages.properties: removed invalid lines, added new lines
+	* netx/net/sourceforge/jnlp/resources/Messages_cs.properties: removed invalid lines,
+	* netx/net/sourceforge/jnlp/resources/Messages_de.properties: removed invalid lines,
+	* netx/net/sourceforge/jnlp/resources/Messages_pl.properties: removed invalid lines,
+	* netx/net/sourceforge/jnlp/runtime/AppletEnvironment.java: showDocument now works
+	* netx/net/sourceforge/jnlp/runtime/Translator.java: added shortcut method to call call VVPossibleBrowserValues
+	* netx/net/sourceforge/jnlp/runtime/html/browser/LinkingBrowser.java: split creation from stand alone launch
+	* netx/net/sourceforge/jnlp/services/XBasicService.java: fully reworked  showDocument. Focus on standard desktop api and customization
+	* tests/reproducers/signed/ShowDocument/resources/ShowDocumentApplet.jnlp: test jnlp for applet's context.showDocument
+	* tests/reproducers/signed/ShowDocument/resources/ShowDocumentMain.jnlp: test jnlp for application's  basicService.showDocument
+	* tests/reproducers/signed/ShowDocument/resources/document.txt: document to be shown in test
+	* tests/reproducers/signed/ShowDocument/srcs/ShowDocument.java: body of applet/jnlp-app
+	* tests/reproducers/signed/ShowDocument/testcases/ShowDocumentTest.java: two testcases - one for applet, second for app. Both running on headless.
+
 2018-09-26  Jiri Vanek <jvanek@redhat.com>
 
 	Allowed itw-settings to be opened from viewer
--- a/netx/net/sourceforge/jnlp/config/BasicValueValidators.java	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/config/BasicValueValidators.java	Fri Oct 12 13:30:42 2018 +0200
@@ -45,6 +45,7 @@
 import java.net.URL;
 import java.util.Arrays;
 import java.util.Locale;
+import net.sourceforge.jnlp.runtime.Translator;
 
 /**
  * Provides {@link ValueValidator} implementations for some common value types
@@ -327,6 +328,52 @@
     public static ValueValidator getFilePathValidator() {
         return new FilePathValidator();
     }
+    
+     public static ValueValidator getBrowserPathValidator() {
+        return new ValueValidator() {
+            @Override
+            public void validate(Object value) throws IllegalArgumentException {
+                if (value == null) {
+                    return;
+                }
+                if (!(value instanceof String)) {
+                    throw new IllegalArgumentException("Value should be string!");
+                }
+               if (verifyFileOrCommand((String)value) == null){
+                    //jsut warn?
+                    throw new IllegalArgumentException("Value should be file, or on PATH, or known keyword. See possible values.");
+               }
+            }
+
+            @Override
+            public String getPossibleValues() {
+                return Translator.VVPossibleBrowserValues();
+            }
+        };
+    }
+     
+      public static String verifyFileOrCommand(String cmd) {
+        cmd = cmd.split("\\s+")[0];
+          if (cmd.equals(DeploymentConfiguration.ALWAYS_ASK) || cmd.equals(DeploymentConfiguration.INTERNAL_HTML)) {
+              return "keyword";
+          }
+        File fileCandidate = new File(cmd);
+        if (fileCandidate.exists() && !fileCandidate.isDirectory()) {
+            return cmd;
+        }
+        String path = System.getenv("PATH");
+        if (path != null) {
+            String[] pathMembers = path.split(File.pathSeparator);
+            for (String s : pathMembers) {
+                File pathCandidate = new File(s, cmd);
+                if (pathCandidate.exists() && !pathCandidate.isDirectory()) {
+                    return pathCandidate.toString();
+                }
+            }
+        }
+        return null;
+    }
+
 
     /**
      * Returns a {@link ValueValidator} that checks if an object represents a
--- a/netx/net/sourceforge/jnlp/config/Defaults.java	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/config/Defaults.java	Fri Oct 12 13:30:42 2018 +0200
@@ -403,7 +403,7 @@
                 /* browser selection */
                 {
                         DeploymentConfiguration.KEY_BROWSER_PATH,
-                        BasicValueValidators.getFilePathValidator(),
+                        BasicValueValidators.getBrowserPathValidator(),
                         null
                 },
                 /* check for update timeout */
--- a/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java	Fri Oct 12 13:30:42 2018 +0200
@@ -221,6 +221,13 @@
     public static final String KEY_AUTO_DOWNLOAD_JRE = "deployment.javaws.autodownload";
 
     public static final String KEY_BROWSER_PATH = "deployment.browser.path";
+    //for legacy reasons, also $BROWSER variable is supported
+    public static final String BROWSER_ENV_VAR = "BROWSER";
+    // both browser.path and BROWSER can ave those for-fun keys:
+    public static final String ALWAYS_ASK="ALWAYS-ASK";
+    public static final String INTERNAL_HTML="INTERNAL-HTML";
+    public static final String LEGACY_WIN32_URL__HANDLER="rundll32 url.dll,FileProtocolHandler ";
+    
     public static final String KEY_UPDATE_TIMEOUT = "deployment.javaws.update.timeout";
     
     public static final String IGNORE_HEADLESS_CHECK = "deployment.headless.ignore";
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/resources/Messages.properties	Fri Oct 12 13:30:42 2018 +0200
@@ -254,9 +254,7 @@
 RPRoxyPacNotSupported=Using Proxy Auto Config (PAC) files is not supported.
 RProxyFirefoxNotFound=Unable to use Firefox''s proxy settings. Using "DIRECT" as proxy type.
 RProxyFirefoxOptionNotImplemented=Browser proxy option "{0}" ({1}) not supported yet.
-RBrowserLocationPromptTitle=Browser Location
-RBrowserLocationPromptMessage=Specify Browser Location
-RBrowserLocationPromptMessageWithReason=Specify Browser Location (the browser command "{0}" is invalid).
+RBrowserLocationPromptTitle=Please select handler (browser) for this url:
 HTMLnoneFound=No applet found on this html page (supported are object, embed and applet tags)
 HTMLmoreThenOne=More then one ({0}) applets found. Using  first. You can specify ''all'' or numbers to specify applets you want to run.
 
@@ -583,6 +581,15 @@
 VVPossibleFileValues=include an absolute path to a file or directory
 VVPossibleRangedIntegerValues=are in range {0} to {1} (inclusive)
 VVPossibleUrlValues=include any valid url (eg. http://icedtea.classpath.org/hg/)
+VVPossibleBrowserValues=Set path to browser or any command launching url. If not set, default browser is used. If default browser is not available, you will be be prompted to provide URL consumer. \
+Eg: firefox, or (windows) {0}, microsoft-edge, (mac) safari, xdg-open (linux) like commands. \
+In headless mode you can use wget, curl or lynx. It can be also javaws itself to launch other jnlp. \
+You can set yor custom browser via {4} property. ${1} environment variable is serving same purpose. \
+You can use keyword {2} to launch internal browser. But be warned, it is terrible. Use {3} to enforce prompt each time instead of using defaults.
+VVBrowserVerificationPass=Verification Ok: {0}
+VVBrowserVerificationFail=Verification failed. See examples!
+VVBrowserSaveNotAllowed=You have set {0} as value for {1}. Can't overwrite.
+VVBrowserSaveAllowed=Will save your selection as {0}
 
 # Control Panel - Main
 CPMainDescriptionShort=Configure IcedTea-Web
--- a/netx/net/sourceforge/jnlp/resources/Messages_cs.properties	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/resources/Messages_cs.properties	Fri Oct 12 13:30:42 2018 +0200
@@ -233,8 +233,6 @@
 RProxyFirefoxNotFound=Nelze pou\u017e\u00edt nastaven\u00ed proxy server\u016f prohl\u00ed\u017ee\u010de Firefox. Je pou\u017eito nastaven\u00ed bez proxy serveru (DIRECT).
 RProxyFirefoxOptionNotImplemented=Mo\u017enost nastaven\u00ed proxy serveru prohl\u00ed\u017ee\u010de {0} ({1}) je\u0161t\u011b nen\u00ed podporov\u00e1na.
 RBrowserLocationPromptTitle=Um\u00edst\u011bn\u00ed prohl\u00ed\u017ee\u010de
-RBrowserLocationPromptMessage=Zadejte um\u00edst\u011bn\u00ed prohl\u00ed\u017ee\u010de.
-RBrowserLocationPromptMessageWithReason=Zadejte um\u00edst\u011bn\u00ed prohl\u00ed\u017ee\u010de (p\u0159\u00edkaz prohl\u00ed\u017ee\u010de {0} je neplatn\u00fd).
 HTMLnoneFound=Na t\u00e9to str\u00e1nce html nebyl nalezen \u017e\u00e1dn\u00fd aplet (podporov\u00e1ny jsou zna\u010dky \u201eobject\u201c, \u201eembed\u201c a \u201eapplet\u201c).
 HTMLmoreThenOne=Bylo nalezeno v\u00edce aplet\u016f ({0}). Pou\u017eije se prvn\u00ed. M\u016f\u017eete specifikovat \u010d\u00edsla aplet\u016f nebo pou\u017e\u00edt volbu \u201ev\u0161echny\u201c (all) a vybrat tak, kter\u00e9 aplety chcete spustit.
 
--- a/netx/net/sourceforge/jnlp/resources/Messages_de.properties	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/resources/Messages_de.properties	Fri Oct 12 13:30:42 2018 +0200
@@ -252,8 +252,6 @@
 RProxyFirefoxNotFound=Es ist nicht m\u00f6glich Firefoxs Proxyeinstellungen zu verwenden. Nutze \u201eDIRECT\u201c als Proxytyp.
 RProxyFirefoxOptionNotImplemented=Browserproxyoption \u201e{0}\u201c ({1}) wird noch nicht unterst\u00fctzt.
 RBrowserLocationPromptTitle=Browserort
-RBrowserLocationPromptMessage=Bitte den Ort des Browsers angeben
-RBrowserLocationPromptMessageWithReason=Bitte den Ort des Browsers angeben (der Browserbefehl \u201e{0}\u201c ist ung\u00fcltig).
 HTMLnoneFound=Es wurde kein Applet auf dieser HTML-Seite gefunden (unterst\u00fctzt werden die Elemente \u201eOBJECT\u201c, \u201eEMBED\u201c und \u201eAPPLET\u201c).
 HTMLmoreThanOne=Mehr als ein ({0}) Applet wurde gefunden. Das erste Applet wird ausgef\u00fchrt. Mit der Angabe von \u201eall\u201c oder Zahlen k\u00f6nnen die gew\u00fcnschten Applets f\u00fcr die Ausf\u00fchrung angegeben werden.
 
--- a/netx/net/sourceforge/jnlp/resources/Messages_pl.properties	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/resources/Messages_pl.properties	Fri Oct 12 13:30:42 2018 +0200
@@ -232,8 +232,6 @@
 RProxyFirefoxNotFound=Nie mo\u017cna u\u017cy\u0107 ustawie\u0144 proxy Firefox-a. Zastosowano \u201eDIRECT\u201d jako typ proxy.
 RProxyFirefoxOptionNotImplemented=Opcja proxy \u201e{0}\u201d ({1}) przegl\u0105darki jeszcze nie jest obs\u0142ugiwana.
 RBrowserLocationPromptTitle=Lokalizacja przegl\u0105darki
-RBrowserLocationPromptMessage=Podaj lokalizacj\u0119 przegl\u0105darki
-RBrowserLocationPromptMessageWithReason=Podaj lokalizacj\u0119 przegl\u0105darki (polecenie \u201e{0}\u201d jest nieprawid\u0142owe).
 BFileInfoAuthors=Nazwiska i adresy poczty elektronicznej zas\u0142u\u017conych dla tego projektu umieszczono w pliku AUTHORS, znajduj\u0105cym si\u0119 w katalogu g\u0142\u00f3wnym IcedTea-Web.
 BFileInfoCopying=Kompletny egzemplarz licencji GPLv2 tego projektu umieszczono w pliku COPYING, znajduj\u0105cym si\u0119 w katalogu g\u0142\u00f3wnym IcedTea-Web.
 BFileInfoNews=Nowo\u015bci o wydaniach tego projektu umieszczono w pliku NEWS, znajduj\u0105cym si\u0119 w katalogu g\u0142\u00f3wnym IcedTea-Web.
--- a/netx/net/sourceforge/jnlp/runtime/AppletEnvironment.java	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/AppletEnvironment.java	Fri Oct 12 13:30:42 2018 +0200
@@ -25,9 +25,11 @@
 import java.lang.reflect.InvocationTargetException;
 import java.net.*;
 import java.io.*;
+import javax.jnlp.ServiceManager;
 import javax.swing.*;
 
 import net.sourceforge.jnlp.*;
+import net.sourceforge.jnlp.services.ServiceUtil;
 import net.sourceforge.jnlp.splashscreen.SplashController;
 import net.sourceforge.jnlp.util.*;
 import net.sourceforge.swing.SwingUtils;
@@ -285,23 +287,23 @@
     }
 
     /**
-     * Not implemented yet.
      * @param uRL url of document
      */
     @Override
     public void showDocument(java.net.URL uRL) {
         checkDestroyed();
-
+        ServiceUtil.getBasicService().showDocument(uRL);
     }
 
     /**
      * Not implemented yet.
      * @param uRL source of document
-     * @param str who know what
+     * @param str _self, _parent, _top, _blank or "name". Have sense only for applets. Not implemented for our javaws world
      */
     @Override
     public void showDocument(java.net.URL uRL, java.lang.String str) {
         checkDestroyed();
+        ServiceUtil.getBasicService().showDocument(uRL);
 
     }
 
--- a/netx/net/sourceforge/jnlp/runtime/Translator.java	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/Translator.java	Fri Oct 12 13:30:42 2018 +0200
@@ -20,6 +20,7 @@
 import java.util.Locale;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
+import net.sourceforge.jnlp.config.DeploymentConfiguration;
 
 /**
  * Utility class to provide simple methods to help localize messages
@@ -80,6 +81,20 @@
     public static String R(String message, Object... params) {
         return getInstance().getMessage(message, params);
     }
+     
+    /**
+     * convenient method to show VVPossibleBrowserValues with all four params
+     *
+     * @return translation of VVPossibleBrowserValues with all params in
+     */
+    public static String VVPossibleBrowserValues() {
+        return R("VVPossibleBrowserValues", DeploymentConfiguration.LEGACY_WIN32_URL__HANDLER,
+                DeploymentConfiguration.BROWSER_ENV_VAR,
+                DeploymentConfiguration.INTERNAL_HTML,
+                DeploymentConfiguration.ALWAYS_ASK,
+                DeploymentConfiguration.KEY_BROWSER_PATH
+        );
+    }
 
    
     /**
--- a/netx/net/sourceforge/jnlp/runtime/html/browser/LinkingBrowser.java	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/html/browser/LinkingBrowser.java	Fri Oct 12 13:30:42 2018 +0200
@@ -46,7 +46,6 @@
 import static net.sourceforge.jnlp.runtime.JNLPRuntime.getConfiguration;
 import net.sourceforge.jnlp.security.JNLPAuthenticator;
 import net.sourceforge.jnlp.util.logging.JavaConsole;
-import net.sourceforge.jnlp.util.logging.OutputController;
 
 public class LinkingBrowser extends JTabbedPane {
 
@@ -92,11 +91,15 @@
         BrowserAwareProxySelector proxySelector = new BrowserAwareProxySelector(getConfiguration());
         proxySelector.initialize();
         ProxySelector.setDefault(proxySelector);
+        createFrame(url, socket, JFrame.EXIT_ON_CLOSE);
+    }
+
+    public static void createFrame(String url, boolean socket, int action) {
         HtmlBrowserPanel.warn();
         JFrame f = new JFrame();
         f.add(new LinkingBrowser(url, socket));
         f.pack();
-        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        f.setDefaultCloseOperation(action);
         f.setVisible(true);
     }
 
--- a/netx/net/sourceforge/jnlp/services/XBasicService.java	Tue Oct 02 10:36:29 2018 +0200
+++ b/netx/net/sourceforge/jnlp/services/XBasicService.java	Fri Oct 12 13:30:42 2018 +0200
@@ -13,54 +13,68 @@
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
 package net.sourceforge.jnlp.services;
 
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Desktop;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
 import static net.sourceforge.jnlp.runtime.Translator.R;
 
 import java.io.IOException;
-import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.net.URLConnection;
+import java.util.StringTokenizer;
 
 import javax.jnlp.BasicService;
-import javax.swing.JOptionPane;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
 import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
 
 import net.sourceforge.jnlp.InformationDesc;
 import net.sourceforge.jnlp.JARDesc;
 import net.sourceforge.jnlp.JNLPFile;
-import net.sourceforge.jnlp.Launcher;
+import net.sourceforge.jnlp.config.BasicValueValidators;
+import static net.sourceforge.jnlp.config.BasicValueValidators.verifyFileOrCommand;
 import net.sourceforge.jnlp.config.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.ApplicationInstance;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.runtime.Translator;
+import net.sourceforge.jnlp.runtime.html.browser.LinkingBrowser;
 import net.sourceforge.jnlp.util.StreamUtils;
 import net.sourceforge.jnlp.util.logging.OutputController;
+import net.sourceforge.swing.SwingUtils;
 
 /**
  * The BasicService JNLP service.
  *
- * @author <a href="mailto:jmaxwell@users.sourceforge.net">Jon A. Maxwell (JAM)</a> - initial author
+ * @author <a href="mailto:jmaxwell@users.sourceforge.net">Jon A. Maxwell
+ * (JAM)</a> - initial author
  * @version $Revision: 1.10 $
  */
 class XBasicService implements BasicService {
 
-    /** command used to exec the native browser */
-    private String command = null;
-
-    /** whether the command was loaded / prompted for */
-    private boolean initialized = false;
-
     protected XBasicService() {
     }
 
     /**
-     * Returns the codebase of the application, applet, or
-     * installer.  If the codebase was not specified in the JNLP
-     * element then the main JAR's location is returned.  If no main
-     * JAR was specified then the location of the JAR containing the
-     * main class is returned.
+     * Returns the codebase of the application, applet, or installer. If the
+     * codebase was not specified in the JNLP element then the main JAR's
+     * location is returned. If no main JAR was specified then the location of
+     * the JAR containing the main class is returned.
      */
     @Override
     public URL getCodeBase() {
@@ -70,13 +84,15 @@
             JNLPFile file = app.getJNLPFile();
 
             // return the codebase.
-            if (file.getCodeBase() != null)
+            if (file.getCodeBase() != null) {
                 return file.getCodeBase();
+            }
 
             // else return the main JAR's URL.
             JARDesc mainJar = file.getResources().getMainJAR();
-            if (mainJar != null)
+            if (mainJar != null) {
                 return mainJar.getLocation();
+            }
 
             // else find JAR where main class was defined.
             //
@@ -101,8 +117,8 @@
     }
 
     /**
-     * Return the first URL from the jnlp file
-     * Or a default URL if no url found in JNLP file
+     * Return the first URL from the jnlp file Or a default URL if no url found
+     * in JNLP file
      */
     private URL findFirstURLFromJNLPFile() {
 
@@ -150,9 +166,8 @@
      */
     @Override
     public boolean isWebBrowserSupported() {
-        initialize();
-
-        return command != null;
+        //there is hardly anything our impl can not handle
+        return true;
     }
 
     /**
@@ -162,133 +177,238 @@
      */
     @Override
     public boolean showDocument(URL url) {
-        initialize();
-
-        if (url.toString().endsWith(".jnlp")) {
-            try {
-                new Launcher(false).launchExternal(url);
-                return true;
-            } catch (Exception ex) {
-                return false;
-            }
-        }
+        try {
+//        if (url.toString().endsWith(".jnlp")) {
+//            try {
+//                new Launcher(false).launchExternal(url);
+//                return true;
+//            } catch (Exception ex) {
+//                return false;
+//            }
+//        }
+// Ignorance of this code is the only regression against original code (if you asume msot of the jnlps havejnlp suffix...) we had
+// anyway, also jnlp protocol should be handled via this, so while this can be set via 
+// ALWAYS-ASK, or directly via BROWSER of deployment.browser.path , it still should be better then it was
+// in all cases, the mime recognition is much harder then .jnlp suffix
 
-        if (command != null) {
-            try {
-                // this is bogus because the command may require options;
-                // should use a StreamTokenizer or similar to get tokens
-                // outside of quotes.
-                Runtime.getRuntime().exec(command + " " + url.toString());
-                //Runtime.getRuntime().exec(new String[]{command,url.toString()});
-
-                return true;
-            } catch (IOException ex) {
-                OutputController.getLogger().log(ex);
-            }
-        }
-
-        return false;
-    }
+            String urls = url.toExternalForm();
+            OutputController.getLogger().log("showDocument for: " + urls);
 
-    private void initialize() {
-        if (initialized)
-            return;
-        initialized = true;
-        initializeBrowserCommand();
-        OutputController.getLogger().log("browser is " + command);
-    }
-
-    /**
-     * Initializes {@link #command} to launch a browser
-     */
-    private void initializeBrowserCommand() {
-        if (JNLPRuntime.isWindows()) {
-            command = "rundll32 url.dll,FileProtocolHandler ";
-        } else if (JNLPRuntime.isUnix()) {
             DeploymentConfiguration config = JNLPRuntime.getConfiguration();
-            command = config.getProperty(DeploymentConfiguration.KEY_BROWSER_PATH);
+            String command = config.getProperty(DeploymentConfiguration.KEY_BROWSER_PATH);
+            //for various debugging
+            //command=DeploymentConfiguration.ALWAYS_ASK;
             if (command != null) {
-                return;
+                OutputController.getLogger().log(DeploymentConfiguration.KEY_BROWSER_PATH + " located. Using: " + command);
+                return exec(command, urls);
             }
-
-            if (posixCommandExists("xdg-open")) {
-                command = "xdg-open";
-                return;
-            }
-
-            if (posixCommandExists(System.getenv("BROWSER"))) {
-                command = System.getenv("BROWSER");
-                return;
+            if (System.getenv(DeploymentConfiguration.BROWSER_ENV_VAR) != null) {
+                command = System.getenv(DeploymentConfiguration.BROWSER_ENV_VAR);
+                OutputController.getLogger().log("variable " + DeploymentConfiguration.BROWSER_ENV_VAR + " located. Using: " + command);
+                return exec(command, urls);
             }
-
-            while (true) {
-                command = promptForCommand(command);
-                if (command != null && posixCommandExists(command)) {
-                    config.setProperty(DeploymentConfiguration.KEY_BROWSER_PATH, command);
-                    try {
-                        config.save();
-                    } catch (IOException e) {
-                        OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e);
-                    }
-                    break;
+            if (JNLPRuntime.isHeadless() || !Desktop.isDesktopSupported()) {
+                command = promptForCommand(urls, false);
+                return exec(command, urls);
+            } else {
+                if (Desktop.isDesktopSupported()) {
+                    OutputController.getLogger().log("using default browser");
+                    Desktop.getDesktop().browse(url.toURI());
+                    return true;
+                } else {
+                    OutputController.getLogger().log("dont know what to do");
+                    return false;
                 }
             }
-        } else {
-            DeploymentConfiguration config = JNLPRuntime.getConfiguration();
-            command = config.getProperty(DeploymentConfiguration.KEY_BROWSER_PATH);
-
-            if (command == null) { // prompt & store
-                command = promptForCommand(null);
-
-                if (command != null) {
-                    config.setProperty(DeploymentConfiguration.KEY_BROWSER_PATH, command);
-                    try {
-                        config.save();
-                    } catch (IOException e) {
-                        OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e);
-                    }
-                }
-            }
+        } catch (Exception e) {
+            OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, e.toString());
+            OutputController.getLogger().log(e);
+            return false;
         }
     }
 
-    /**
-     * Check that a command exists on a posix-like system
-     * @param command the command to check
-     * @return true if the command exists
-     */
-    private boolean posixCommandExists(String command) {
-        if (command == null || command.trim().length() == 0) {
-            return false;
-        }
-
-        command = command.trim();
-        if (command.contains("\n") || command.contains("\r")) {
-            return false;
-        }
-
+    //cmd form user can contains spaces, wuotes and so... now we are relying on default dummy impl
+    private boolean exec(String cmd, String url) {
         try {
-            Process p = Runtime.getRuntime().exec(new String[] { "bash", "-c", "type " + command });
+            if (cmd == null || cmd.length() == 0) {
+                return false;
+            }
+            if (url == null || url.length() == 0) {
+                return false;
+            }
+            if (cmd.equals(DeploymentConfiguration.ALWAYS_ASK)) {
+                cmd = promptForCommand(url, true);
+            }
+            if (cmd.equals(DeploymentConfiguration.INTERNAL_HTML)) {
+                LinkingBrowser.createFrame(url, false, JFrame.DISPOSE_ON_CLOSE);
+                return true;
+            }
+            //copypasted from exec
+            StringTokenizer st = new StringTokenizer(cmd + " " + url);
+            String[] cmdarray = new String[st.countTokens()];
+            for (int i = 0; st.hasMoreTokens(); i++) {
+                cmdarray[i] = st.nextToken();
+            }
+            final ProcessBuilder pb = new ProcessBuilder(cmdarray);
+            pb.inheritIO();
+            final Process p = pb.start();
             StreamUtils.waitForSafely(p);
             return (p.exitValue() == 0);
-        } catch (IOException e) {
-            OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e);
+        } catch (Exception e) {
+            OutputController.getLogger().log(e);
+            try {
+                //time for stderr to deal with it in verbose mode
+                Thread.sleep(50);
+            } catch (Exception ex) {
+                //ss
+            }
+            OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, e.toString());
+            OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, Translator.VVPossibleBrowserValues());
             return false;
         }
     }
 
-    private String promptForCommand(String previousCommand) {
-        String message = null;
-        if (previousCommand == null) {
-            message = R("RBrowserLocationPromptMessage");
+    private String promptForCommand(final String targetUrl, boolean aa) throws IOException {
+        String message = Translator.VVPossibleBrowserValues();
+        String title = R("RBrowserLocationPromptTitle");
+        if (JNLPRuntime.isHeadless()) {
+            OutputController.getLogger().printOutLn(message);
+            OutputController.getLogger().printOutLn("*** " + targetUrl + " ***");
+            OutputController.getLogger().printOutLn(title);
+            String entered = OutputController.getLogger().readLine();
+            String verification = verifyFileOrCommand(entered);
+            if (verification == null) {
+                OutputController.getLogger().printOutLn(R("VVBrowserVerificationFail"));
+            } else {
+                OutputController.getLogger().printOutLn(R("VVBrowserVerificationPass", verification));
+            }
+            return entered;
         } else {
-            message = R("RBrowserLocationPromptMessageWithReason", previousCommand);
+            final PromptUrl pu = new PromptUrl();
+            pu.arrange(targetUrl, aa);
+            pu.setVisible(true);
+            return pu.getValue();
+        }
+    }
+
+    private static class PromptUrl extends JDialog {
+
+        JTextField value = new JTextField("firefox");
+        JLabel verification = new JLabel("?");
+        private WindowListener cl = new WindowAdapter() {
+            @Override
+            public void windowClosing(WindowEvent e) {
+                value.setText("");
+            }
+        };
+        JCheckBox save = new JCheckBox(R("PESaveChanges"));
+        private boolean ask;
+
+        public PromptUrl() {
+            super((JDialog) null, R("RBrowserLocationPromptTitle"), true);
         }
-        return JOptionPane.showInputDialog(new JPanel(),
-                                           R("RBrowserLocationPromptTitle"),
-                                           message,
-                                           JOptionPane.PLAIN_MESSAGE
-                                          );
+
+        public void arrange(String url, boolean ask) {
+            this.ask = ask;
+            JPanel top = new JPanel(new GridLayout(2, 1));
+            JPanel bottom = new JPanel(new GridLayout(5, 1));
+            this.setLayout(new BorderLayout());
+            this.add(top, BorderLayout.NORTH);
+            this.add(bottom, BorderLayout.SOUTH);
+            top.add(new JLabel("<html><b>" + R("RBrowserLocationPromptTitle")));
+            JTextField urlField = new JTextField(url);
+            urlField.setEditable(false);
+            top.add(urlField);
+            JTextArea ta = new JTextArea(Translator.VVPossibleBrowserValues());
+            ta.setEditable(false);
+            ta.setLineWrap(true);
+            ta.setWrapStyleWord(false);
+            JScrollPane scrollableTa=new JScrollPane(ta);
+            scrollableTa.setHorizontalScrollBar(null);
+            this.add(scrollableTa);
+            bottom.add(value);
+            bottom.add(verification);
+            JButton ok = new JButton(R("ButOk"));
+            ok.addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    if (save.isSelected()) {
+                        JNLPRuntime.getConfiguration().setProperty(DeploymentConfiguration.KEY_BROWSER_PATH, value.getText());
+                        try {
+                            JNLPRuntime.getConfiguration().save();
+                        } catch (IOException ex) {
+                            OutputController.getLogger().log(ex);
+                        }
+                    }
+                    PromptUrl.this.dispose();
+                }
+            });
+            JButton cancel = new JButton(R("ButCancel"));
+            cancel.addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    cl.windowClosing(null);
+                    PromptUrl.this.dispose();
+                }
+            });
+            bottom.add(save);
+            bottom.add(ok);
+            bottom.add(cancel);
+            if (this.ask) {
+                save.setSelected(false);
+                save.setEnabled(false);
+                save.setToolTipText(R("VVBrowserSaveNotAllowed", DeploymentConfiguration.ALWAYS_ASK, DeploymentConfiguration.KEY_BROWSER_PATH));
+            } else {
+                save.setEnabled(true);
+                save.setToolTipText(R("VVBrowserSaveAllowed", DeploymentConfiguration.KEY_BROWSER_PATH));
+            }
+            this.addWindowListener(cl);
+
+            value.getDocument().addDocumentListener(new DocumentListener() {
+
+                @Override
+                public void insertUpdate(DocumentEvent e) {
+                    check();
+                }
+
+                @Override
+                public void removeUpdate(DocumentEvent e) {
+                    check();
+                }
+
+                @Override
+                public void changedUpdate(DocumentEvent e) {
+                    check();
+                }
+
+                private void check() {
+                    String result = BasicValueValidators.verifyFileOrCommand(value.getText());
+                    if (result == null) {
+                        verification.setForeground(Color.red);
+                        verification.setText(R("VVBrowserVerificationFail"));
+                        if (!PromptUrl.this.ask) {
+                            save.setSelected(false);
+                        }
+                    } else {
+                        verification.setForeground(Color.green);
+                        verification.setText(R("VVBrowserVerificationPass", result));
+                        if (!PromptUrl.this.ask) {
+                            save.setSelected(true);
+                        }
+                    }
+                }
+            });
+            this.pack();
+            this.setSize(500, 400);
+        }
+
+        private String getValue() {
+            if (value.getText().trim().isEmpty()) {
+                return null;
+            }
+            return value.getText();
+        }
+
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/signed/ShowDocument/resources/ShowDocumentApplet.jnlp	Fri Oct 12 13:30:42 2018 +0200
@@ -0,0 +1,60 @@
+<!--
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+IcedTea is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+
+-->
+<?xml version="1.0" encoding="utf-8"?>
+<jnlp spec="1.0" href="ShowDocumentApplet.jnlp">
+    <information>
+        <title>ShowDocumentApplet</title>
+        <vendor>IcedTea</vendor>
+        <homepage href="http://icedtea.classpath.org/wiki/IcedTea-Web#Testing_IcedTea-Web "/>
+        <description>ShowDocumentApplet</description>
+        <offline/>
+    </information>
+    <resources>
+        <j2se version="1.4+"/>
+        <jar href="ShowDocument.jar"/>
+    </resources>
+    <security>
+      <all-permissions/>
+    </security>
+    <applet-desc
+      documentBase="."
+      name="ShowDocument"
+      main-class="ShowDocument"
+      width="100"
+      height="100">
+    </applet-desc>
+</jnlp>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/signed/ShowDocument/resources/ShowDocumentMain.jnlp	Fri Oct 12 13:30:42 2018 +0200
@@ -0,0 +1,56 @@
+<!--
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+IcedTea is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+
+ -->
+<?xml version="1.0" encoding="utf-8"?>
+<jnlp spec="1.0" href="ShowDocumentMain.jnlp" codebase=".">
+  <information>
+    <title>ShowDocumentMain</title>
+    <vendor>IcedTea</vendor>
+    <homepage href="http://icedtea.classpath.org/wiki/IcedTea-Web#Testing_IcedTea-Web"/>
+    <description>ShowDocumentMain</description>
+    <offline/>
+  </information>
+  <resources>
+    <j2se version="1.4+"/>
+    <jar href="ShowDocument.jar"/>
+  </resources>
+  <security>
+    <all-permissions/>
+  </security>
+  <application-desc main-class="ShowDocument">
+  </application-desc>
+</jnlp>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/signed/ShowDocument/resources/document.txt	Fri Oct 12 13:30:42 2018 +0200
@@ -0,0 +1,2 @@
+document appears!
+Good.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/signed/ShowDocument/srcs/ShowDocument.java	Fri Oct 12 13:30:42 2018 +0200
@@ -0,0 +1,122 @@
+
+import java.applet.Applet;
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.jnlp.BasicService;
+import javax.jnlp.ServiceManager;
+import javax.jnlp.UnavailableServiceException;
+
+
+/* SimpleTest2.java
+Copyright (C) 2011 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+ */
+public class ShowDocument extends Applet {
+
+    //this is the only reason why it is isgned
+    private static String url = System.getProperty("durl", "http://www-eng-x.llnl.gov/documents/a_document.txt");
+
+    private static class Killer extends Thread {
+
+        public static final int n = 2000;
+
+        @Override
+        public void run() {
+            try {
+                Thread.sleep(n);
+                System.out.println("Applet killing himself after " + n + " ms of life");
+                System.exit(0);
+            } catch (Exception ex) {
+            }
+        }
+    }
+    private Killer killer;
+
+    public static void main(String[] args) throws MalformedURLException, UnavailableServiceException {
+        // Lookup the javax.jnlp.BasicService object
+        BasicService bs = (BasicService) ServiceManager.lookup("javax.jnlp.BasicService");
+        // Invoke the showDocument method
+        bs.showDocument(new URL(url));
+    }
+
+    public void work1() {
+        try {
+            boolean ok = true;
+            this.getAppletContext().showDocument(new URL(url));
+            if (!ok) {
+                throw new RuntimeException("document should show");
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void work2() {
+        try {
+            boolean ok = true;
+            this.getAppletContext().showDocument(new URL(url), "");
+            if (!ok) {
+                throw new RuntimeException("document should show");
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void init() {
+        System.out.println("applet was initialised");
+        killer = new Killer();
+    }
+
+    @Override
+    public void start() {
+        System.out.println("applet was started");
+        work1();
+        work2();
+        killer.start();
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("applet was stopped");
+    }
+
+    @Override
+    public void destroy() {
+        System.out.println("applet will be destroyed");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/signed/ShowDocument/testcases/ShowDocumentTest.java	Fri Oct 12 13:30:42 2018 +0200
@@ -0,0 +1,76 @@
+/* ShowDocumentTest.java
+Copyright (C) 2011 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+ */
+
+import java.util.Arrays;
+import net.sourceforge.jnlp.OptionsDefinitions;
+import net.sourceforge.jnlp.ProcessResult;
+import net.sourceforge.jnlp.ProcessWrapper;
+import net.sourceforge.jnlp.ServerAccess;
+import net.sourceforge.jnlp.closinglisteners.StringBasedClosingListener;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ShowDocumentTest {
+
+    private static ServerAccess server = new ServerAccess();
+
+    @Test
+    public void testShowDocumentMain() throws Exception {
+        ProcessWrapper pw = new ProcessWrapper(server.getJavawsLocation(), Arrays.asList(
+                new String[]{OptionsDefinitions.OPTIONS.HEADLESS.option,
+                    "-J-Ddurl=http://localhost:" + server.getPort() + "/document.txt"}), server.getUrl("ShowDocumentMain.jnlp"));
+        pw.setWriter("curl\n");
+        pw.addStdOutListener(new StringBasedClosingListener("killer was started"));
+        ProcessResult pr = pw.execute();
+        Assert.assertFalse("stderr should NOT contains Exception but didn", pr.stderr.contains("Exception"));
+        Assert.assertTrue("stdout hsould read document but didn't", pr.stdout.contains("document appears!"));
+    }
+
+    @Test
+    public void testShowDocumentApplet() throws Exception {
+        ProcessWrapper pw = new ProcessWrapper(server.getJavawsLocation(), Arrays.asList(
+                new String[]{OptionsDefinitions.OPTIONS.HEADLESS.option,
+                    "-J-Ddurl=http://localhost:" + server.getPort() + "/document.txt"}), server.getUrl("ShowDocumentApplet.jnlp"));
+        pw.setWriter("curl\n");
+        pw.addStdOutListener(new StringBasedClosingListener("killer was started"));
+        ProcessResult pr = pw.execute();
+        Assert.assertFalse("stderr should NOT contains Exception but didn", pr.stderr.contains("Exception"));
+        Assert.assertTrue("stdout hsould read document but didn't", pr.stdout.contains("document appears!"));
+    }
+
+}