changeset 1248:7e1e9ab4824d

All dialogs are able to accept answer from standard input and thus works in headless mode * netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java: turned headless/logic order. Headless is now only hanging output, not behavior. * netx/net/sourceforge/jnlp/resources/Messages.properties: Changed KSheadlesWarning added HeadlessDialogues AWPstdoutHint1-3 PAPstdinInfo and HDwrongValue keys for headless dialogues. * netx/net/sourceforge/jnlp/security/KeystorePasswordAttempter.java: headelss error changed to stdin reading. Shared code extracted to addPnewPassword * netx/net/sourceforge/jnlp/security/SecurityDialog.java: small refactroings createTitle, new methods, and one more abstraction upon getPanel * netx/net/sourceforge/jnlp/security/SecurityDialogMessageHandler.java: added and called processMessageInHeadless * netx/net/sourceforge/jnlp/security/dialogresults/AccessWarningPaneComplexReturn.java: added method returning string with all possible values * netx/net/sourceforge/jnlp/security/dialogresults/NamePassword.java: (readValue) got logic * netx/net/sourceforge/jnlp/security/dialogs/AccessWarningPane.java: implemented readFromStdIn and helpToStdIn * netx/net/sourceforge/jnlp/security/dialogs/AppletWarningPane.java: same * netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java: same * netx/net/sourceforge/jnlp/security/dialogs/CertsInfoPane.java: same * netx/net/sourceforge/jnlp/security/dialogs/MissingALACAttributePanel.java: same * netx/net/sourceforge/jnlp/security/dialogs/MissingPermissionsAttributePanel.java: same * netx/net/sourceforge/jnlp/security/dialogs/MoreInfoPane.java: same * netx/net/sourceforge/jnlp/security/dialogs/PasswordAuthenticationPane.java: same * netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningPanel.java: same * netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java: same * netx/net/sourceforge/jnlp/security/dialogs/remember/RememberDialog.java: logic of setOrUpdateRememberedState splited to two methods to allow headless to save added * netx/net/sourceforge/jnlp/security/dialogs/SecurityDialogPanel.java: written default getText method, which creates stdout message from already done gui implementations * netx/net/sourceforge/jnlp/util/logging/OutputController.java: added readLine method to allow simple reading of standard in * tests/netx/unit/net/sourceforge/jnlp/security/SecurityDialogsTest.java: become NoStdOutErrTest. Disabled most partiallYsignedTests. Hard to mock certVerifier and securityDelegate * tests/test-extensions/net/sourceforge/jnlp/util/logging/NoStdOutErrTest.java: enhanced to handle also stdout/err not jsut logger
author Jiri Vanek <jvanek@redhat.com>
date Thu, 18 Jun 2015 12:29:34 +0200
parents 50571bdee6ed
children c09f70284a5f
files ChangeLog netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java netx/net/sourceforge/jnlp/resources/Messages.properties netx/net/sourceforge/jnlp/security/KeystorePasswordAttempter.java netx/net/sourceforge/jnlp/security/SecurityDialog.java netx/net/sourceforge/jnlp/security/SecurityDialogMessageHandler.java netx/net/sourceforge/jnlp/security/dialogresults/AccessWarningPaneComplexReturn.java netx/net/sourceforge/jnlp/security/dialogresults/NamePassword.java netx/net/sourceforge/jnlp/security/dialogs/AccessWarningPane.java netx/net/sourceforge/jnlp/security/dialogs/AppletWarningPane.java netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java netx/net/sourceforge/jnlp/security/dialogs/CertsInfoPane.java netx/net/sourceforge/jnlp/security/dialogs/MissingALACAttributePanel.java netx/net/sourceforge/jnlp/security/dialogs/MissingPermissionsAttributePanel.java netx/net/sourceforge/jnlp/security/dialogs/MoreInfoPane.java netx/net/sourceforge/jnlp/security/dialogs/PasswordAuthenticationPane.java netx/net/sourceforge/jnlp/security/dialogs/SecurityDialogPanel.java netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningPanel.java netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java netx/net/sourceforge/jnlp/security/dialogs/remember/RememberDialog.java netx/net/sourceforge/jnlp/util/logging/OutputController.java tests/netx/unit/net/sourceforge/jnlp/security/SecurityDialogsTest.java tests/test-extensions/net/sourceforge/jnlp/util/logging/NoStdOutErrTest.java
diffstat 23 files changed, 561 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Jun 17 17:15:52 2015 +0200
+++ b/ChangeLog	Thu Jun 18 12:29:34 2015 +0200
@@ -1,3 +1,50 @@
+2015-06-18  Jiri Vanek  <jvanek@redhat.com>
+
+	All dialogs are able to accept answer from standard input and thus works in headless mode
+	* netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java: turned headless/logic
+	order. Headless is now only hanging output, not behavior.
+	* netx/net/sourceforge/jnlp/resources/Messages.properties: Changed KSheadlesWarning
+	added HeadlessDialogues AWPstdoutHint1-3 PAPstdinInfo and HDwrongValue keys
+	for headless dialogues.
+	* netx/net/sourceforge/jnlp/security/KeystorePasswordAttempter.java: headelss
+	error changed to stdin reading. Shared code extracted to addPnewPassword
+	* netx/net/sourceforge/jnlp/security/SecurityDialog.java: small refactroings
+	createTitle, new methods, and one more abstraction upon getPanel
+	* netx/net/sourceforge/jnlp/security/SecurityDialogMessageHandler.java: added
+	and called processMessageInHeadless
+	* netx/net/sourceforge/jnlp/security/dialogresults/AccessWarningPaneComplexReturn.java:
+	added method returning string with all possible values
+	* netx/net/sourceforge/jnlp/security/dialogresults/NamePassword.java: (readValue)
+	got logic
+	* netx/net/sourceforge/jnlp/security/dialogs/AccessWarningPane.java: implemented
+	readFromStdIn and helpToStdIn
+	* netx/net/sourceforge/jnlp/security/dialogs/AppletWarningPane.java: same
+	* netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java: same
+	* netx/net/sourceforge/jnlp/security/dialogs/CertsInfoPane.java: same
+	* netx/net/sourceforge/jnlp/security/dialogs/MissingALACAttributePanel.java: same
+	* netx/net/sourceforge/jnlp/security/dialogs/MissingPermissionsAttributePanel.java:
+	same
+	* netx/net/sourceforge/jnlp/security/dialogs/MoreInfoPane.java:	same
+	* netx/net/sourceforge/jnlp/security/dialogs/PasswordAuthenticationPane.java:
+	same
+	* netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningPanel.java:
+	same
+	* netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java:
+	same
+	* netx/net/sourceforge/jnlp/security/dialogs/remember/RememberDialog.java: logic
+	of setOrUpdateRememberedState splited to two methods to allow headless to save
+	added 
+	* netx/net/sourceforge/jnlp/security/dialogs/SecurityDialogPanel.java: written
+	default getText method, which creates stdout message from already done gui implementations
+	* netx/net/sourceforge/jnlp/util/logging/OutputController.java: added readLine
+	method to allow simple reading of standard in
+	* tests/netx/unit/net/sourceforge/jnlp/security/SecurityDialogsTest.java:
+	become NoStdOutErrTest.	Disabled most partiallYsignedTests. Hard to mock
+	certVerifier and securityDelegate
+	* tests/test-extensions/net/sourceforge/jnlp/util/logging/NoStdOutErrTest.java:
+	enhanced to handle also stdout/err not jsut logger
+
+
 2015-06-16  Jiri Vanek  <jvanek@redhat.com>
 
 	All headless, xtrustatAll/None, shouldPrompt dialogue decisions moved into shared place
