Mercurial > hg > icedtea11
changeset 1670:a51259dbf916
2009-02-25 Omair Majid <omajid@redhat.com>
* plugin/icedtea/sun/applet/PluginMain.java:
New File. Implements a Java console for IcedTea Plugin.
* plugin/icedtea/sun/applet/JavaConsole.java
New constants PLUGIN_STDERR_FILE and PLUGIN_STDOUT_FILE for filenames that
stdout/stderr is redirected to.
(PluginMain): Always write stdout/stderr to
PLUGIN_STDERR_FILE/PLUGIN_STDOUT_FILE.
(TeeOutputStream): New class. Copies a PrintStream to a file.
(transplanted from 9259bc9bee3645c1f9a53a7f77c3da553d96882b)
author | Omair Majid <omajid@redhat.com> |
---|---|
date | Wed, 25 Feb 2009 13:34:13 -0500 |
parents | 4c8969cb6ee3 |
children | a7448ed41188 |
files | ChangeLog plugin/icedtea/sun/applet/JavaConsole.java plugin/icedtea/sun/applet/PluginMain.java |
diffstat | 3 files changed, 455 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Feb 24 14:53:39 2009 +0000 +++ b/ChangeLog Wed Feb 25 13:34:13 2009 -0500 @@ -69,6 +69,17 @@ * patches/hotspot/original/icedtea-includedb.patch, * patches/icedtea-libraries.patch: Recreated. +2009-02-25 Omair Majid <omajid@redhat.com> + + * plugin/icedtea/sun/applet/PluginMain.java: + New File. Implements a Java console for IcedTea Plugin. + * plugin/icedtea/sun/applet/JavaConsole.java + New constants PLUGIN_STDERR_FILE and PLUGIN_STDOUT_FILE for filenames that + stdout/stderr is redirected to. + (PluginMain): Always write stdout/stderr to + PLUGIN_STDERR_FILE/PLUGIN_STDOUT_FILE. + (TeeOutputStream): New class. Copies a PrintStream to a file. + 2009-02-24 Gary Benson <gbenson@redhat.com> * ports/hotspot/src/share/vm/shark/sharkBlock.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/JavaConsole.java Wed Feb 25 13:34:13 2009 -0500 @@ -0,0 +1,372 @@ +/* JavaConsole -- A java console for the plugin + Copyright (C) 2009 Red Hat + +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. */ + +package sun.applet; + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.EmptyBorder; +import javax.swing.border.TitledBorder; + +import net.sourceforge.jnlp.runtime.JNLPClassLoader; + +/** + * A simple Java console for IcedTeaPlugin + * + */ +public class JavaConsole { + + private boolean initialized = false; + + JFrame consoleWindow; + JTextArea stdErrText; + JTextArea stdOutText; + + /** + * Initialize the console + */ + public void initialize() { + + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + e.printStackTrace(); + } + + consoleWindow = new JFrame("Java Console"); + + Container contentPane = consoleWindow.getContentPane(); + contentPane.setLayout(new GridBagLayout()); + + GridBagConstraints c; + + Font monoSpace = new Font("Monospaced", Font.PLAIN, 12); + + /* std out */ + + stdOutText = new JTextArea(); + JScrollPane stdOutScrollPane = new JScrollPane(stdOutText); + stdOutScrollPane.setBorder(new TitledBorder( + new EmptyBorder(5, 5, 5, 5), "System.out")); + stdOutText.setEditable(false); + stdOutText.setFont(monoSpace); + + TextAreaUpdater stdOutUpdater = new TextAreaUpdater(new File( + PluginMain.PLUGIN_STDOUT_FILE), stdOutText); + stdOutUpdater.setName("IcedteaPlugin Console Thread(System.out)"); + + /* std err */ + + stdErrText = new JTextArea(); + JScrollPane stdErrScrollPane = new JScrollPane(stdErrText); + stdErrScrollPane.setBorder(new TitledBorder( + new EmptyBorder(5, 5, 5, 5), "System.err")); + stdErrText.setEditable(false); + stdErrText.setFont(monoSpace); + + TextAreaUpdater stdErrUpdater = new TextAreaUpdater(new File( + PluginMain.PLUGIN_STDERR_FILE), stdErrText); + stdErrUpdater.setName("IcedteaPlugin Console Thread(System.err)"); + + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, + stdOutScrollPane, stdErrScrollPane); + + c = new GridBagConstraints(); + c.fill = GridBagConstraints.BOTH; + c.gridheight = 10; + c.weighty = 1; + + contentPane.add(splitPane, c); + + /* buttons */ + + c = new GridBagConstraints(); + c.gridy = 10; + c.gridheight = 1; + c.weightx = 0.5; + c.weighty = 0; + + JPanel buttonPanel = new JPanel(); + contentPane.add(buttonPanel, c); + + JButton gcButton = new JButton("Run GC"); + buttonPanel.add(gcButton); + gcButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + printMemoryInfo(); + System.out.print("Performing Garbage Collection...."); + System.gc(); + System.out.println("Done"); + printMemoryInfo(); + } + + }); + + JButton finalizersButton = new JButton("Run Finalizers"); + buttonPanel.add(finalizersButton); + finalizersButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + printMemoryInfo(); + System.out.print("Running finalization...."); + Runtime.getRuntime().runFinalization(); + System.out.println("Done"); + printMemoryInfo(); + } + }); + + JButton memoryButton = new JButton("Memory Info"); + buttonPanel.add(memoryButton); + memoryButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + printMemoryInfo(); + } + + }); + + JButton systemPropertiesButton = new JButton("System Properties"); + buttonPanel.add(systemPropertiesButton); + systemPropertiesButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + printSystemProperties(); + } + + }); + + JButton classloadersButton = new JButton("Classloaders"); + buttonPanel.add(classloadersButton); + classloadersButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + printClassLoaders(); + } + + }); + + JButton threadListButton = new JButton("Thread List"); + buttonPanel.add(threadListButton); + threadListButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + printThreadInfo(); + } + + }); + + JButton killVmButton = new JButton("Destory VM"); + buttonPanel.add(killVmButton); + killVmButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + System.exit(0); + } + + }); + + stdOutUpdater.start(); + stdErrUpdater.start(); + + consoleWindow.setMinimumSize(new Dimension(500, 400)); + consoleWindow.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + consoleWindow.pack(); + + initialized = true; + + splitPane.setDividerLocation(0.5); + + } + + public void showConsole() { + + if (!initialized) { + initialize(); + } + + consoleWindow.setVisible(true); + } + + public void hideConsole() { + consoleWindow.setVisible(false); + } + + protected void printSystemProperties() { + + System.out.println(" ----"); + System.out.println("System Properties:"); + System.out.println(); + Properties p = System.getProperties(); + Set<Object> keys = p.keySet(); + for (Object key : keys) { + System.out.println(key.toString() + ": " + p.get(key)); + } + + System.out.println(" ----"); + } + + private void printClassLoaders() { + System.out.println(" ----"); + System.out.println("Available Classloaders: "); + Set<ClassLoader> loaders = PluginAppletSecurityContext.classLoaders.keySet(); + for (ClassLoader loader: loaders) { + System.out.println(loader.getClass().getName() + "\n" + + " codebase = " + + PluginAppletSecurityContext.classLoaders.get(loader)); + } + System.out.println(" ----"); + } + + private void printMemoryInfo() { + System.out.println(" ----- "); + System.out.println(" Memory Info:"); + System.out.println(" Max Memory: " + + String.format("%1$10d", Runtime.getRuntime().maxMemory())); + System.out.println(" Total Memory: " + + String.format("%1$10d", Runtime.getRuntime().totalMemory())); + System.out.println(" Free Memory: " + + String.format("%1$10d", Runtime.getRuntime().freeMemory())); + System.out.println(" ----"); + + } + + private void printThreadInfo() { + Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces(); + Set<Thread> keys = map.keySet(); + for (Thread key : keys) { + System.out.println("Thread " + key.getId() + ": " + key.getName()); + for (StackTraceElement element : map.get(key)) { + System.out.println(" " + element); + } + + } + } + + public static void main(String[] args) { + + final JavaConsole console = new JavaConsole(); + + boolean toShowConsole = false; + + for (int i = 0; i < args.length; i++) { + if (args[i] == "--show-console") { + toShowConsole = true; + } + } + + if (toShowConsole) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + console.showConsole(); + } + }); + } + + } + + /** + * This thread updates the text on a JTextArea based on the text in a file + */ + class TextAreaUpdater extends Thread { + + File fileToRead; + JTextArea outputTextArea; + + public TextAreaUpdater(File file, JTextArea textArea) { + fileToRead = file; + outputTextArea = textArea; + setDaemon(true); + } + + public void run() { + + try { + BufferedReader reader = new BufferedReader(new FileReader( + fileToRead)); + String line; + while (true) { + while ((line = reader.readLine()) != null) { + outputTextArea.insert(line + "\n", outputTextArea + .getDocument().getLength()); + outputTextArea.setCaretPosition(outputTextArea + .getText().length()); + } + Thread.sleep(1000); + } + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + Thread.currentThread().interrupt(); + } + + } + + } + +}
--- a/plugin/icedtea/sun/applet/PluginMain.java Tue Feb 24 14:53:39 2009 +0000 +++ b/plugin/icedtea/sun/applet/PluginMain.java Wed Feb 25 13:34:13 2009 -0500 @@ -84,6 +84,11 @@ */ 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"; + final boolean redirectStreams = System.getenv().containsKey("ICEDTEAPLUGIN_DEBUG"); static PluginStreamHandler streamHandler; @@ -111,18 +116,15 @@ public PluginMain(String inPipe, String outPipe) { - if (redirectStreams) { - try { - File errFile = new File("/tmp/java.stderr"); - File outFile = new File("/tmp/java.stdout"); + try { + File errFile = new File(PLUGIN_STDERR_FILE); + File outFile = new File(PLUGIN_STDOUT_FILE); - System.setErr(new PrintStream(new FileOutputStream(errFile))); - System.setOut(new PrintStream(new FileOutputStream(outFile))); - - } catch (Exception e) { - PluginDebug.debug("Unable to redirect streams"); - e.printStackTrace(); - } + 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); @@ -219,4 +221,63 @@ static String getMessage() { return streamHandler.getMessage(); } + + /** + * Behaves like the 'tee' command, sends output to both actual std stream and a + * file + */ + class TeeOutputStream extends PrintStream { + + // Everthing written to TeeOutputStream is written to this file + PrintStream logFile; + + public TeeOutputStream(FileOutputStream fileOutputStream, + PrintStream stdStream) { + super(stdStream); + logFile = new PrintStream(fileOutputStream); + } + + @Override + public boolean checkError() { + boolean thisError = super.checkError(); + boolean fileError = logFile.checkError(); + + return thisError || fileError; + } + + @Override + public void close() { + logFile.close(); + super.close(); + } + + @Override + public void flush() { + logFile.flush(); + super.flush(); + } + + /* + * The big ones: these do the actual writing + */ + + @Override + public void write(byte[] buf, int off, int len) { + logFile.write(buf, off, len); + super.write(buf, off, len); + } + + @Override + public void write(int b) { + logFile.write(b); + super.write(b); + } + + @Override + public void write(byte[] b) throws IOException { + logFile.write(b); + super.write(b); + } + } + }