changeset 31:30efa2ff349b

use deployment.properties file for infrastructure related configuration 2010-11-03 Omair Majid <omajid@redhat.com> * netx/net/sourceforge/jnlp/Launcher.java (markNetxRunning): Get file name from configuration. (markNetxStopped): Likewise. * netx/net/sourceforge/jnlp/cache/CacheUtil.java (clearCache): Get cache directory from configuration. (okToClearCache): Get netx_running file from configuration. (getCacheFile): Get cache directory from configuration. (urlToPath): Change semantics to take in the full path of the directory instead of a directory under runtime. * netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java: Change DEPLOYMENT_DIR to ".icedtea". Add constants KEY_USER_CACHE_DIR, KEY_USER_PERSISTENCE_CACHE_DIR, KEY_SYSTEM_CACHE_DIR, KEY_USER_LOG_DIR, KEY_USER_TMP_DIR, KEY_USER_LOCKS_DIR, and KEY_USER_NETX_RUNNING_FILE. (load): Use DEPLOYMENT_DIR instead of hardcoded string. (loadDefaultProperties): Add LOCKS_DIR. Replace strings with constants. Add new default values for persistence cache directory, single instance locks directory and the netx_running file. * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java: Remove unneeded TMP_DIR, LOCKS_DIR and NETX_RUNNING_FILE * netx/net/sourceforge/jnlp/services/SingleInstanceLock.java (getLockFile): Get locks directory from configuration. * netx/net/sourceforge/jnlp/services/XPersistenceService.java (toCacheFile): Get persistence cache directory from configuration. * netx/net/sourceforge/jnlp/util/XDesktopEntry.java (getContentsAsReader): Get cache directory from configuration. (installDesktopLauncher): Get temporary directory from configuration. Make parent directories if required. * plugin/icedteanp/java/sun/applet/JavaConsole.java (initialize): Get log directory from configuration and create the error and output files under it. * plugin/icedteanp/java/sun/applet/PluginMain.java: PLUGIN_STDERR_FILE and PLUGIN_STDOUT_FILE are now just filesnames. (PluginMain): Use configuration for finding the log directory. Initialize JNLPRuntime before creating the stderr and stdout logs.
author Omair Majid <omajid@redhat.com>
date Wed, 03 Nov 2010 11:33:41 -0400
parents 6c2527d42900
children 2405cef22921
files ChangeLog netx/net/sourceforge/jnlp/Launcher.java netx/net/sourceforge/jnlp/cache/CacheUtil.java netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java netx/net/sourceforge/jnlp/services/SingleInstanceLock.java netx/net/sourceforge/jnlp/services/XPersistenceService.java netx/net/sourceforge/jnlp/util/XDesktopEntry.java plugin/icedteanp/java/sun/applet/JavaConsole.java plugin/icedteanp/java/sun/applet/PluginMain.java
diffstat 10 files changed, 136 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Nov 01 11:44:15 2010 -0400
+++ b/ChangeLog	Wed Nov 03 11:33:41 2010 -0400
@@ -1,3 +1,41 @@
+2010-11-03  Omair Majid  <omajid@redhat.com>
+
+	* netx/net/sourceforge/jnlp/Launcher.java
+	(markNetxRunning): Get file name from configuration.
+	(markNetxStopped): Likewise.
+	* netx/net/sourceforge/jnlp/cache/CacheUtil.java
+	(clearCache): Get cache directory from configuration.
+	(okToClearCache): Get netx_running file from configuration.
+	(getCacheFile): Get cache directory from configuration.
+	(urlToPath): Change semantics to take in the full path of the
+	directory instead of a directory under runtime.
+	* netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java:
+	Change DEPLOYMENT_DIR to ".icedtea". Add constants
+	KEY_USER_CACHE_DIR, KEY_USER_PERSISTENCE_CACHE_DIR,
+	KEY_SYSTEM_CACHE_DIR, KEY_USER_LOG_DIR, KEY_USER_TMP_DIR,
+	KEY_USER_LOCKS_DIR, and KEY_USER_NETX_RUNNING_FILE.
+	(load): Use DEPLOYMENT_DIR instead of hardcoded string.
+	(loadDefaultProperties): Add LOCKS_DIR. Replace strings with
+	constants. Add new default values for persistence cache directory,
+	single instance locks directory and the netx_running file.
+	* netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java: Remove
+	unneeded TMP_DIR, LOCKS_DIR and NETX_RUNNING_FILE
+	* netx/net/sourceforge/jnlp/services/SingleInstanceLock.java
+	(getLockFile): Get locks directory from configuration.
+	* netx/net/sourceforge/jnlp/services/XPersistenceService.java
+	(toCacheFile): Get persistence cache directory from configuration.
+	* netx/net/sourceforge/jnlp/util/XDesktopEntry.java
+	(getContentsAsReader): Get cache directory from configuration.
+	(installDesktopLauncher): Get temporary directory from
+	configuration. Make parent directories if required.
+	* plugin/icedteanp/java/sun/applet/JavaConsole.java
+	(initialize): Get log directory from configuration and create the
+	error and output files under it.
+	* plugin/icedteanp/java/sun/applet/PluginMain.java:
+	PLUGIN_STDERR_FILE and PLUGIN_STDOUT_FILE are now just filesnames.
+	(PluginMain): Use configuration for finding the log directory.
+	Initialize JNLPRuntime before creating the stderr and stdout logs.
+
 2010-11-01  Omair Majid  <omajid@redhat.com>
 
 	* Makefile.am (clean-IcedTeaPlugin): Only delete launcher directory if it