--- a/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java	Thu Jun 18 12:29:34 2015 +0200
@@ -832,8 +832,9 @@
         }
         //this call should endure even if (ever) will migration code be removed
         DirectoryValidator.DirectoryCheckResults r = new DirectoryValidator().ensureDirs();
-        if (!JNLPRuntime.isHeadless()) {
-            if (r.getFailures() > 0) {
+        if (r.getFailures() > 0) {
+            OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, r.getMessage());
+            if (!JNLPRuntime.isHeadless()) {
                 JOptionPane.showMessageDialog(null, r.getMessage());
             }
         }
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/resources/Messages.properties	Thu Jun 18 12:29:34 2015 +0200
@@ -525,8 +525,14 @@
 # KeyStores: set password
 KSresultUntilNow=Got {0} during keystore operation {1}. Attempts to unlock: {2}
 KSinvalidPassword=Invalid password?
-KSheadlesWarning=Headless mode currently does not support runtime-passwords
+KSheadlesWarning=Type new password and press ok. Give up by pressing return on empty line.
 KSnwPassHelp=Type new password and press ok. Give up by pressing anything else.
+HeadlessDialogues=Type `exit` to terminate ITW, or type one of the below values. Prefix answer by "R " to remember decision and by "RC " to do so for whole codebase.
+AWPstdoutHint1=You can type YES/NO or complex answer parseable by AccessWarningPaneComplexReturn.readValue.
+AWPstdoutHint2=eg: YES,D(not_found_browser,false,null,true,)M(firefox,false,null,false,)
+AWPstdoutHint3=where: global_answer,desktop_shortcut(browser_bin,fixJnlpHref,type:null_or_one_of{0},really_create)same_for_menu...
+PAPstdinInfo=Type NAME space PASSWORD. Sorry, no spaces in name, no security, keep your screen safe:
+HDwrongValue=Probably wrong value?
 
 # Deployment Configuration messages
 DCIncorrectValue=Property "{0}" has incorrect value "{1}". Possible values {2}.
--- a/netx/net/sourceforge/jnlp/security/KeystorePasswordAttempter.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/KeystorePasswordAttempter.java	Thu Jun 18 12:29:34 2015 +0200
@@ -167,17 +167,20 @@
                     OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, s1);
                     OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, Translator.R("KSinvalidPassword"));
                     if (JNLPRuntime.isHeadless()) {
-                        OutputController.getLogger().log(Translator.R("KSheadlesWarning"));
-                        finish(firstEx);
+                        OutputController.getLogger().printOutLn(s1 + "\n" + Translator.R("KSheadlesWarning"));
+                        String s = OutputController.getLogger().readLine();
+                        if (s == null || s.trim().isEmpty()) {
+                            finish(firstEx);
+                        }
+                        //if input is null or empty , exception is thrown from finish method
+                        addPnewPassword(s, localPases);
                     } else {
                         String s = JOptionPane.showInputDialog(s1 + "\n" + Translator.R("KSnwPassHelp"));
                         if (s == null) {
                             finish(firstEx);
                         }
                         //if input is null, exception is thrown from finish method
-                        SavedPassword users = new SavedPassword(s.toCharArray());
-                        passes.add(users);
-                        localPases.add(users);
+                        addPnewPassword(s, localPases);
                     }
                     //user already read all messages, now show only last one
                     messages = "";
@@ -187,6 +190,12 @@
         return null;
     }
 
