aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Vanek <[email protected]>2013-12-15 11:07:05 +0100
committerJiri Vanek <[email protected]>2013-12-15 11:07:05 +0100
commitd91bf9ee53eebc7028f4143e03881ee350e4ebef (patch)
treed1886733f58835ff3a9ae5d51a5411139ae55ce5
parent3c5836190bd9954c56c7d4180bfc2e7ed9a0d82d (diff)
Console made aware of plugin messages
-rw-r--r--ChangeLog40
-rw-r--r--NEWS1
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/FileLog.java3
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/JavaConsole.java81
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/LogConfig.java11
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/OutputController.java115
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/headers/Header.java161
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/headers/JavaMessage.java63
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/headers/MessageWithHeader.java46
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/headers/PluginHeader.java82
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/headers/PluginMessage.java94
-rw-r--r--plugin/icedteanp/IcedTeaNPPlugin.cc153
-rw-r--r--plugin/icedteanp/IcedTeaNPPlugin.h9
-rw-r--r--plugin/icedteanp/IcedTeaPluginUtils.cc33
-rw-r--r--plugin/icedteanp/IcedTeaPluginUtils.h39
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginMain.java17
-rw-r--r--tests/netx/unit/net/sourceforge/jnlp/util/logging/JavaConsoleTest.java59
17 files changed, 916 insertions, 91 deletions
diff --git a/ChangeLog b/ChangeLog
index d57ec03..e16fdbd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2013-12-15 Jiri Vanek <[email protected]>
+
+ Console made aware of plugin messages
+ * NEWS : mentioned
+ * netx/net/sourceforge/jnlp/util/logging/FileLog.java: call to log adapted
+ to new Header.
+ * netx/net/sourceforge/jnlp/util/logging/JavaConsole.java: (logOutput) and
+ (logError) replaced by (addMessage). Added (createPluginReader) to process
+ plugin debug pipe
+ * netx/net/sourceforge/jnlp/util/logging/LogConfig.java: (getConfig) do
+ config available untill JNLPRuntime config is proper singleton
+ * netx/net/sourceforge/jnlp/util/logging/OutputController.java: (Level)
+ static methods converted to members and enhanced. (getHeader) and
+ (getCallerClass) moved to Headers.
+ * netx/net/sourceforge/jnlp/util/logging/headers/Header.java: Structure
+ to keep header as object instead of string.
+ * netx/net/sourceforge/jnlp/util/logging/headers/JavaMessage.java: Structure
+ to hold message and its header.
+ * netx/net/sourceforge/jnlp/util/logging/headers/MessageWithHeader.java:
+ Interface for JavaMessage and PluginMessage
+ * netx/net/sourceforge/jnlp/util/logging/headers/PluginHeader.java: extended
+ header to handle plugin's preinit and threads.
+ * netx/net/sourceforge/jnlp/util/logging/headers/PluginMessage.java:
+ implementation of MessageWithHeader which parse from String from plugin
+ debug pipe.
+ * plugin/icedteanp/IcedTeaNPPlugin.cc: added debug pipe (debug_pipe_name),
+ synced via (debug_pipe_lock), controlled by (debug_to_appletviewer) and used
+ by method (plugin_send_message_to_appletviewer_console).
+ * plugin/icedteanp/IcedTeaNPPlugin.h: (debug_pipe_name) and (jvvm_up) declared
+ extern. Utility methods (plugin_send_message_to_appletviewer_console) and
+ (flush_plugin_send_message_to_appletviewer_console) declared and impelmented
+ * plugin/icedteanp/IcedTeaPluginUtils.cc: print debug info enhanced for
+ debug pipe
+ * plugin/icedteanp/IcedTeaPluginUtils.h: (PLUGIN_MESSAGE) and (PLIGIN_ERROR)
+ now log to debug pipe if enabled.
+ * plugin/icedteanp/java/sun/applet/PluginMain.java: args reprinted, checked
+ third parameter debug pipe if should. Started debug_pipe reader if should
+ * tests/netx/unit/net/sourceforge/jnlp/util/logging/JavaConsoleTest.java:
+ added tests for parsing the plugin message.
+
2013-12-13 Jiri Vanek <[email protected]>
Made again compatible with JDK6.All JLists, JComboBoxs, and DefaultComboBoxModels
diff --git a/NEWS b/NEWS
index 46e5732..05688fe 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,7 @@ New in release 1.5 (2013-XX-XX):
- PR1026 - Apps fail to run because of the nanoxml parser's strict XML validation
- PR1473 - javaws should not depend on name of local file
- Redesigned About dialogue layout and contents
+ - Console made aware of plugin messages
* Plugin
- PR854: Resizing an applet several times causes 100% CPU load
- PR1271: icedtea-web does not handle 'javascript:'-protocol URLs
diff --git a/netx/net/sourceforge/jnlp/util/logging/FileLog.java b/netx/net/sourceforge/jnlp/util/logging/FileLog.java
index 3ac048b..962e4ab 100644
--- a/netx/net/sourceforge/jnlp/util/logging/FileLog.java
+++ b/netx/net/sourceforge/jnlp/util/logging/FileLog.java
@@ -46,6 +46,7 @@ import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import net.sourceforge.jnlp.util.FileUtils;
+import net.sourceforge.jnlp.util.logging.headers.Header;
/**
* This class writes log information to file.
@@ -90,7 +91,7 @@ public final class FileLog implements SingleStreamLogger {
impl = Logger.getLogger(loggerName);
impl.setLevel(Level.ALL);
impl.addHandler(fh);
- log(OutputController.getHeader(null, null));
+ log(new Header(OutputController.Level.WARNING_ALL, Thread.currentThread().getStackTrace(), Thread.currentThread(), false).toString());
} catch (IOException e) {
throw new RuntimeException(e);
}
diff --git a/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java b/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java
index 52bc1aa..2ee601e 100644
--- a/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java
+++ b/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java
@@ -46,6 +46,11 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -63,6 +68,10 @@ import javax.swing.border.TitledBorder;
import net.sourceforge.jnlp.config.DeploymentConfiguration;
import net.sourceforge.jnlp.runtime.JNLPRuntime;
import net.sourceforge.jnlp.util.ImageResources;
+import net.sourceforge.jnlp.util.logging.headers.Header;
+import net.sourceforge.jnlp.util.logging.headers.JavaMessage;
+import net.sourceforge.jnlp.util.logging.headers.MessageWithHeader;
+import net.sourceforge.jnlp.util.logging.headers.PluginMessage;
/**
* A simple Java console for IcedTeaPlugin and JavaWS
@@ -392,7 +401,7 @@ public class JavaConsole {
final JavaConsole console = new JavaConsole();
- boolean toShowConsole = false;
+ boolean toShowConsole = true;
for (String arg : args) {
if ("--show-console".equals(arg)) {
@@ -406,11 +415,73 @@ public class JavaConsole {
}
- void logOutput(String s) {
- stdOutText.setText(stdOutText.getText() + s + "\n");
+
+ void addMessage(Header header, String message) {
+ if (!LogConfig.getLogConfig().isEnableHeaders()){
+ if (header.level.isError()){
+ stdErrText.setText(stdErrText.getText() + message + "\n");
+ }
+ if (header.level.isOutput()){
+ stdOutText.setText(stdOutText.getText() + message + "\n");
+ }
+ } else {
+ if (header.level.isError()){
+ stdErrText.setText(stdErrText.getText( )+ header.toString() + message +"\n");
+ }
+ if (header.level.isOutput()){
+ stdOutText.setText(stdOutText.getText() + header.toString() + message + "\n");
+ }
+ }
+ }
+
+ /**
+ * parse plugin message and add it as header+message to data
+ * @param s string to be parsed
+ */
+ private void processPluginMessage(String s) {
+ PluginMessage pm = new PluginMessage(s);
+ addMessage(pm.getHeader(), pm.getMessage());
}
- void logError(String s) {
- stdErrText.setText(stdErrText.getText() + s + "\n");
+
+ public void createPluginReader(final File file) {
+ OutputController.getLogger().log("Starting processing of plugin-debug-to-console " + file.getAbsolutePath());
+ Thread t = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new InputStreamReader(new FileInputStream(file),
+ Charset.forName("UTF-8")));
+ //never ending loop
+ while (true) {
+ try{
+ String s = br.readLine();
+ if (s == null) {
+ break;
+ }
+ processPluginMessage(s);
+ }catch(Exception ex){
+ OutputController.getLogger().log(ex);
+ }
+ }
+ } catch (Exception ex) {
+ OutputController.getLogger().log(ex);
+ if (br != null) {
+ try {
+ br.close();
+ } catch (Exception exx) {
+ OutputController.getLogger().log(exx);
+ }
+ }
+ }
+ OutputController.getLogger().log("Ended processing of plugin-debug-to-console " + file.getAbsolutePath());
+ }
+ }, "plugin-debug-to-console reader thread");
+ t.setDaemon(true);
+ t.start();
+
+ OutputController.getLogger().log("Started processing of plugin-debug-to-console " + file.getAbsolutePath());
}
}
diff --git a/netx/net/sourceforge/jnlp/util/logging/LogConfig.java b/netx/net/sourceforge/jnlp/util/logging/LogConfig.java
index 2c98cd2..72941f3 100644
--- a/netx/net/sourceforge/jnlp/util/logging/LogConfig.java
+++ b/netx/net/sourceforge/jnlp/util/logging/LogConfig.java
@@ -55,12 +55,13 @@ public class LogConfig {
private boolean logToFile;
private boolean logToStreams;
private boolean logToSysLog;
+ private DeploymentConfiguration config;
private static LogConfig logConfig;
public LogConfig() {
try {
- DeploymentConfiguration config = JNLPRuntime.getConfiguration();
+ config = JNLPRuntime.getConfiguration();
if (config.getRaw().isEmpty()){
config = new DeploymentConfiguration();//JNLPRuntime.getConfiguration() cannotbe loaded time
config.load(); //read one prior
@@ -161,7 +162,11 @@ public class LogConfig {
return JavaConsole.isEnabled();
}
-
-
+ /*
+ * logging stuff may be interested in used config
+ */
+ public DeploymentConfiguration getConfig() {
+ return config;
+ }
}
diff --git a/netx/net/sourceforge/jnlp/util/logging/OutputController.java b/netx/net/sourceforge/jnlp/util/logging/OutputController.java
index 6a6dcd6..d84950a 100644
--- a/netx/net/sourceforge/jnlp/util/logging/OutputController.java
+++ b/netx/net/sourceforge/jnlp/util/logging/OutputController.java
@@ -54,20 +54,37 @@ public class OutputController {
ERROR_ALL, // - stderr/log in all cases (default for
ERROR_DEBUG; // - stderr/log in verbose/debug mode
//ERROR_DEBUG is default for Throwable
- //MESSAGE_VERBOSE is defautrl for String
+ //MESSAGE_DEBUG is default for String
- private static boolean isOutput(MessageWithLevel s) {
- return s.level == Level.MESSAGE_ALL
- || s.level == Level.MESSAGE_DEBUG
- || s.level == Level.WARNING_ALL
- || s.level == Level.WARNING_DEBUG;
+ public boolean isOutput() {
+ return this == Level.MESSAGE_ALL
+ || this == Level.MESSAGE_DEBUG
+ || this == Level.WARNING_ALL
+ || this == Level.WARNING_DEBUG;
}
- private static boolean isError(MessageWithLevel s) {
- return s.level == Level.ERROR_ALL
- || s.level == Level.ERROR_DEBUG
- || s.level == Level.WARNING_ALL
- || s.level == Level.WARNING_DEBUG;
+ public boolean isError() {
+ return this == Level.ERROR_ALL
+ || this == Level.ERROR_DEBUG
+ || this == Level.WARNING_ALL
+ || this == Level.WARNING_DEBUG;
+ }
+
+ public boolean isWarning() {
+ return this == Level.WARNING_ALL
+ || this == Level.WARNING_DEBUG;
+ }
+
+ public boolean isDebug() {
+ return this == Level.ERROR_DEBUG
+ || this == Level.MESSAGE_DEBUG
+ || this == Level.WARNING_DEBUG;
+ }
+
+ public boolean isInfo() {
+ return this == Level.ERROR_ALL
+ || this == Level.WARNING_ALL
+ || this == Level.MESSAGE_ALL;
}
}
@@ -76,6 +93,8 @@ public class OutputController {
public final String message;
public final Level level;
public final StackTraceElement[] stack = Thread.currentThread().getStackTrace();
+ public final Thread thread = Thread.currentThread();
+ public final Date loggedAt = new Date();
public MessageWithLevel(String message, Level level) {
this.message = message;
@@ -132,6 +151,11 @@ public class OutputController {
private void consume() {
MessageWithLevel s = messageQue.get(0);
messageQue.remove(0);
+ net.sourceforge.jnlp.util.logging.headers.Header header = new net.sourceforge.jnlp.util.logging.headers.Header(s.level, s.stack, s.thread, s.loggedAt, false);
+ //filtering is done in console during runtime
+ if (LogConfig.getLogConfig().isLogToConsole()) {
+ JavaConsole.getConsole().addMessage(header, s.message);
+ }
if (!JNLPRuntime.isDebug() && (s.level == Level.MESSAGE_DEBUG
|| s.level == Level.WARNING_DEBUG
|| s.level == Level.ERROR_DEBUG)) {
@@ -142,16 +166,16 @@ public class OutputController {
String message = s.message;
if (LogConfig.getLogConfig().isEnableHeaders()) {
if (message.contains("\n")) {
- message = getHeader(s.level, s.stack) + "\n" + message;
+ message = header.toString() + "\n" + message;
} else {
- message = getHeader(s.level, s.stack) + " " + message;
+ message = header.toString() + " " + message;
}
}
if (LogConfig.getLogConfig().isLogToStreams()) {
- if (Level.isOutput(s)) {
+ if (s.level.isOutput()) {
outLog.log(message);
}
- if (Level.isError(s)) {
+ if (s.level.isError()) {
errLog.log(message);
}
}
@@ -161,14 +185,6 @@ public class OutputController {
if (LogConfig.getLogConfig().isLogToSysLog()) {
getSystemLog().log(message);
}
- if (LogConfig.getLogConfig().isLogToConsole()) {
- if (Level.isOutput(s)){
- JavaConsole.getConsole().logOutput(message);
- }
- if (Level.isError(s)){
- JavaConsole.getConsole().logError(message);
- }
- }
}
@@ -344,59 +360,6 @@ public class OutputController {
printOut(e);
printError(e);
}
-
- public static String getHeader(Level level, StackTraceElement[] stack) {
- StringBuilder sb = new StringBuilder();
- try {
- String user = System.getProperty("user.name");
- sb.append("[").append(user).append("]");
- if (JNLPRuntime.isWebstartApplication()) {
- sb.append("[ITW-JAVAWS]");
- } else {
- sb.append("[ITW]");
- }
- if (level != null) {
- sb.append('[').append(level.toString()).append(']');
- }
- sb.append('[').append(new Date().toString()).append(']');
- if (stack != null) {
- sb.append('[').append(getCallerClass(stack)).append(']');
- }
- sb.append(" NETX Thread# ")
- .append(Integer.toHexString(((Object)Thread.currentThread()).hashCode()))
- .append(", name ")
- .append(Thread.currentThread().getName());
- } catch (Exception ex) {
- getLogger().log(ex);
- }
- return sb.toString();
-
- }
-
- static String getCallerClass(StackTraceElement[] stack) {
- try {
- //0 is always thread
- //1..? is OutputController itself
- //pick up first after.
- StackTraceElement result = stack[0];
- int i = 1;
- for (; i < stack.length; i++) {
- result = stack[i];//at least moving up
- if (stack[i].getClassName().contains(OutputController.class.getName()) ||
- //PluginDebug.class.getName() not avaiable during netx make
- stack[i].getClassName().contains("sun.applet.PluginDebug") ) {
- continue;
- } else {
- break;
- }
- }
- return result.toString();
- } catch (Exception ex) {
- getLogger().log(ex);
- return "Unknown caller";
- }
- }
-
//package private setters for testing
diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/Header.java b/netx/net/sourceforge/jnlp/util/logging/headers/Header.java
new file mode 100644
index 0000000..a87a14f
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/util/logging/headers/Header.java
@@ -0,0 +1,161 @@
+/*
+Copyright (C) 2009, 2013 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 net.sourceforge.jnlp.util.logging.headers;
+
+import java.util.Date;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.util.logging.OutputController;
+import net.sourceforge.jnlp.util.logging.OutputController.Level;
+
+public class Header {
+
+ public String user;
+ public boolean application;
+ public Level level;
+ public Date date = new Date();
+ public boolean isC;//false=> java
+ public String caller;
+ public String thread1;
+ public String thread2;
+
+ //to alow simple inheritance
+ public Header() {
+ }
+
+ public Header(Level level, StackTraceElement[] stack, Thread thread, boolean isC) {
+ this(level, stack, thread, new Date(), isC);
+ }
+
+ public Header(Level level, StackTraceElement[] stack, Thread thread, Date d, boolean isC) {
+ this.user = System.getProperty("user.name");
+ this.application = JNLPRuntime.isWebstartApplication();
+ this.level = level;
+ this.date = d;
+ this.isC = isC;
+ if (stack != null) {
+ this.caller = getCallerClass(stack);
+ }
+ this.thread1 = Integer.toHexString(((Object) thread).hashCode());
+ this.thread2 = thread.getName();
+ }
+
+ @Override
+ public String toString() {
+ return toString(true, true, true, true, true, true, true);
+ }
+
+ public String toString(boolean userb, boolean originb, boolean levelb, boolean dateb, boolean callerb, boolean thread1b, boolean thread2b) {
+ StringBuilder sb = new StringBuilder();
+ try {
+ if (userb){
+ sb.append("[").append(user).append("]");
+ }
+ if(originb){
+ sb.append("[").append(getOrigin()).append("]");
+ }
+
+ if (levelb && level != null) {
+ sb.append('[').append(level.toString()).append(']');
+ }
+ if (dateb){
+ sb.append('[').append(date.toString()).append(']');
+ }
+ if (callerb && caller != null) {
+ sb.append('[').append(caller).append(']');
+ }
+ if (thread1b && thread2b){
+ sb.append(threadsToString());
+ }else if (thread1b) {
+ sb.append(thread1ToString());
+ }else if (thread2b) {
+ sb.append(thread2ToString());
+ }
+ } catch (Exception ex) {
+ OutputController.getLogger().log(ex);
+ }
+ return sb.toString();
+ }
+
+ public String thread1ToString() {
+ return " NETX Thread# " + thread1;
+ }
+
+ public String thread2ToString() {
+ return "name " + thread2;
+ }
+
+ public String threadsToString() {
+ return thread1ToString()
+ + ", " + thread2ToString();
+ }
+
+ public String getOrigin() {
+ if (application) {
+ return "ITW-JAVAWS";
+ } else {
+ if (isC) {
+ return "ITW-C-PLUGIN";
+ } else {
+ return "ITW-APPLET";
+ }
+ }
+ }
+
+ static String getCallerClass(StackTraceElement[] stack) {
+ try {
+ //0 is always thread
+ //1..? is OutputController itself
+ //pick up first after.
+ StackTraceElement result = stack[0];
+ int i = 1;
+ for (; i < stack.length; i++) {
+ result = stack[i];//at least moving up
+ if (stack[i].getClassName().contains(OutputController.class.getName())
+ || //PluginDebug.class.getName() not avaiable during netx make
+ stack[i].getClassName().contains("sun.applet.PluginDebug")) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ return result.toString();
+ } catch (Exception ex) {
+ OutputController.getLogger().log(ex);
+ return "Unknown caller";
+ }
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/JavaMessage.java b/netx/net/sourceforge/jnlp/util/logging/headers/JavaMessage.java
new file mode 100644
index 0000000..6994f9e
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/util/logging/headers/JavaMessage.java
@@ -0,0 +1,63 @@
+/*
+Copyright (C) 2009, 2013 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 net.sourceforge.jnlp.util.logging.headers;
+
+
+
+public class JavaMessage implements MessageWithHeader{
+
+ public Header header;
+ public String message;
+
+ public JavaMessage(Header header, String message) {
+ this.header = header;
+ this.message = message;
+ }
+
+
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+ @Override
+ public Header getHeader() {
+ return header;
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/MessageWithHeader.java b/netx/net/sourceforge/jnlp/util/logging/headers/MessageWithHeader.java
new file mode 100644
index 0000000..5af997b
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/util/logging/headers/MessageWithHeader.java
@@ -0,0 +1,46 @@
+/*
+Copyright (C) 2009, 2013 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 net.sourceforge.jnlp.util.logging.headers;
+
+
+public interface MessageWithHeader {
+
+ String getMessage();
+ Header getHeader();
+
+}
diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/PluginHeader.java b/netx/net/sourceforge/jnlp/util/logging/headers/PluginHeader.java
new file mode 100644
index 0000000..31ed19d
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/util/logging/headers/PluginHeader.java
@@ -0,0 +1,82 @@
+/*
+Copyright (C) 2009, 2013 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 net.sourceforge.jnlp.util.logging.headers;
+
+import java.util.Date;
+import java.util.regex.Pattern;
+
+public class PluginHeader extends Header {
+
+ public boolean preinit;
+ public Date originalTimeStamp;
+ static final String PLUGIN_DEBUG = "plugindebug ";
+ static final String PLUGIN_DEBUG_PREINIT = "preinit_plugindebug ";
+ static final String PLUGIN_ERROR = "pluginerror ";
+ static final String PLUGIN_ERROR_PREINIT = "preinit_pluginerror ";
+ static final Pattern bracketsPattern = Pattern.compile("(\\]\\s*\\[)|(\\s*\\[)|(\\]\\s*)");
+ static final Pattern whiteSpaces = Pattern.compile("\\s+");
+ static final Pattern threadsPattern = Pattern.compile("\\s+|,\\s*|:");
+
+ @Override
+ public String toString() {
+ if (preinit) {
+ return "!" + super.toString();
+ } else {
+ return super.toString();
+ }
+ }
+
+ @Override
+ public String toString(boolean userb, boolean originb, boolean levelb, boolean dateb, boolean callerb, boolean thread1b, boolean thread2b) {
+ if (preinit) {
+ return "!" + super.toString(userb, originb, levelb, dateb, callerb, thread1b, thread2b);
+ } else {
+ return super.toString(userb, originb, levelb, dateb, callerb, thread1b, thread2b);
+ }
+ }
+
+ @Override
+ public String thread1ToString() {
+ return " ITNPP Thread# " + thread1;
+ }
+
+ @Override
+ public String thread2ToString() {
+ return "gthread " + thread2;
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/PluginMessage.java b/netx/net/sourceforge/jnlp/util/logging/headers/PluginMessage.java
new file mode 100644
index 0000000..098d258
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/util/logging/headers/PluginMessage.java
@@ -0,0 +1,94 @@
+/*
+Copyright (C) 2009, 2013 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 net.sourceforge.jnlp.util.logging.headers;
+
+import java.util.Date;
+import net.sourceforge.jnlp.util.logging.FileLog;
+import net.sourceforge.jnlp.util.logging.OutputController;
+
+public class PluginMessage implements MessageWithHeader{
+
+ public PluginHeader header;
+ public String restOfMessage;
+ public boolean wasError = false;
+
+ public PluginMessage(String orig) {
+ restOfMessage = orig;
+ header = new PluginHeader();
+ String s = orig.trim();
+ PluginHeader p = this.header;
+ try {
+ p.isC = true;
+ p.application = false;
+ if (s.startsWith("preinit_plugin")) {
+ p.preinit = true;
+ }
+ if (s.startsWith(PluginHeader.PLUGIN_DEBUG) || s.startsWith(PluginHeader.PLUGIN_DEBUG_PREINIT)) {
+ p.level = OutputController.Level.MESSAGE_DEBUG;
+ } else if (s.startsWith(PluginHeader.PLUGIN_ERROR) || s.startsWith(PluginHeader.PLUGIN_ERROR_PREINIT)) {
+ p.level = OutputController.Level.ERROR_ALL;
+ } else {
+ p.level = OutputController.Level.WARNING_ALL;
+ }
+ String[] init = PluginHeader.whiteSpaces.split(s);
+ p.originalTimeStamp = new Date(Long.parseLong(init[1]) / 1000);
+ String[] main = PluginHeader.bracketsPattern.split(s);
+ p.user = main[1];
+ p.caller = main[5];
+ p.date = FileLog.getPluginSharedFormatter().parse(main[4]);
+ String[] threads = PluginHeader.threadsPattern.split(main[6]);
+ p.thread1 = threads[2];
+ p.thread2 = threads[4];
+ int i = orig.indexOf(p.thread2);
+ restOfMessage = orig.substring(i + p.thread2.length() + 2); //+": "
+ } catch (Exception ex) {
+ OutputController.getLogger().log(ex);
+ this.wasError = true;
+ }
+ }
+
+ @Override
+ public String getMessage() {
+ return restOfMessage;
+ }
+
+ @Override
+ public Header getHeader() {
+ return header;
+ }
+}
diff --git a/plugin/icedteanp/IcedTeaNPPlugin.cc b/plugin/icedteanp/IcedTeaNPPlugin.cc
index 9a0d0c4..1317831 100644
--- a/plugin/icedteanp/IcedTeaNPPlugin.cc
+++ b/plugin/icedteanp/IcedTeaNPPlugin.cc
@@ -138,6 +138,9 @@ gint in_watch_source;
// Applet viewer output pipe name.
gchar* out_pipe_name;
+// Applet viewer debug pipe name.
+gchar* debug_pipe_name = NULL;
+
// Applet viewer output watch source.
gint out_watch_source;
@@ -147,9 +150,15 @@ pthread_t itnp_plugin_thread_id;
// Mutex to lock async call queue
pthread_mutex_t pluginAsyncCallMutex;
+/*to sync pipe to apletviewer console*/
+pthread_mutex_t debug_pipe_lock = PTHREAD_MUTEX_INITIALIZER;
+
// Applet viewer output channel.
GIOChannel* out_to_appletviewer;
+// Applet viewer debug channel.
+GIOChannel* debug_to_appletviewer = NULL;
+
// Tracks jvm status
gboolean jvm_up = FALSE;
@@ -488,6 +497,34 @@ void start_jvm_if_needed()
}
PLUGIN_DEBUG ("ITNP_New: created output fifo: %s\n", out_pipe_name);
+ // Create plugin-debug-to-appletviewer pipe which we refer to as the
+ // debug pipe.
+ initialize_debug();//should be already initialized, but...
+ if (plugin_debug_to_console){
+ // debug_pipe_name
+ debug_pipe_name = g_strdup_printf ("%s/%d-icedteanp-plugin-debug-to-appletviewer",
+ data_directory.c_str(), getpid());
+
+ if (!debug_pipe_name)
+ {
+ PLUGIN_ERROR ("Failed to create debug pipe name.\n");
+ np_error = NPERR_OUT_OF_MEMORY_ERROR;
+ goto cleanup_debug_pipe_name;
+ }
+
+ // clean up any older pip
+ unlink (debug_pipe_name);
+
+ PLUGIN_DEBUG ("ITNP_New: creating debug fifo: %s\n", debug_pipe_name);
+ if (mkfifo (debug_pipe_name, 0600) == -1 && errno != EEXIST)
+ {
+ PLUGIN_ERROR ("Failed to create debug pipe\n", strerror (errno));
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_debug_pipe_name;
+ }
+ PLUGIN_DEBUG ("ITNP_New: created debug fifo: %s\n", debug_pipe_name);
+ }
+
// Start a separate appletviewer process for each applet, even if
// there are multiple applets in the same page. We may need to
// change this behaviour if we find pages with multiple applets that
@@ -548,12 +585,46 @@ void start_jvm_if_needed()
g_io_add_watch (in_from_appletviewer,
(GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_HUP),
plugin_in_pipe_callback, (gpointer) in_from_appletviewer);
+
+ // Create plugin-to-appletviewer console debug channel. The default encoding for
+ // the file is UTF-8.
+ // debug_to_appletviewer
+ if (plugin_debug_to_console){
+ debug_to_appletviewer = g_io_channel_new_file (debug_pipe_name,
+ "w", &channel_error);
+ if (!debug_to_appletviewer)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR ("Failed to debug output channel, '%s'\n",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to create debug channel\n");
+
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_debug_to_appletviewer;
+ }
+ }
jvm_up = TRUE;
-
+
+ if (plugin_debug_to_console){
+ //jvm is up, we can start console producer thread
+ pthread_t debug_to_console_consumer;
+ pthread_create(&debug_to_console_consumer,NULL,&flush_pre_init_messages,NULL);
+ }
goto done;
// Free allocated data in case of error
+ cleanup_debug_to_appletviewer:
+ if (plugin_debug_to_console){
+ if (debug_to_appletviewer)
+ g_io_channel_unref (debug_to_appletviewer);
+ debug_to_appletviewer = NULL;
+ }
cleanup_in_watch_source:
// Removing a source is harmless if it fails since it just means the
@@ -575,6 +646,21 @@ void start_jvm_if_needed()
g_io_channel_unref (out_to_appletviewer);
out_to_appletviewer = NULL;
+ if (plugin_debug_to_console){
+ // cleanup_debug_pipe:
+ // Delete output pipe.
+ PLUGIN_DEBUG ("ITNP_New: deleting debug fifo: %s\n", debug_pipe_name);
+ unlink (debug_pipe_name);
+ PLUGIN_DEBUG ("ITNP_New: deleted debug fifo: %s\n", debug_pipe_name);
+ }
+ cleanup_debug_pipe_name:
+ if (plugin_debug_to_console){
+ g_free (debug_pipe_name);
+ debug_pipe_name = NULL;
+ }
+
+
+
// cleanup_out_pipe:
// Delete output pipe.
PLUGIN_DEBUG ("ITNP_New: deleting input fifo: %s\n", in_pipe_name);
@@ -1401,6 +1487,9 @@ plugin_start_appletviewer (ITNPPluginData* data)
command_line.push_back("sun.applet.PluginMain");
command_line.push_back(out_pipe_name);
command_line.push_back(in_pipe_name);
+ if (plugin_debug_to_console){
+ command_line.push_back(debug_pipe_name);
+ }
// Finished command line parameters
@@ -1576,6 +1665,38 @@ plugin_send_message_to_appletviewer (gchar const* message)
PLUGIN_DEBUG ("plugin_send_message_to_appletviewer return\n");
}
+// unlike like plugin_send_message_to_appletviewer
+// do not debug
+// do not error
+// do not have its own line end
+// is accesed by only one thread
+// have own pipe
+// jvm must be up
+void
+plugin_send_message_to_appletviewer_console (gchar const* newline_message)
+{
+ gsize bytes_written = 0;
+ if (g_io_channel_write_chars (debug_to_appletviewer,
+ newline_message, -1, &bytes_written,
+ &channel_error) != G_IO_STATUS_NORMAL) {
+ if (channel_error) {
+ //error must be freed
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ }
+}
+//flush only when its full
+void flush_plugin_send_message_to_appletviewer_console (){
+ if (g_io_channel_flush (debug_to_appletviewer, &channel_error)
+ != G_IO_STATUS_NORMAL) {
+ if (channel_error) {
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ }
+}
+
/*
* Sends the initialization message (handle/size/url) to the plugin
*/
@@ -2046,6 +2167,36 @@ NP_Shutdown (void)
g_free (in_pipe_name);
in_pipe_name = NULL;
+ if (plugin_debug_to_console){
+ //jvm_up is now false
+ if (g_io_channel_shutdown (debug_to_appletviewer,
+ TRUE, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR ("Failed to shut down appletviewer"
+ " debug channel\n", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to shut down debug to appletviewer\n");
+ }
+ // cleanup_out_to_appletviewer:
+ if (debug_to_appletviewer)
+ g_io_channel_unref (debug_to_appletviewer);
+ out_to_appletviewer = NULL;
+ // cleanup_debug_pipe:
+ // Delete debug pipe.
+ PLUGIN_DEBUG ("NP_Shutdown: deleting debug fifo: %s\n", debug_pipe_name);
+ unlink (debug_pipe_name);
+ PLUGIN_DEBUG ("NP_Shutdown: deleted debug fifo: %s\n", debug_pipe_name);
+ // cleanup_out_pipe_name:
+ g_free (debug_pipe_name);
+ debug_pipe_name = NULL;
+ }
+
// Destroy the call queue mutex
pthread_mutex_destroy(&pluginAsyncCallMutex);
diff --git a/plugin/icedteanp/IcedTeaNPPlugin.h b/plugin/icedteanp/IcedTeaNPPlugin.h
index 6e1465b..3e66599 100644
--- a/plugin/icedteanp/IcedTeaNPPlugin.h
+++ b/plugin/icedteanp/IcedTeaNPPlugin.h
@@ -115,6 +115,9 @@ extern pthread_t itnp_plugin_thread_id;
/* Mutex around plugin async call queue ops */
extern pthread_mutex_t pluginAsyncCallMutex;
+/*to sync pipe to apletviewer console*/
+extern pthread_mutex_t debug_pipe_lock;
+
// debug switches
extern bool debug_initiated;
extern int plugin_debug;
@@ -125,6 +128,9 @@ extern bool plugin_debug_to_system;
extern bool plugin_debug_to_console;
extern FILE * plugin_file_log;
extern std::string plugin_file_log_name;
+extern gchar* debug_pipe_name;
+
+extern gboolean jvm_up;
// Browser function table.
extern NPNetscapeFuncs browser_functions;
@@ -152,6 +158,9 @@ int get_id_from_instance(NPP instance);
/* Sends a message to the appletviewer */
void plugin_send_message_to_appletviewer(gchar const* message);
+/*this method is not logging, do not add \n and is using different pipe*/
+void plugin_send_message_to_appletviewer_console(gchar const* message);
+void flush_plugin_send_message_to_appletviewer_console();
/* Returns an appropriate (package/object) scriptable npobject */
NPObject* get_scriptable_object(NPP instance);
diff --git a/plugin/icedteanp/IcedTeaPluginUtils.cc b/plugin/icedteanp/IcedTeaPluginUtils.cc
index 0986aa8..5cd4231 100644
--- a/plugin/icedteanp/IcedTeaPluginUtils.cc
+++ b/plugin/icedteanp/IcedTeaPluginUtils.cc
@@ -54,10 +54,37 @@ int IcedTeaPluginUtilities::reference = -1;
pthread_mutex_t IcedTeaPluginUtilities::reference_mutex = PTHREAD_MUTEX_INITIALIZER;
std::map<void*, NPP>* IcedTeaPluginUtilities::instance_map = new std::map<void*, NPP>();
std::map<std::string, NPObject*>* IcedTeaPluginUtilities::object_map = new std::map<std::string, NPObject*>();
+std::queue<std::string> pre_jvm_message;
/* Plugin async call queue */
static std::vector< PluginThreadCall* >* pendingPluginThreadRequests = new std::vector< PluginThreadCall* >();
+void *flush_pre_init_messages(void* data) {
+while (true){
+ struct timespec ts;
+ ts.tv_sec = 1;
+ ts.tv_nsec = 0;
+ nanosleep(&ts ,0);
+ if (jvm_up) {
+ while (!pre_jvm_message.empty()) {
+ pthread_mutex_lock(&debug_pipe_lock);
+ std::string message = pre_jvm_message.front();
+ pre_jvm_message.pop();
+ pthread_mutex_unlock(&debug_pipe_lock);
+ plugin_send_message_to_appletviewer_console(message.c_str());
+
+ }
+ flush_plugin_send_message_to_appletviewer_console();
+ }
+
+}
+}
+void push_pre_init_messages(char * ldm){
+ pthread_mutex_lock(&debug_pipe_lock);
+ pre_jvm_message.push(std::string(ldm));
+ pthread_mutex_unlock(&debug_pipe_lock);
+}
+
/**
* Given a context number, constructs a message prefix to send to Java
*
@@ -1161,7 +1188,11 @@ void IcedTeaPluginUtilities::printDebugStatus(){
PLUGIN_DEBUG("plugin_debug_to_system: false\n");
}
if (plugin_debug_to_console){
- PLUGIN_DEBUG("plugin_debug_to_console: true\n");
+ if (debug_pipe_name){
+ PLUGIN_DEBUG("plugin_debug_to_console: true, pipe %s\n", debug_pipe_name);
+ } else {
+ PLUGIN_DEBUG("plugin_debug_to_console: true, pipe not yet known or broken\n");
+ }
} else {
PLUGIN_DEBUG("plugin_debug_to_console: false\n");
}
diff --git a/plugin/icedteanp/IcedTeaPluginUtils.h b/plugin/icedteanp/IcedTeaPluginUtils.h
index f0f52d7..6967793 100644
--- a/plugin/icedteanp/IcedTeaPluginUtils.h
+++ b/plugin/icedteanp/IcedTeaPluginUtils.h
@@ -58,6 +58,7 @@ exception statement from your version. */
#include <sstream>
#include <string>
#include <vector>
+#include <queue>
#include <npapi.h>
#include <glib.h>
@@ -65,6 +66,9 @@ exception statement from your version. */
#include "IcedTeaParseProperties.h"
+void *flush_pre_init_messages(void* data);
+void push_pre_init_messages(char * ldm);
+
// debugging macro.
#define initialize_debug() \
do \
@@ -81,7 +85,7 @@ exception statement from your version. */
IcedTeaPluginUtilities::initFileLog(); \
} \
if (plugin_debug_to_console) { \
- /*no op now*/ \
+ /*initialisation done during jvm startup*/ \
} \
IcedTeaPluginUtilities::printDebugStatus(); \
} \
@@ -91,6 +95,7 @@ exception statement from your version. */
#define HEADER_SIZE 500
#define BODY_SIZE 500
#define MESSAGE_SIZE HEADER_SIZE + BODY_SIZE
+#define LDEBUG_MESSAGE_SIZE MESSAGE_SIZE+50
//header is destination char array
#define CREATE_HEADER(ldebug_header) \
@@ -132,7 +137,21 @@ exception statement from your version. */
fflush(plugin_file_log); \
} \
if (plugin_debug_to_console) { \
- /*no op now*/ \
+ /*headers are always going to console*/ \
+ if (!plugin_debug_headers){ \
+ CREATE_HEADER(ldebug_header); \
+ } \
+ snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \
+ char ldebug_channel_message[LDEBUG_MESSAGE_SIZE]; \
+ struct timeval current_time; \
+ gettimeofday (&current_time, NULL);\
+ if (jvm_up) { \
+ snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "plugindebug", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \
+ push_pre_init_messages(ldebug_channel_message); \
+ } else { \
+ snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "preinit_plugindebug", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \
+ push_pre_init_messages(ldebug_channel_message); \
+ } \
} \
} \
} while (0)
@@ -161,7 +180,21 @@ exception statement from your version. */
fflush(plugin_file_log); \
} \
if (plugin_debug_to_console) { \
- /*no op now*/ \
+ /*headers are always going to console*/ \
+ if (!plugin_debug_headers){ \
+ CREATE_HEADER(ldebug_header); \
+ } \
+ snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \
+ char ldebug_channel_message[LDEBUG_MESSAGE_SIZE]; \
+ struct timeval current_time; \
+ gettimeofday (&current_time, NULL);\
+ if (jvm_up) { \
+ snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "pluginerror", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \
+ push_pre_init_messages(ldebug_channel_message); \
+ } else { \
+ snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "preinit_pluginerror", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \
+ push_pre_init_messages(ldebug_channel_message); \
+ } \
} \
} while (0)
diff --git a/plugin/icedteanp/java/sun/applet/PluginMain.java b/plugin/icedteanp/java/sun/applet/PluginMain.java
index e6ba080..421edb5 100644
--- a/plugin/icedteanp/java/sun/applet/PluginMain.java
+++ b/plugin/icedteanp/java/sun/applet/PluginMain.java
@@ -84,6 +84,7 @@ import net.sourceforge.jnlp.config.DeploymentConfiguration;
import net.sourceforge.jnlp.runtime.JNLPRuntime;
import net.sourceforge.jnlp.security.JNLPAuthenticator;
import net.sourceforge.jnlp.util.logging.JavaConsole;
+import net.sourceforge.jnlp.util.logging.LogConfig;
import net.sourceforge.jnlp.util.logging.OutputController;
/**
@@ -119,16 +120,30 @@ public class PluginMain {
*/
public static void main(String args[])
throws IOException {
+ //we are polite, we reprint start arguments
+ OutputController.getLogger().log("startup arguments: ");
+ for (int i = 0; i < args.length; i++) {
+ String string = args[i];
+ OutputController.getLogger().log(i + ": "+string);
+
+ }
if (AppContext.getAppContext() == null) {
SunToolkit.createNewAppContext();
}
installDummyJavascriptProtocolHandler();
- if (args.length != 2 || !(new File(args[0]).exists()) || !(new File(args[1]).exists())) {
+ if (args.length < 2 || !(new File(args[0]).exists()) || !(new File(args[1]).exists())) {
OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Invalid pipe names provided. Refusing to proceed.");
JNLPRuntime.exit(1);
}
DeploymentConfiguration.move14AndOlderFilesTo15StructureCatched();
+ if (JavaConsole.isEnabled()) {
+ if ((args.length < 3) || !new File(args[2]).exists()) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Warning, although console is on, plugin debug connection do not exists. No plugin information will be displayed in console (only java ones).");
+ } else {
+ JavaConsole.getConsole().createPluginReader(new File(args[2]));
+ }
+ }
try {
PluginStreamHandler streamHandler = connect(args[0], args[1]);
diff --git a/tests/netx/unit/net/sourceforge/jnlp/util/logging/JavaConsoleTest.java b/tests/netx/unit/net/sourceforge/jnlp/util/logging/JavaConsoleTest.java
new file mode 100644
index 0000000..8b36bac
--- /dev/null
+++ b/tests/netx/unit/net/sourceforge/jnlp/util/logging/JavaConsoleTest.java
@@ -0,0 +1,59 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package net.sourceforge.jnlp.util.logging;
+
+import net.sourceforge.jnlp.util.logging.headers.PluginMessage;
+import java.util.Date;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class JavaConsoleTest {
+
+
+ String s1 = "plugindebug 1384850630162925 [jvanek][ITW-C-PLUGIN][MESSAGE_DEBUG][Tue Nov 19 09:43:50 CET 2013][/home/jvanek/Desktop/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.cc:1204] ITNPP Thread# 140513434003264, gthread 0x7fcbd531f8c0: PIPE: plugin read: plugin PluginProxyInfo reference 1 http://www.walter-fendt.de:80";
+ String s2 = "plugindebugX 1384850630162954 [jvanek][ITW-Cplugindebug 1384850630163008 [jvanek][ITW-C-PLUGIN][MESSAGE_DEBUG][Tue Nov 19 09:43:50 CET 2013][/home/jvanek/Desktop/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.cc:1124] ITNPP Thread# 140513434003264, gthread 0x7fcbd531f8c0: parts[0]=plugin, parts[1]=PluginProxyInfo, reference, parts[3]=1, parts[4]=http://www.walter-fendt.de:80 -- decoded_url=http://www.walter-fendt.de:80";
+ String s3 = "preinit_pluginerror 1384850630163298 [jvanek][ITW-C-PLUGIN][MESSAGE_DEBUG][Tue Nov 19 09:43:50 CET 2013][/home/jvanek/Desktop/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.cc:1134] ITNPP Thread# 140513434003264, gthread 0x7fcbd531f8c0: Proxy info: plugin PluginProxyInfo reference 1 DIRECT";
+
+ @Test
+ public void CreatePluginHeaderTestOK() throws Exception{
+ PluginMessage p1 = new PluginMessage(s1);
+ System.out.println(p1.header + p1.restOfMessage);
+ PluginMessage p3 = new PluginMessage(s3);
+ Assert.assertFalse(p1.wasError);
+ Assert.assertFalse(p3.wasError);
+ Assert.assertTrue(p1.header.isC);
+ Assert.assertTrue(p3.header.isC);
+ Assert.assertEquals(OutputController.Level.MESSAGE_DEBUG,p1.header.level);
+ Assert.assertEquals(OutputController.Level.ERROR_ALL,p3.header.level);
+ Assert.assertTrue(p1.header.date.toString().contains("Tue Nov 19 09:43:50") && p1.header.date.toString().contains("2013"));
+ Assert.assertTrue(p3.header.date.toString().contains("Tue Nov 19 09:43:50") && p3.header.date.toString().contains("2013"));
+ Assert.assertTrue(p1.header.caller.contains("/home/jvanek"));
+ Assert.assertTrue(p3.header.caller.contains("/home/jvanek"));
+ Assert.assertTrue(p1.header.user.equals("jvanek"));
+ Assert.assertTrue(p3.header.user.equals("jvanek"));
+ Assert.assertTrue(p1.header.thread1.equals("140513434003264"));
+ Assert.assertTrue(p1.header.thread2.equals("0x7fcbd531f8c0"));
+ Assert.assertTrue(p3.header.thread1.equals("140513434003264"));
+ Assert.assertTrue(p3.header.thread2.equals("0x7fcbd531f8c0"));
+ Assert.assertTrue(p1.restOfMessage.equals(" PIPE: plugin read: plugin PluginProxyInfo reference 1 http://www.walter-fendt.de:80"));
+ Assert.assertTrue(p3.restOfMessage.equals("Proxy info: plugin PluginProxyInfo reference 1 DIRECT"));
+
+ }
+ @Test
+ public void CreatePluginHeaderTestNotOK()throws Exception{
+ PluginMessage p2 = new PluginMessage(s2);
+ Assert.assertTrue(p2.wasError);
+ Assert.assertTrue(p2.header.isC);
+ Assert.assertEquals(OutputController.Level.WARNING_ALL,p2.header.level);
+ Assert.assertTrue(p2.header.date.toString().contains(new Date().toString().substring(0,16))); //means no Tue Nov 19 09:43:50 :)
+ Assert.assertTrue(p2.header.user.equals("jvanek"));
+ Assert.assertTrue(p2.header.thread1 == null);
+ Assert.assertTrue(p2.header.thread2 == null);
+
+
+ }
+}