--- a/netx/net/sourceforge/jnlp/Launcher.java	Mon Nov 01 11:44:15 2010 -0400
+++ b/netx/net/sourceforge/jnlp/Launcher.java	Wed Nov 03 11:33:41 2010 -0400
@@ -43,6 +43,7 @@
 import net.sourceforge.jnlp.runtime.AppThreadGroup;
 import net.sourceforge.jnlp.runtime.AppletInstance;
 import net.sourceforge.jnlp.runtime.ApplicationInstance;
+import net.sourceforge.jnlp.runtime.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.JNLPClassLoader;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
 import net.sourceforge.jnlp.services.InstanceExistsException;
@@ -724,7 +725,8 @@
         try {
             String message = "This file is used to check if netx is running";
 
-            File netxRunningFile = new File(JNLPRuntime.NETX_RUNNING_FILE);
+            File netxRunningFile = new File(JNLPRuntime.getConfiguration()
+                    .getProperty(DeploymentConfiguration.KEY_USER_NETX_RUNNING_FILE));
             netxRunningFile.getParentFile().mkdirs();
             if (netxRunningFile.createNewFile()) {
                 FileOutputStream fos = new FileOutputStream(netxRunningFile);
@@ -749,7 +751,7 @@
             if (fileLock != null && fileLock.isShared()) {
                 if (JNLPRuntime.isDebug()) {
                     System.out.println("Acquired shared lock on " +
-                            JNLPRuntime.NETX_RUNNING_FILE + " to indicate javaws is running");
+                            netxRunningFile.toString() + " to indicate javaws is running");
                 }
             } else {
                 fileLock = null;
@@ -773,7 +775,9 @@
             fileLock.channel().close();
             fileLock = null;
             if (JNLPRuntime.isDebug()) {
-                System.out.println("Release shared lock on " + JNLPRuntime.NETX_RUNNING_FILE);
+                String file = JNLPRuntime.getConfiguration()
+                    .getProperty(DeploymentConfiguration.KEY_USER_NETX_RUNNING_FILE);
+                System.out.println("Release shared lock on " + file);
             }
         } catch (IOException e) {
             e.printStackTrace();
--- a/netx/net/sourceforge/jnlp/cache/CacheUtil.java	Mon Nov 01 11:44:15 2010 -0400
+++ b/netx/net/sourceforge/jnlp/cache/CacheUtil.java	Wed Nov 03 11:33:41 2010 -0400
@@ -141,7 +141,8 @@
             return;
         }
 
-        File cacheDir = new File(JNLPRuntime.getBaseDir() + File.separator + "cache");
+        File cacheDir = new File(JNLPRuntime.getConfiguration()
+                .getProperty(DeploymentConfiguration.KEY_USER_CACHE_DIR));
         if (!(cacheDir.isDirectory())) {
             return;
         }
@@ -150,7 +151,8 @@
             System.err.println("Clearing cache directory: " + cacheDir);
         }
         try {
-            FileUtils.recursiveDelete(cacheDir, JNLPRuntime.getBaseDir());
+            cacheDir = cacheDir.getCanonicalFile();
+            FileUtils.recursiveDelete(cacheDir, cacheDir);
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
@@ -161,7 +163,8 @@
      * @return true if the cache can be cleared at this time without problems
      */
     private static boolean okToClearCache() {
-        File otherJavawsRunning = new File(JNLPRuntime.NETX_RUNNING_FILE);
+        File otherJavawsRunning = new File(JNLPRuntime.getConfiguration()
+                .getProperty(DeploymentConfiguration.KEY_USER_NETX_RUNNING_FILE));
         try {
             if (otherJavawsRunning.isFile()) {
                 FileOutputStream fis = new FileOutputStream(otherJavawsRunning);
@@ -289,7 +292,9 @@
             throw new IllegalArgumentException(R("CNotCacheable", source));
 
         try {
-            File localFile = urlToPath(source, "cache");
+            String cacheDir = JNLPRuntime.getConfiguration()
+                .getProperty(DeploymentConfiguration.KEY_USER_CACHE_DIR);
+            File localFile = urlToPath(source, cacheDir);
             localFile.getParentFile().mkdirs();
 
             return localFile;
@@ -345,20 +350,23 @@
     }
 
     /**
-     * Converts a URL into a local path string within the runtime's
-     * base directory.
+     * Converts a URL into a local path string within the given directory. For
+     * example a url with subdirectory /tmp/ will
+     * result in a File that is located somewhere within /tmp/
      *
      * @param location the url
-     * @param subdir subdirectory under the base directory
+     * @param subdir the subdirectory
      * @return the file
      */
     public static File urlToPath(URL location, String subdir) {
+        if (subdir == null) {
+            throw new NullPointerException();
+        }
+
         StringBuffer path = new StringBuffer();
 
-        if (subdir != null) {
-            path.append(subdir);
-            path.append(File.separatorChar);
-        }
+        path.append(subdir);
+        path.append(File.separatorChar);
 
         path.append(location.getProtocol());
         path.append(File.separatorChar);
@@ -366,7 +374,7 @@
         path.append(File.separatorChar);
         path.append(location.getPath().replace('/', File.separatorChar));
 
-        return new File(JNLPRuntime.getBaseDir(), FileUtils.sanitizePath(path.toString()));
+        return new File(FileUtils.sanitizePath(path.toString()));
     }
 
 
--- a/netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java	Mon Nov 01 11:44:15 2010 -0400
+++ b/netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java	Wed Nov 03 11:33:41 2010 -0400
@@ -28,6 +28,7 @@
 import java.io.Reader;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.channels.FileLock;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
@@ -98,7 +99,7 @@
         }
     }
 
-    public static final String DEPLOYMENT_DIR = ".netx";
+    public static final String DEPLOYMENT_DIR = ".icedtea";
     public static final String DEPLOYMENT_CONFIG = "deployment.config";
     public static final String DEPLOYMENT_PROPERTIES = "deployment.properties";
 
@@ -125,6 +126,22 @@
     public static final int PROXY_TYPE_AUTO = 2;
     public static final int PROXY_TYPE_BROWSER = 3;
 
+    public static final String KEY_USER_CACHE_DIR = "deployment.user.cachedir";
+    public static final String KEY_USER_PERSISTENCE_CACHE_DIR = "deployment.user.pcachedir";
+    public static final String KEY_SYSTEM_CACHE_DIR = "deployment.system.cachedir";
+    public static final String KEY_USER_LOG_DIR = "deployment.user.logdir";
+    public static final String KEY_USER_TMP_DIR = "deployment.user.tmp";
+    /** the directory containing locks for single instance applications */
+    public static final String KEY_USER_LOCKS_DIR = "deployment.user.locksdir";
+    /**
+     * The netx_running file is used to indicate if any instances of netx are
+     * running (this file may exist even if no instances are running). All netx
+     * instances acquire a shared lock on this file. If this file can be locked
+     * (using a {@link FileLock}) in exclusive mode, then other netx instances
+     * are not running
+     */
+    public static final String KEY_USER_NETX_RUNNING_FILE = "deployment.user.runningfile";
+
     public enum ConfigType {
         System, User
     }
@@ -156,7 +173,7 @@
      */
     public void load() throws ConfigurationException {
         // make sure no state leaks if security check fails later on
-        File userFile = new File(System.getProperty("user.home") + File.separator + ".netx"
+        File userFile = new File(System.getProperty("user.home") + File.separator + DEPLOYMENT_DIR
                 + File.separator + DEPLOYMENT_PROPERTIES);
 
         SecurityManager sm = System.getSecurityManager();
@@ -277,6 +294,10 @@
         final String USER_HOME = System.getProperty("user.home") + File.separator + DEPLOYMENT_DIR;
         final String USER_SECURITY = USER_HOME + File.separator + "security";
 
+        final String LOCKS_DIR = System.getProperty("java.io.tmpdir") + File.separator
+                + System.getProperty("user.name") + File.separator + "netx" + File.separator
+                + "locks";
+
         /*
          * This is more or less a straight copy from the deployment
          * configuration page, with occasional replacements of "" or no-defaults
@@ -285,10 +306,13 @@
 
         String[][] defaults = new String[][] {
             /* infrastructure */
-            { "deployment.user.cachedir", USER_HOME + File.separator + "cache" },
-            { "deployment.system.cachedir", null },
-            { "deployment.user.logdir", USER_HOME + File.separator + "log" },
-            { "deployment.user.tmp", USER_HOME + File.separator + "tmp" },
+            { KEY_USER_CACHE_DIR, USER_HOME + File.separator + "cache" },
+            { KEY_USER_PERSISTENCE_CACHE_DIR, USER_HOME + File.separator + "pcache" },
+            { KEY_SYSTEM_CACHE_DIR, null },
+            { KEY_USER_LOG_DIR, USER_HOME + File.separator + "log" },
+            { KEY_USER_TMP_DIR, USER_HOME + File.separator + "tmp" },
+            { KEY_USER_LOCKS_DIR, LOCKS_DIR },
+            { KEY_USER_NETX_RUNNING_FILE, LOCKS_DIR + File.separator + "netx_running" },
             /* certificates and policy files */
             { "deployment.user.security.policy", "file://" + USER_SECURITY + File.separator + "java.policy" },
             { "deployment.user.security.trusted.cacerts", USER_SECURITY + File.separator + "trusted.cacerts" },
--- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Mon Nov 01 11:44:15 2010 -0400
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Wed Nov 03 11:33:41 2010 -0400
@@ -132,25 +132,6 @@
     /** the ~/.netx/security/trusted.certs file containing trusted certificates */
     public static final String CERTIFICATES_FILE = SECURITY_DIR + File.separator + "trusted.certs";
 
-    /** the /tmp/ directory used for temporary files */
-    public static final String TMP_DIR = System.getProperty("java.io.tmpdir");
-
-    /**
-     * the /tmp/$USER/netx/locks/ directory containing locks for single instance
-     * applications
-     */
-    public static final String LOCKS_DIR = TMP_DIR + File.separator + USER + File.separator
-            + "netx" + File.separator + "locks";
-
-    /**
-     * The /tmp/$USER/netx/locks/netx_running file is used to indicate if any
-     * instances of netx are running (this file may exist even if no instances
-     * are running). All netx instances acquire a shared lock on this file. If
-     * this file can be locked (using a {@link FileLock}) in exclusive mode, then
-     * other netx instances are not running
-     */
-    public static final String NETX_RUNNING_FILE = LOCKS_DIR + File.separator + "netx_running";
-
     /** the java.home directory */
     public static final String JAVA_HOME_DIR = System.getProperty("java.home");
 
--- a/netx/net/sourceforge/jnlp/services/SingleInstanceLock.java	Mon Nov 01 11:44:15 2010 -0400
+++ b/netx/net/sourceforge/jnlp/services/SingleInstanceLock.java	Wed Nov 03 11:33:41 2010 -0400
@@ -28,6 +28,7 @@
 import java.net.ServerSocket;
 
 import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.runtime.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
 import net.sourceforge.jnlp.util.FileUtils;
 
@@ -128,7 +129,8 @@
      * may or may not exist.
      */
     private File getLockFile() {
-        File baseDir = new File(JNLPRuntime.LOCKS_DIR);
+        File baseDir = new File(JNLPRuntime.getConfiguration()
+                .getProperty(DeploymentConfiguration.KEY_USER_LOCKS_DIR));
 
         if (!baseDir.isDirectory() && !baseDir.mkdirs()) {
             throw new RuntimeException(R("RNoLockDir", baseDir));
--- a/netx/net/sourceforge/jnlp/services/XPersistenceService.java	Mon Nov 01 11:44:15 2010 -0400
+++ b/netx/net/sourceforge/jnlp/services/XPersistenceService.java	Wed Nov 03 11:33:41 2010 -0400
@@ -80,7 +80,9 @@
      * @return the file
      */
     protected File toCacheFile(URL location) throws MalformedURLException {
-        return CacheUtil.urlToPath(location, "pcache");
+        String pcache = JNLPRuntime.getConfiguration()
+            .getProperty(DeploymentConfiguration.KEY_USER_PERSISTENCE_CACHE_DIR);
+        return CacheUtil.urlToPath(location, pcache);
     }
 
     /**
--- a/netx/net/sourceforge/jnlp/util/XDesktopEntry.java	Mon Nov 01 11:44:15 2010 -0400
+++ b/netx/net/sourceforge/jnlp/util/XDesktopEntry.java	Wed Nov 03 11:33:41 2010 -0400
@@ -32,6 +32,7 @@
 import net.sourceforge.jnlp.StreamEater;
 import net.sourceforge.jnlp.cache.CacheUtil;
 import net.sourceforge.jnlp.cache.UpdatePolicy;
+import net.sourceforge.jnlp.runtime.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
 
 /**
@@ -73,7 +74,9 @@
 
         String pathToJavaws = System.getProperty("java.home") + File.separator + "bin"
                 + File.separator + "javaws";
-        File cacheFile = CacheUtil.urlToPath(file.getSourceLocation(), "cache");
+        String cacheDir = JNLPRuntime.getConfiguration()
+            .getProperty(DeploymentConfiguration.KEY_USER_CACHE_DIR);
+        File cacheFile = CacheUtil.urlToPath(file.getSourceLocation(), cacheDir);
 
         String fileContents = "[Desktop Entry]\n";
         fileContents += "Version=1.0\n";
@@ -131,10 +134,14 @@
      * Install this XDesktopEntry into the user's desktop as a launcher
      */
     private void installDesktopLauncher() {
-        File shortcutFile = new File(JNLPRuntime.TMP_DIR + File.separator
-                + FileUtils.sanitizeFileName(file.getTitle()) + ".desktop");
+        File shortcutFile = new File(JNLPRuntime.getConfiguration()
+                .getProperty(DeploymentConfiguration.KEY_USER_TMP_DIR)
+                + File.separator + FileUtils.sanitizeFileName(file.getTitle()) + ".desktop");
         try {
 
+            if (!shortcutFile.getParentFile().isDirectory() && !shortcutFile.getParentFile().mkdirs()) {
+                throw new IOException(shortcutFile.getParentFile().toString());
+            }
             /*
              * Write out a Java String (UTF-16) as a UTF-8 file
              */
--- a/plugin/icedteanp/java/sun/applet/JavaConsole.java	Mon Nov 01 11:44:15 2010 -0400
+++ b/plugin/icedteanp/java/sun/applet/JavaConsole.java	Wed Nov 03 11:33:41 2010 -0400
@@ -63,6 +63,9 @@
 import javax.swing.border.EmptyBorder;
 import javax.swing.border.TitledBorder;
 
+import net.sourceforge.jnlp.runtime.DeploymentConfiguration;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+
 /**
  * A simple Java console for IcedTeaPlugin
  * 
@@ -86,6 +89,8 @@
             e.printStackTrace();
         }
 
+        final String logDir = JNLPRuntime.getConfiguration().getProperty(DeploymentConfiguration.KEY_USER_LOG_DIR);
+
         consoleWindow = new JFrame("Java Console");
 
         JPanel contentPanel = new JPanel();
@@ -104,7 +109,7 @@
         stdOutText.setEditable(false);
         stdOutText.setFont(monoSpace);
 
-        TextAreaUpdater stdOutUpdater = new TextAreaUpdater(new File(
+        TextAreaUpdater stdOutUpdater = new TextAreaUpdater(new File(logDir,
                 PluginMain.PLUGIN_STDOUT_FILE), stdOutText);
         stdOutUpdater.setName("IcedteaPlugin Console Thread(System.out)");
 
@@ -117,7 +122,7 @@
         stdErrText.setEditable(false);
         stdErrText.setFont(monoSpace);
 
-        TextAreaUpdater stdErrUpdater = new TextAreaUpdater(new File(
+        TextAreaUpdater stdErrUpdater = new TextAreaUpdater(new File(logDir,
                 PluginMain.PLUGIN_STDERR_FILE), stdErrText);
         stdErrUpdater.setName("IcedteaPlugin Console Thread(System.err)");
 
--- a/plugin/icedteanp/java/sun/applet/PluginMain.java	Mon Nov 01 11:44:15 2010 -0400
+++ b/plugin/icedteanp/java/sun/applet/PluginMain.java	Wed Nov 03 11:33:41 2010 -0400
@@ -80,6 +80,8 @@
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManager;
 
+import net.sourceforge.jnlp.runtime.DeploymentConfiguration;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
 import net.sourceforge.jnlp.security.VariableX509TrustManager;
 
 /**
@@ -87,10 +89,9 @@
  */
 public class PluginMain
 {
-
     // the files where stdout/stderr are sent to
-    public static final String PLUGIN_STDERR_FILE = System.getProperty("user.home") + "/.icedteaplugin/java.stderr";
-    public static final String PLUGIN_STDOUT_FILE = System.getProperty("user.home") + "/.icedteaplugin/java.stdout";
+    public static final String PLUGIN_STDERR_FILE = "java.stderr";
+    public static final String PLUGIN_STDOUT_FILE = "java.stdout";
 
 	final boolean redirectStreams = System.getenv().containsKey("ICEDTEAPLUGIN_DEBUG");
 	static PluginStreamHandler streamHandler;
@@ -123,16 +124,6 @@
 
     public PluginMain(String inPipe, String outPipe) {
     	
-    	try {
-    		File errFile = new File(PLUGIN_STDERR_FILE);
-    		File outFile = new File(PLUGIN_STDOUT_FILE);
-
-    		System.setErr(new TeeOutputStream(new FileOutputStream(errFile), System.err));
-    		System.setOut(new TeeOutputStream(new FileOutputStream(outFile), System.out));
-    	} catch (Exception e) {
-    		PluginDebug.debug("Unable to redirect streams");
-    		e.printStackTrace();
-    	}
 
     	connect(inPipe, outPipe);
 
@@ -141,6 +132,20 @@
     	securityContext.setStreamhandler(streamHandler);
     	AppletSecurityContextManager.addContext(0, securityContext);
 
+    	String logDir = JNLPRuntime.getConfiguration().getProperty(DeploymentConfiguration.KEY_USER_LOG_DIR);
+        try {
+            File errFile = new File(logDir, PLUGIN_STDERR_FILE);
+            errFile.getParentFile().mkdirs();
+            File outFile = new File(logDir, PLUGIN_STDOUT_FILE);
+            outFile.getParentFile().mkdirs();
+
+            System.setErr(new TeeOutputStream(new FileOutputStream(errFile), System.err));
+            System.setOut(new TeeOutputStream(new FileOutputStream(outFile), System.out));
+        } catch (Exception e) {
+            PluginDebug.debug("Unable to redirect streams");
+            e.printStackTrace();
+        }
+
 		PluginAppletViewer.setStreamhandler(streamHandler);
 		PluginAppletViewer.setPluginCallRequestFactory(new PluginCallRequestFactory());