+    private void addPnewPassword(String s, List<SavedPassword> localPases) {
+        SavedPassword users = new SavedPassword(s.toCharArray());
+        passes.add(users);
+        localPases.add(users);
+    }
+
     private void finish(Exception ex) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, IOException, CertificateException {
         if (ex instanceof KeyStoreException) {
             throw (KeyStoreException) ex;
--- a/netx/net/sourceforge/jnlp/security/SecurityDialog.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/SecurityDialog.java	Thu Jun 18 12:29:34 2015 +0200
@@ -223,24 +223,7 @@
     }
 
     private void initDialog() {
-        String dialogTitle = "";
-        if (dialogType == DialogType.CERT_WARNING) {
-            if (accessType == AccessType.VERIFIED)
-                dialogTitle = "Security Approval Required";
-            else
-                dialogTitle = "Security Warning";
-        } else if (dialogType == DialogType.MORE_INFO)
-            dialogTitle = "More Information";
-        else if (dialogType == DialogType.CERT_INFO)
-            dialogTitle = "Details - Certificate";
-        else if (dialogType == DialogType.ACCESS_WARNING)
-            dialogTitle = "Security Warning";
-        else if (dialogType == DialogType.APPLET_WARNING)
-            dialogTitle = "Applet Warning";
-        else if (dialogType == DialogType.PARTIALLYSIGNED_WARNING)
-            dialogTitle = "Security Warning";
-        else if (dialogType == DialogType.AUTHENTICATION)
-            dialogTitle = "Authentication Required";
+        String dialogTitle = createTitle();
 
         setTitle(dialogTitle);
         setModalityType(ModalityType.MODELESS);
@@ -277,6 +260,31 @@
         addWindowFocusListener(adapter);
     }
 
+    private String createTitle() {
+        return createTitle(dialogType, accessType);
+    }
+    private static String createTitle(DialogType dtype, AccessType atype) {
+        String dialogTitle = "";
+        if (dtype == DialogType.CERT_WARNING) {
+            if (atype == AccessType.VERIFIED)
+                dialogTitle = "Security Approval Required";
+            else
+                dialogTitle = "Security Warning";
+        } else if (dtype == DialogType.MORE_INFO)
+            dialogTitle = "More Information";
+        else if (dtype == DialogType.CERT_INFO)
+            dialogTitle = "Details - Certificate";
+        else if (dtype == DialogType.ACCESS_WARNING)
+            dialogTitle = "Security Warning";
+        else if (dtype == DialogType.APPLET_WARNING)
+            dialogTitle = "Applet Warning";
+        else if (dtype == DialogType.PARTIALLYSIGNED_WARNING)
+            dialogTitle = "Security Warning";
+        else if (dtype == DialogType.AUTHENTICATION)
+            dialogTitle = "Authentication Required";
+        return dialogTitle;
+    }
+
     public AccessType getAccessType() {
         return accessType;
     }
@@ -303,31 +311,35 @@
     /*
      * find appropriate JPanel to given Dialog, based on {@link DialogType}.
      */
-    private static SecurityDialogPanel getPanel(SecurityDialog sd) {
+    static SecurityDialogPanel getPanel(SecurityDialog sd) {
+        return getPanel(sd.dialogType, sd);
+    }
+    
+    static SecurityDialogPanel getPanel(DialogType type, SecurityDialog sd) {
         SecurityDialogPanel lpanel = null;
-        if (sd.dialogType == DialogType.CERT_WARNING) {
+        if (type == DialogType.CERT_WARNING) {
             lpanel = new CertWarningPane(sd, sd.certVerifier, (SecurityDelegate) sd.extras[0]);
-        } else if (sd.dialogType == DialogType.MORE_INFO) {
+        } else if (type == DialogType.MORE_INFO) {
             lpanel = new MoreInfoPane(sd, sd.certVerifier);
-        } else if (sd.dialogType == DialogType.CERT_INFO) {
+        } else if (type == DialogType.CERT_INFO) {
             lpanel = new CertsInfoPane(sd, sd.certVerifier);
-        } else if (sd.dialogType == DialogType.SINGLE_CERT_INFO) {
+        } else if (type == DialogType.SINGLE_CERT_INFO) {
             lpanel = new SingleCertInfoPane(sd, sd.certVerifier);
-        } else if (sd.dialogType == DialogType.ACCESS_WARNING) {
+        } else if (type == DialogType.ACCESS_WARNING) {
             lpanel = new AccessWarningPane(sd, sd.extras, sd.certVerifier);
-        } else if (sd.dialogType == DialogType.APPLET_WARNING) {
+        } else if (type == DialogType.APPLET_WARNING) {
             lpanel = new AppletWarningPane(sd, sd.certVerifier);
-        } else if (sd.dialogType == DialogType.PARTIALLYSIGNED_WARNING) {
+        } else if (type == DialogType.PARTIALLYSIGNED_WARNING) {
             lpanel = AppTrustWarningDialog.partiallySigned(sd, sd.file, (SecurityDelegate) sd.extras[0]);
-        } else if (sd.dialogType == DialogType.UNSIGNED_WARNING) {
+        } else if (type == DialogType.UNSIGNED_WARNING) {
             lpanel = AppTrustWarningDialog.unsigned(sd, sd.file); // Only necessary for applets on 'high security' or above
-        } else if (sd.dialogType == DialogType.AUTHENTICATION) {
+        } else if (type == DialogType.AUTHENTICATION) {
             lpanel = new PasswordAuthenticationPane(sd, sd.extras);
-        } else if (sd.dialogType == DialogType.UNSIGNED_EAS_NO_PERMISSIONS_WARNING) {
+        } else if (type == DialogType.UNSIGNED_EAS_NO_PERMISSIONS_WARNING) {
             lpanel = new MissingPermissionsAttributePanel(sd, sd.file.getTitle(), sd.file.getCodeBase().toExternalForm());
-        } else if (sd.dialogType == DialogType.MISSING_ALACA) {
+        } else if (type == DialogType.MISSING_ALACA) {
             lpanel = new MissingALACAttributePanel(sd, sd.file.getTitle(), (String) sd.extras[0], (String) sd.extras[1]);
-        } else if (sd.dialogType == DialogType.MATCHING_ALACA) {
+        } else if (type == DialogType.MATCHING_ALACA) {
             lpanel = AppTrustWarningDialog.matchingAlaca(sd, sd.file, (String) sd.extras[0], (String) sd.extras[1]);
         } else {
             throw new RuntimeException("Unknown value of " + sd.dialogType + ". Panel will be null. Tahts not allowed.");
@@ -410,4 +422,16 @@
         return  panel.getDefaultPositiveAnswer();
     }
 
+    String getText() {
+        return panel.getText();
+    }
+
+    DialogResult readFromStdIn(String what){
+        return panel.readFromStdIn(what);
+    }
+
+    String helpToStdIn(){
+        return panel.helpToStdIn();
+    }
+
 }
--- a/netx/net/sourceforge/jnlp/security/SecurityDialogMessageHandler.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/SecurityDialogMessageHandler.java	Thu Jun 18 12:29:34 2015 +0200
@@ -37,6 +37,8 @@
 
 package net.sourceforge.jnlp.security;
 
+import java.io.IOException;
+
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.security.AccessController;
@@ -45,7 +47,9 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import net.sourceforge.jnlp.config.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.runtime.Translator;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletTrustConfirmation;
+import net.sourceforge.jnlp.security.dialogresults.BasicDialogValue;
 import net.sourceforge.jnlp.security.dialogs.remember.RememberDialog;
 import net.sourceforge.jnlp.security.dialogs.remember.RememberableDialog;
 import net.sourceforge.jnlp.security.dialogs.remember.SavedRememberAction;
@@ -124,9 +128,11 @@
             unlockMessagesClient(message);
         } else {
             
-            if (!shouldPromptUser() || isHeadless()) {
+            if (!shouldPromptUser()) {
                 message.userResponse =  dialog.getDefaultNegativeAnswer();
                 unlockMessagesClient(message);
+            } else if (isHeadless()) {
+                processMessageInHeadless(dialog, message);
             } else {
                 processMessageInGui(dialog, found, message);
             }
@@ -166,6 +172,65 @@
         dialog.setVisible(true);
     }
 
+    private void processMessageInHeadless(final SecurityDialog dialog, final SecurityDialogMessage message) {
+        try {
+            boolean keepGoing = true;
+            boolean repeatAll = true;
+            do {
+                try {
+                    if (repeatAll){
+                        OutputController.getLogger().printOutLn(dialog.getText());
+                    }
+                    OutputController.getLogger().printOutLn(Translator.R("HeadlessDialogues"));
+                    OutputController.getLogger().printOutLn(dialog.helpToStdIn());
+                    String s = OutputController.getLogger().readLine();
+                    if (s == null) {
+                         throw new IOException("Stream closed");
+                    }
+                    if (s.trim().toLowerCase().equals("exit")) {
+                        JNLPRuntime.exit(0);
+                    }
+                    boolean codebase = false;
+                    boolean remember = false;
+                    if (s.startsWith("RC ")){
+                        codebase = true;
+                        remember = true;
+                        s=s.substring(3);
+                    }
+                    if (s.startsWith("R ")){
+                        remember = true;
+                        s=s.substring(2);
+                    }
+                    message.userResponse = dialog.readFromStdIn(s);
+                    keepGoing = false;
+                    try {
+                        String value = BasicDialogValue.writeNUll();
+                        if (message.userResponse != null) {
+                            value = message.userResponse.writeValue();
+                        }
+                        RememberDialog.getInstance().setOrUpdateRememberedState(dialog, codebase, new SavedRememberAction(RememberDialog.createAction(remember, message.userResponse), value));
+                    } catch (Exception ex) {    
+                        OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, ex);
+                    }
+                } catch (IOException eex) {
+                    OutputController.getLogger().log(eex);
+                    keepGoing = false;
+                } catch (IllegalArgumentException eeex){
+                    OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, eeex.toString());
+                    OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, eeex);
+                    OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, Translator.R("HDwrongValue"));
+                    repeatAll = false;
+                } catch (Exception ex) {
+                    OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, ex.toString());
+                    OutputController.getLogger().log(OutputController.Level.ERROR_ALL, ex);
+                    repeatAll = true;
+                }
+            } while (keepGoing);
+        } finally {
+            unlockMessagesClient(message);
+        }
+    }
+
     protected void unlockMessagesClient(final SecurityDialogMessage msg) {
         /* Allow the client to continue on the other side */
         if (msg.toDispose != null) {
--- a/netx/net/sourceforge/jnlp/security/dialogresults/AccessWarningPaneComplexReturn.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogresults/AccessWarningPaneComplexReturn.java	Thu Jun 18 12:29:34 2015 +0200
@@ -36,6 +36,7 @@
  */
 package net.sourceforge.jnlp.security.dialogresults;
 
+import java.util.EnumSet;
 import java.util.Objects;
 
 public class AccessWarningPaneComplexReturn implements DialogResult {
@@ -102,6 +103,11 @@
         public static enum Shortcut {
 
             BROWSER, GENERATED_JNLP, JNLP_HREF, JAVAWS_HTML;
+            
+            public static String allValues() {
+                EnumSet<Shortcut> all = EnumSet.of(BROWSER, GENERATED_JNLP, JNLP_HREF, JAVAWS_HTML);
+                return all.toString();
+            }
         }
 
         @Override
--- a/netx/net/sourceforge/jnlp/security/dialogresults/NamePassword.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogresults/NamePassword.java	Thu Jun 18 12:29:34 2015 +0200
@@ -69,7 +69,8 @@
     
 
      public static NamePassword readValue(String s) {
-        throw new UnsupportedOperationException("Not supported yet."); 
+        int  i = s.indexOf(" ");
+        return new NamePassword(s.substring(0,i), s.substring(i+1).toCharArray());
     }
 
     @Override
--- a/netx/net/sourceforge/jnlp/security/dialogs/AccessWarningPane.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/AccessWarningPane.java	Thu Jun 18 12:29:34 2015 +0200
@@ -68,16 +68,19 @@
 import net.sourceforge.jnlp.ShortcutDesc;
 import net.sourceforge.jnlp.config.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.runtime.Translator;
 import net.sourceforge.jnlp.security.CertVerifier;
 import net.sourceforge.jnlp.security.SecurityDialog;
 import net.sourceforge.jnlp.security.SecurityDialogs.AccessType;
 import net.sourceforge.jnlp.security.dialogresults.AccessWarningPaneComplexReturn;
 import net.sourceforge.jnlp.security.dialogresults.BasicDialogValue;
 import net.sourceforge.jnlp.security.dialogresults.DialogResult;
+import net.sourceforge.jnlp.security.dialogresults.YesNo;
 import net.sourceforge.jnlp.security.dialogs.remember.RememberPanelResult;
 import net.sourceforge.jnlp.security.dialogs.remember.RememberableDialog;
 import net.sourceforge.jnlp.util.FileUtils;
 import net.sourceforge.jnlp.util.XDesktopEntry;
+import net.sourceforge.jnlp.util.docprovider.formatters.formatters.PlainTextFormatter;
 
 /**
  * Provides a panel to show inside a SecurityDialog. These dialogs are
@@ -519,4 +522,21 @@
         return new AccessWarningPaneComplexReturn(true);
     }
 
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return AccessWarningPaneComplexReturn.readValue(what);
+    }
+
+    @Override
+    public String helpToStdIn() {
+        if (parent.getAccessType() == AccessType.CREATE_DESTKOP_SHORTCUT){
+            return Translator.R("AWPstdoutHint1") + PlainTextFormatter.getLineSeparator()
+                    + Translator.R("AWPstdoutHint2") + PlainTextFormatter.getLineSeparator()
+                    + Translator.R("AWPstdoutHint3", AccessWarningPaneComplexReturn.ShortcutResult.Shortcut.allValues()) + PlainTextFormatter.getLineSeparator()
+                    + Translator.R("AWPstdoutHint1") + PlainTextFormatter.getLineSeparator();
+        } else {
+            return YesNo.yes().getAllowedValues().toString();
+        }
+    }
+    
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/AppletWarningPane.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/AppletWarningPane.java	Thu Jun 18 12:29:34 2015 +0200
@@ -126,4 +126,13 @@
         return YesNoCancel.yes();
     }
 
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return YesNoCancel.readValue(what);
+    }
+    @Override
+    public String helpToStdIn() {
+        return YesNoCancel.cancel().getAllowedValues().toString();
+    }
+
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java	Thu Jun 18 12:29:34 2015 +0200
@@ -374,5 +374,14 @@
     public DialogResult getDefaultPositiveAnswer() {
         return YesNoSandbox.yes();
     }
+    
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return YesNoSandbox.readValue(what);
+    }
+    @Override
+    public String helpToStdIn() {
+        return YesNoSandbox.sandbox().getAllowedValues().toString();
+    }
 
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/CertsInfoPane.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/CertsInfoPane.java	Thu Jun 18 12:29:34 2015 +0200
@@ -360,4 +360,14 @@
     public DialogResult getDefaultPositiveAnswer() {
         return new Yes();
     }
+    
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return Yes.readValue(what);
+    }
+    
+    @Override
+    public String helpToStdIn() {
+        return new Yes().getAllowedValues().toString();
+    }
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/MissingALACAttributePanel.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/MissingALACAttributePanel.java	Thu Jun 18 12:29:34 2015 +0200
@@ -202,4 +202,13 @@
         return YesNo.yes();
     }
 
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return YesNo.readValue(what);
+    }
+
+    @Override
+    public String helpToStdIn() {
+        return YesNo.no().getAllowedValues().toString();
+    }
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/MissingPermissionsAttributePanel.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/MissingPermissionsAttributePanel.java	Thu Jun 18 12:29:34 2015 +0200
@@ -193,4 +193,14 @@
         return YesNo.yes();
     }
 
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return YesNo.readValue(what);
+    }
+    
+    @Override
+    public String helpToStdIn() {
+        return YesNo.no().getAllowedValues().toString();
+    }
+
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/MoreInfoPane.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/MoreInfoPane.java	Thu Jun 18 12:29:34 2015 +0200
@@ -139,4 +139,13 @@
         return new Yes();
     }
 
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return Yes.readValue(what);
+    }
+
+    @Override
+    public String helpToStdIn() {
+        return new Yes().getAllowedValues().toString();
+    }
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/PasswordAuthenticationPane.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/PasswordAuthenticationPane.java	Thu Jun 18 12:29:34 2015 +0200
@@ -50,6 +50,7 @@
 import javax.swing.JLabel;
 import javax.swing.JPasswordField;
 import javax.swing.JTextField;
+import net.sourceforge.jnlp.runtime.Translator;
 import net.sourceforge.jnlp.security.SecurityDialog;
 import net.sourceforge.jnlp.security.dialogresults.DialogResult;
 import net.sourceforge.jnlp.security.dialogresults.NamePassword;
@@ -195,4 +196,14 @@
         return null;
     }
 
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return NamePassword.readValue(what);
+    }
+
+    @Override
+    public String helpToStdIn() {
+        return Translator.R("PAPstdinInfo");
+    }
+
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/SecurityDialogPanel.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/SecurityDialogPanel.java	Thu Jun 18 12:29:34 2015 +0200
@@ -38,12 +38,21 @@
 package net.sourceforge.jnlp.security.dialogs;
 
 import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.lang.reflect.Method;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
 
 import javax.swing.JComponent;
 import javax.swing.JPanel;
+import javax.swing.JRadioButton;
 import net.sourceforge.jnlp.security.CertVerifier;
 import net.sourceforge.jnlp.security.SecurityDialog;
 import net.sourceforge.jnlp.security.dialogresults.DialogResult;
+import net.sourceforge.jnlp.util.docprovider.formatters.formatters.PlainTextFormatter;
+import net.sourceforge.jnlp.util.logging.OutputController;
+import net.sourceforge.jnlp.util.logging.TeeOutputStream;
 
 /**
  * Provides a JPanel for use in JNLP warning dialogs.
@@ -92,5 +101,95 @@
 
     public abstract DialogResult getDefaultPositiveAnswer();
 
+    /** this is default SecurityDialog "toString".
+     * All extending panels are recommended to override this.
+     * However, this method is reading possible shown gui,  and printing it to output
+     * so free of code, this to string have pretty nice results
+     * @return text gathered from components placed on this panel and cleaned from some html tags
+     */
+    public String getText() {
+        String s = traverse(this);
+        if (s != null) {
+            s = s.replace("<html>", "").replace("</html>", "")
+                    .replace("<head>", "").replace("</head>", "")
+                    .replace("<body>", "").replace("</body>", "")
+                    .replace("<br>", PlainTextFormatter.getLineSeparator())
+                    .replace("<BR>", PlainTextFormatter.getLineSeparator())
+                    .replace("<br/>", PlainTextFormatter.getLineSeparator())
+                    .replace("<BR/>", PlainTextFormatter.getLineSeparator()); //see htmlWrap and its usages.. but eg a href is ok to keep
+            s = s.replaceAll("(?m)^\\s+$", "");
+            while (s.contains(PlainTextFormatter.getLineSeparator() + PlainTextFormatter.getLineSeparator())) {
+                s = s.replace(PlainTextFormatter.getLineSeparator() + PlainTextFormatter.getLineSeparator(), PlainTextFormatter.getLineSeparator());
+            }
+        }
+        
+        return s;
+    }
+
+    private String traverse(Container co) {
+        return traverse(co, true, JButton.class, JRadioButton.class, JCheckBox.class);
+    }
+
+    private String traverse(Container co, boolean skipClassName, Class... skipClasses) {
+        StringBuilder sb = new StringBuilder();
+        Component[] c = co.getComponents();
+        compIter:
+        for (Component c1 : c) {
+            //searching to depth is important
+            if (c1 instanceof Container){
+                String s = traverse((Container) c1);
+                sb.append(s);
+            } 
+            //eg jlabel is also container
+            for (Class clazz : skipClasses) {
+                if (c1.getClass() == clazz){
+                    continue compIter;
+                }
+            }            
+            String s;
+            Method getText = getGetText(c1.getClass());
+            if (getText != null) {
+                s = getText(c1, getText);
+            } else {
+                s = c1.toString();
+            }
+            if (s != null) {
+                s = s.trim();
+                if (s.isEmpty()){
+                    continue;
+                }
+                if (!skipClassName){
+                    sb.append(s).append(PlainTextFormatter.getLineSeparator());
+                } else 
+                if (!s.contains(c1.getClass().getSimpleName()))  {
+                    sb.append(s).append(PlainTextFormatter.getLineSeparator());
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    private Method getGetText(Class aClass) {
+        try {
+            String methodName = "getText";
+            return aClass.getMethod(methodName);
+        } catch (Exception ex) {
+            OutputController.getLogger().log(ex);
+            return null;
+        }
+    }
+
+    private String getText(Component c1, Method getText) {
+        try {
+            return (String) getText.invoke(c1);
+        } catch (Exception ex) {
+            OutputController.getLogger().log(ex);
+            return null;
+        }
+    }
+
+    public abstract DialogResult readFromStdIn(String what);
+
+    public abstract String helpToStdIn() ;
 
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningPanel.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningPanel.java	Thu Jun 18 12:29:34 2015 +0200
@@ -309,4 +309,14 @@
         return YesNoSandboxLimited.yes();
     }
 
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return YesNoSandboxLimited.readValue(what);
+    }
+    
+    @Override
+    public String helpToStdIn() {
+        return YesNoSandboxLimited.yes().getAllowedValues().toString();
+    }
+    
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java	Thu Jun 18 12:29:34 2015 +0200
@@ -182,4 +182,13 @@
         return YesNoSandbox.yes();
     }
 
+    @Override
+    public DialogResult readFromStdIn(String what) {
+        return YesNoSandbox.readValue(what);
+    }
+    @Override
+    public String helpToStdIn() {
+        return YesNoSandbox.sandbox().getAllowedValues().toString();
+    }
+    
 }
--- a/netx/net/sourceforge/jnlp/security/dialogs/remember/RememberDialog.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/security/dialogs/remember/RememberDialog.java	Thu Jun 18 12:29:34 2015 +0200
@@ -48,12 +48,26 @@
 
     public void setOrUpdateRememberedState(SecurityDialog dialog) {
         RememberableDialog found = findRememberablePanel(dialog);
+        if (found == null) {
+            return;
+        }
         String value =  BasicDialogValue.writeNUll();
         if (found.getValue()!=null){
             value = found.getValue().writeValue();
         }
         SavedRememberAction action = new SavedRememberAction(createAction(found.getRemeberAction().isRemember(), found.getValue()), value);
-        UnsignedAppletTrustConfirmation.updateAppletAction(found.getFile(), action, found.getRemeberAction().isCodebase(), (Class<RememberableDialog>) found.getClass());
+        setOrUpdateRememberedState(dialog, found.getRemeberAction().isCodebase(), action);
+    }
+    
+    /*
+     * for headless dialogues
+     */
+     public void setOrUpdateRememberedState(SecurityDialog dialog, boolean wholeCodebase, SavedRememberAction action) {
+        RememberableDialog found = findRememberablePanel(dialog);
+        if (found == null) {
+            return;
+        }
+        UnsignedAppletTrustConfirmation.updateAppletAction(found.getFile(), action, wholeCodebase, (Class<RememberableDialog>) found.getClass());
     }
 
     public SavedRememberAction getRememberedState(SecurityDialog dialog) {
@@ -95,7 +109,7 @@
         return null;
     }
 
-    private ExecuteAppletAction createAction(boolean pernament, DialogResult value) {
+    public static ExecuteAppletAction createAction(boolean pernament, DialogResult value) {
         if (value == null){
             return ExecuteAppletAction.NO; 
         }
--- a/netx/net/sourceforge/jnlp/util/logging/OutputController.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/netx/net/sourceforge/jnlp/util/logging/OutputController.java	Thu Jun 18 12:29:34 2015 +0200
@@ -35,6 +35,9 @@
  */
 package net.sourceforge.jnlp.util.logging;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -105,6 +108,8 @@
     private List<MessageWithHeader> messageQue = new LinkedList<MessageWithHeader>();
     private MessageQueConsumer messageQueConsumer = new MessageQueConsumer();
     Thread consumerThread;
+     /*stdin reader for headless dialogues*/
+    private BufferedReader br;
 
     //bounded to instance
     private class MessageQueConsumer implements Runnable {
@@ -406,5 +411,12 @@
         SystemLogHolder.INSTANCE = sysLog;
     }
     
+    public synchronized String readLine() throws IOException {
+        if (br == null) {
+            br = new BufferedReader(new InputStreamReader(System.in));
+        }
+        return br.readLine();
+    }
+    
     
 }
--- a/tests/netx/unit/net/sourceforge/jnlp/security/SecurityDialogsTest.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/tests/netx/unit/net/sourceforge/jnlp/security/SecurityDialogsTest.java	Thu Jun 18 12:29:34 2015 +0200
@@ -36,8 +36,10 @@
  */
 package net.sourceforge.jnlp.security;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.reflect.Field;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -56,8 +58,8 @@
 import net.sourceforge.jnlp.security.dialogresults.BasicDialogValue;
 import net.sourceforge.jnlp.security.dialogresults.NamePassword;
 import net.sourceforge.jnlp.security.dialogresults.YesNo;
-import net.sourceforge.jnlp.security.dialogresults.YesNoSandbox;
 import net.sourceforge.jnlp.util.FileUtils;
+import net.sourceforge.jnlp.util.logging.NoStdOutErrTest;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Assert;
@@ -65,7 +67,7 @@
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-public class SecurityDialogsTest {
+public class SecurityDialogsTest extends NoStdOutErrTest {
 
     private static boolean wasHeadless;
     private static boolean wasTrustAll;
@@ -212,11 +214,11 @@
             testAllDialogs(ExpectedResults.PositiveResults);
             checkUnsignedActing(true);
             setAS(AppletSecurityLevel.ASK_UNSIGNED);
-            checkUnsignedActing(true, false);
+            checkUnsignedActing(true, null);
             setAS(AppletSecurityLevel.DENY_ALL);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
             setAS(AppletSecurityLevel.DENY_UNSIGNED);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
         } finally {
             resetQueue();
         }
@@ -230,17 +232,20 @@
         setPrompt(true); //should not metter becasue is headless
         setAS(AppletSecurityLevel.ALLOW_UNSIGNED);
         fakeQueue();
+        InputStream backup = System.in;
         try {
             fakeQueue();
-            testAllDialogs(ExpectedResults.NegativeResults);
+            System.setIn(new ByteArrayInputStream(new byte[0]));
+            testAllDialogsNullResaults();
             checkUnsignedActing(true);
             setAS(AppletSecurityLevel.ASK_UNSIGNED);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
             setAS(AppletSecurityLevel.DENY_ALL);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
             setAS(AppletSecurityLevel.DENY_UNSIGNED);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
         } finally {
+            System.setIn(backup);
             resetQueue();
         }
     }
@@ -257,11 +262,11 @@
             testAllDialogs(ExpectedResults.PositiveResults);
             checkUnsignedActing(true);
             setAS(AppletSecurityLevel.ASK_UNSIGNED);
-            checkUnsignedActing(true, false);
+            checkUnsignedActing(true, null);
             setAS(AppletSecurityLevel.DENY_ALL);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
             setAS(AppletSecurityLevel.DENY_UNSIGNED);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
         } finally {
             resetQueue();
         }
@@ -279,11 +284,11 @@
             testAllDialogs(ExpectedResults.NegativeResults);
             checkUnsignedActing(true);
             setAS(AppletSecurityLevel.ASK_UNSIGNED);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
             setAS(AppletSecurityLevel.DENY_ALL);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
             setAS(AppletSecurityLevel.DENY_UNSIGNED);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
         } finally {
             resetQueue();
         }
@@ -313,18 +318,46 @@
         Assert.assertEquals(r.b, r9);
     }
 
-    private void checkUnsignedActing(boolean b) throws MalformedURLException {
+    private void testAllDialogsNullResaults() throws MalformedURLException {
+        //anything but  shoertcut
+        AccessWarningPaneComplexReturn r1 = SecurityDialogs.showAccessWarningDialog(SecurityDialogs.AccessType.PRINTER, crtJnlpF(), null);
+        Assert.assertEquals(null, r1);
+        //shortcut
+        AccessWarningPaneComplexReturn r2 = SecurityDialogs.showAccessWarningDialog(SecurityDialogs.AccessType.CREATE_DESTKOP_SHORTCUT, crtJnlpF(), null);
+        Assert.assertEquals(null, r2);
+        YesNo r3 = SecurityDialogs.showUnsignedWarningDialog(crtJnlpF());
+        Assert.assertEquals(null, r3);
+        //cant emualte security delegate now
+        //YesNoSandbox r4 = SecurityDialogs.showCertWarningDialog(SecurityDialogs.AccessType.UNVERIFIED, crtJnlpF(), null, null);
+        //Assert.assertEquals(r.p, r4.getValue());
+        //YesNo r5 = SecurityDialogs.showPartiallySignedWarningDialog(crtJnlpF(), null, null);
+        //Assert.assertEquals(r.ea, r5);
+        NamePassword r6 = SecurityDialogs.showAuthenicationPrompt(null, 123456, null, null);
+        Assert.assertEquals(null, r6);
+        boolean r7 = SecurityDialogs.showMissingALACAttributePanel(crtJnlpF(), null, new HashSet<URL>());
+        Assert.assertEquals(false, r7);
+        boolean r8 = SecurityDialogs.showMatchingALACAttributePanel(crtJnlpF(), url, new HashSet<URL>());
+        Assert.assertEquals(false, r8);
+        boolean r9 = SecurityDialogs.showMissingPermissionsAttributeDialogue(crtJnlpF());
+        Assert.assertEquals(false, r9);
+    }
+
+    private void checkUnsignedActing(Boolean b) throws MalformedURLException {
         checkUnsignedActing(b, b);
     }
 
     /*
      *  testPartiallySignedBehaviour(); needs security delegate to set sandbox, so somtetimes results are strange
      */
-    private void checkUnsignedActing(boolean b1, boolean b2) throws MalformedURLException {
-        boolean r10 = testUnsignedBehaviour();
-        Assert.assertEquals(b1, r10);
-        boolean r11 = testPartiallySignedBehaviour();
-        Assert.assertEquals(b2, r11);
+    private void checkUnsignedActing(Boolean b1, Boolean b2) throws MalformedURLException {
+        if (b1 != null) {
+            boolean r10 = testUnsignedBehaviour();
+            Assert.assertEquals(b1.booleanValue(), r10);
+        }
+        if (b2 != null) {
+            boolean r11 = testPartiallySignedBehaviour();
+            Assert.assertEquals(b2.booleanValue(), r11);
+        }
     }
 
     private boolean testUnsignedBehaviour() throws MalformedURLException {
@@ -419,32 +452,43 @@
         Assert.assertEquals(metcounter, npecounter + allowedRuns);
     }
 
-    private void checkUnsignedNPE(boolean b) throws MalformedURLException {
+    private void checkUnsignedNPE(Boolean b) throws MalformedURLException {
         checkUnsignedNPE(b, b);
     }
 
     /*
      testPartiallySignedBehaviour(); needs security delegate to set sandbox, so somtetimes results are strange
      */
-    private void checkUnsignedNPE(boolean b1, boolean b2) throws MalformedURLException {
+    private void checkUnsignedNPE(Boolean b1, Boolean b2) throws MalformedURLException {
         int metcounter = 0;
+        int maxcount = 0;
         boolean ex1 = false;
         boolean ex2 = false;
-        try {
-            metcounter++;
-            testPartiallySignedBehaviour();
-        } catch (NullPointerException ex) {
-            ex1 = true;
+        if (b1 != null) {
+            maxcount++;
+            try {
+                metcounter++;
+                testPartiallySignedBehaviour();
+            } catch (NullPointerException ex) {
+                ex1 = true;
+            }
         }
-        try {
-            metcounter++;
-            testUnsignedBehaviour();
-        } catch (NullPointerException ex) {
-            ex2 = true;
+        if (b2 != null) {
+            maxcount++;
+            try {
+                metcounter++;
+                testUnsignedBehaviour();
+            } catch (NullPointerException ex) {
+                ex2 = true;
+            }
         }
-        Assert.assertEquals(2, metcounter);
-        Assert.assertEquals(b1, ex1);
-        Assert.assertEquals(b2, ex2);
+        Assert.assertEquals(maxcount, metcounter);
+        if (b1 != null) {
+            Assert.assertEquals(b1.booleanValue(), ex1);
+        }
+        if (b2 != null) {
+            Assert.assertEquals(b2.booleanValue(), ex2);
+        }
     }
 
     @Test(timeout = 10000)//if gui pops up
@@ -479,11 +523,11 @@
         setAS(AppletSecurityLevel.ASK_UNSIGNED);
         try {
             fakeQueue();
-            checkUnsignedActing(true, false);
+            checkUnsignedActing(true, null);
             setAS(AppletSecurityLevel.DENY_ALL);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
             setAS(AppletSecurityLevel.DENY_UNSIGNED);
-            checkUnsignedActing(false);
+            checkUnsignedActing(false, null);
         } finally {
             resetQueue();
         }
@@ -532,15 +576,15 @@
             fakeQueue();
             boolean r10 = testUnsignedBehaviour();
             Assert.assertEquals(false, r10);
-            checkUnsignedNPE(false);
+            checkUnsignedNPE(null, false);
             setAS(AppletSecurityLevel.DENY_ALL);
             boolean r11 = testUnsignedBehaviour();
             Assert.assertEquals(false, r11);
-            checkUnsignedNPE(false);
+            checkUnsignedNPE(null, false);
             setAS(AppletSecurityLevel.DENY_UNSIGNED);
             boolean r12 = testUnsignedBehaviour();
             Assert.assertEquals(false, r12);
-            checkUnsignedNPE(false);
+            checkUnsignedNPE(null, false);
         } finally {
             resetQueue();
         }
--- a/tests/test-extensions/net/sourceforge/jnlp/util/logging/NoStdOutErrTest.java	Wed Jun 17 17:15:52 2015 +0200
+++ b/tests/test-extensions/net/sourceforge/jnlp/util/logging/NoStdOutErrTest.java	Thu Jun 18 12:29:34 2015 +0200
@@ -37,6 +37,9 @@
 
 package net.sourceforge.jnlp.util.logging;
 
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import net.sourceforge.jnlp.ServerAccess;
 import org.junit.AfterClass;
@@ -60,7 +63,16 @@
     /*
      * "printed" exceptions are otherwise  consumed via junit if thrown :-/
      */
+    private static Object origOut;
+    private static Object origErr;
 
+    private static PrintStream dummy = new PrintStream(new OutputStream() {
+                @Override
+                public void write(int b) {
+                    //DO NOTHING
+                }
+            });
+    
     @BeforeClass
     public static synchronized void disableStds() {
         try {
@@ -73,6 +85,7 @@
             OutputController.getLogger().flush();
             origialStds = LogConfig.getLogConfig().isLogToStreams();
             invokeSetLogToStreams(false);
+            removeStreams();
         } catch (Exception ex) {
             ServerAccess.logException(ex);
         }
@@ -83,6 +96,7 @@
         try {
             OutputController.getLogger().flush();
             invokeSetLogToStreams(origialStds);
+            resetStreams();
         } catch (Exception ex) {
             ServerAccess.logException(ex);
         }
@@ -97,4 +111,32 @@
             ServerAccess.logException(ex);
         }
     }
+    
+    private static synchronized void removeStreams() {
+        try {
+            Field lcs1 = OutputController.class.getDeclaredField("outLog");
+            lcs1.setAccessible(true);
+            origOut = lcs1.get(OutputController.getLogger());
+            Field lcs2 = OutputController.class.getDeclaredField("errLog");
+            lcs2.setAccessible(true);
+            origErr = lcs1.get(OutputController.getLogger());
+            lcs1.set(OutputController.getLogger(), new PrintStreamLogger(dummy));
+            lcs2.set(OutputController.getLogger(), new PrintStreamLogger(dummy));
+        } catch (Exception ex) {
+            ServerAccess.logException(ex);
+        }
+    }
+    
+    private static synchronized void resetStreams() {
+        try {
+            Field lcs1 = OutputController.class.getDeclaredField("outLog");
+            lcs1.setAccessible(true);
+            Field lcs2 = OutputController.class.getDeclaredField("errLog");
+            lcs2.setAccessible(true);
+            lcs1.set(OutputController.getLogger(), origOut);
+            lcs2.set(OutputController.getLogger(), origErr);
+        } catch (Exception ex) {
+            ServerAccess.logException(ex);
+        }
+    }
 }