Revision: 4618
http://sourceforge.net/p/vexi/code/4618
Author: mkpg2
Date: 2013-12-19 23:55:02 +0000 (Thu, 19 Dec 2013)
Log Message:
-----------
Launcher. Display console/log in the event of an error.
Modified Paths:
--------------
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Launcher.java
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/LauncherApplet.java
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/LauncherMain.java
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Splash.java
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/util/StreamReader.java
Added Paths:
-----------
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Log.java
Removed Paths:
-------------
trunk/org.vexi-launcher/Launcher.java
trunk/org.vexi-launcher/LauncherApplet.java
Deleted: trunk/org.vexi-launcher/Launcher.java
===================================================================
--- trunk/org.vexi-launcher/Launcher.java 2013-12-19 22:33:44 UTC (rev
4617)
+++ trunk/org.vexi-launcher/Launcher.java 2013-12-19 23:55:02 UTC (rev
4618)
@@ -1,463 +0,0 @@
-package org.vexi.launcher;
-
-import java.applet.Applet;
-import java.awt.Color;
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-import org.vexi.DotVexi;
-
-/**
- * @author [email protected]
- * @contributor [email protected]
- *
- * <p>The launcher is responsible for downloading the Vexi Core
- * and the principle application components (.vexi files)
- * and launching it as a separate process so that it can
- * exist and survive outside of the restrictive environment
- * that is imposed upon applets.</p>
- *
- */
-abstract public class Launcher {
-
- // REMARK although a signed applet doesn't have any known securities
- // we restrict it to running from domains that we control because in
- // the event that it is compromised we can update the copy on these
- // domains. In this way the fetching of the applet acts as the security
- // check.
- abstract public Color getTextColor();
- abstract public Color getBorderColor();
- abstract public Color getBarColor();
- abstract public URL getSplashImageResource();
- abstract public String[] getPermittedDomains();
- abstract public Map getCerts();
- abstract public String getVersion();
-
- ////////////////
- // INIT
- final LauncherApplet applet;
- DotVexi dotvexi;
- String fetchCount = "?";
- int fetchIndex = 1;
- public Launcher(LauncherApplet applet) {
- this.applet = applet;
- }
-
- static protected void logflush() {
- System.err.flush();
- }
-
- static protected void log(String s) {
- System.err.println(s);
- }
-
-
- static private String getEnv(String name) {
- try {
- return System.getenv(name);
- } catch(Throwable t) {
- // REMARK - they deprecated this in 1.4, only to bring it back in
1.5.
- // By deprecated we mean it throws an error. So here we fall back
to
- // getting it from the commandline.
- try {
- String os = System.getProperty("os.name").toLowerCase();
- Process p;
- String cmd;
- if (os.indexOf("windows 9") != -1 || os.indexOf("windows me")
!= -1) {
- cmd = "command.com /c set";
- } else if (os.indexOf("windows") > -1) {
- cmd = "cmd.exe /c set";
- } else {
- cmd = "env";
- }
- p = Runtime.getRuntime().exec(cmd);
- BufferedReader br = new BufferedReader(new
InputStreamReader(p.getInputStream()));
- String s;
- while ((s = br.readLine()) != null) {
- if (s.startsWith(name + "=")) {
- return s.substring(name.length() + 1);
- }
- }
- } catch (Throwable t2) {
- log("Encountered an exception during fallback discovery of:
'"+name+"'");
- t2.printStackTrace();
- }
- return null;
- }
- }
-
- /** generates the basic command string to start java */
- static private String findInJavaHome(String os_name, String javaHome) {
- if (javaHome != null && !javaHome.equals("")) {
- String r = javaHome + File.separatorChar + "bin" +
File.separatorChar + "java";
- if (os_name.indexOf("windows") != -1) {
- r += ".exe";
- }
- if (new File(r).exists()) {
- return r;
- }
- }
- return null;
- }
-
- /** searches for the JVM binary in the usual places
- * @throws Problem */
- static private String findJvmBinary() throws Exception {
- log("-- Locating the Java Binary --");
- String jvmBinary = null;
- String os_name = System.getProperty("os.name", "").toLowerCase();
-
- log("Trying Environment Variable 'VEXI_JRE'");
- jvmBinary = findInJavaHome(os_name,getEnv("VEXI_JRE"));
- if (jvmBinary != null) {
- return jvmBinary;
- }
-
- log("Trying Environment Variable 'JAVA_HOME'");
- jvmBinary = findInJavaHome(os_name,getEnv("JAVA_HOME"));
- if (jvmBinary != null) {
- return jvmBinary;
- }
-
- log("Trying System Property 'java.home'");
- jvmBinary = findInJavaHome(os_name,System.getProperty("java.home"));
- if (jvmBinary != null) {
- return jvmBinary;
- }
-
- // check PATH
- log("Checking to see if java is on the PATH Environment Variable");
- String path = getEnv("PATH");
- if (path == null) {
- path = getEnv("Path");
- }
- if (path!=null) {
- StringTokenizer st = new StringTokenizer(path,
File.pathSeparatorChar + "");
- while (st.hasMoreTokens()) {
- String s = st.nextToken();
- if (new File(s + File.separatorChar + "java").exists() || new
File(s + File.separatorChar + "java.exe").exists() ) {
- jvmBinary = s + File.separatorChar + "java";
- if (os_name.indexOf("windows") != -1) {
- jvmBinary += ".exe";
- }
- return jvmBinary;
- }
- }
- }
-
- throw new Problem("Couldn't find a suitable JVM binary! See console
log for details");
- }
-
- long lastDate = -1;
- protected InputStream getInputStream(String url) throws IOException{
- final URLConnection uc = connect(url);
- InputStream is = uc.getInputStream();
- int contentLength = uc.getContentLength();
- lastDate = uc.getLastModified();
- return progressInputStream(is, url, contentLength);
- }
-
- public void initDotVexi() {
- dotvexi = new DotVexi(getCerts()) {
-
- protected void log(String s) { Launcher.log(s); }
-
- protected InputStream getInputStream(Object fountain, Object
principal) throws IOException {
- String url = (String)fountain;
- return Launcher.this.getInputStream(url);
- }
- protected long getRemoteDate(Object fountain, Object principal) {
- return lastDate;
- }
- };
- }
-
- public void initSplash(){
- Splash.init(getVersion(),getSplashImageResource(), getTextColor(),
getBorderColor(), getBarColor());
- }
-
-
- private InputStream progressInputStream(InputStream is, final String
displayname, final int contentLength ) {
- final String left = "Downloading: "+displayname;
- final String right = fetchIndex+"/"+fetchCount;
-
- return new FilterInputStream(new BufferedInputStream(is)) {
- int total = 0;
- int percent = 0;
- private void display() {
- double loaded = ((double)total) / ((double)contentLength);
- int newpercent = ((int)Math.ceil(loaded * 100));
- if (newpercent!=percent) {
- percent = newpercent;
-
- //log(percent + "%");
- Splash.update(left, right, (double)percent);
- }
- }
-
- public int read() throws IOException {
- int ret = super.read();
- if (ret != -1) {
- total++;
- }
- display();
- return ret;
- }
- public int read(byte[] buf, int off, int len) throws IOException {
- int ret = super.read(buf, off, len);
- if (ret != -1) {
- total += ret;
- }
- display();
- return ret;
- }
- };
- }
-
- /** check if a url falls within the permitted domains
- * @param url a string of an absolute url, must start with 'http://' or
'file://'
- * @return true iff url is permitted */
- protected boolean checkUrl(String url) {
- if (url.startsWith("file")) {
- return true;
- }
- if (url.startsWith("http")) {
- // remove the protocol
- url = url.substring(url.indexOf("//")+2);
- while (true) {
- String[] permittedDomains = getPermittedDomains();
- for (int i=0; i<permittedDomains.length; i++) {
- if (url.startsWith(permittedDomains[i])) {
- return true;
- }
- }
- // if we are a subdomain remove leading part and recheck
- if (url.indexOf('.')==-1) {
- break;
- }
- url = url.substring(url.indexOf('.')+1);
- }
- }
- return false;
- }
-
- static private String join(String[] ss) {
- String r = "";
- for (int i=0; i<ss.length; i++) {
- if (i>0) {
- r += ",";
- }
- r += ss[i];
- }
- return r;
- }
-
- /** fetches a file from the distribution site, writing it to the
appropriate place */
- public File fetch(String url) throws IOException {
- File localfile = dotvexi.getLocalFile(url);
- dotvexi.fetch(url, null, url, localfile);
- fetchIndex++;
- return localfile;
- }
-
- /** attempts to create a local file for logging vexi output to */
- protected File createLog(String logfile) throws IOException {
- File dir = dotvexi.findSubDir("logs");
- dir.mkdirs();
- File f=null;
- String fname = logfile;
- for (int i=0; i<100; i++) {
- f = new File(dir,fname);
- if ((f.exists() && !f.delete())) {
- fname = logfile+i;
- continue; // file occupied!
- }
- if (!f.createNewFile()) {
- break;
- }
- return f;
- }
- throw new RuntimeException("Could not create log file: " +
f.getCanonicalPath());
- }
-
-
-
- static public class Problem extends Exception {
- public Problem(String message) { super(message); }
- }
-
-
-
- public void go(
- String core,
- String mem,
- List<String> fetchVexis) {
- //log("Codebase is "+url);
- fetchCount = ""+(fetchVexis.size()+1);
-
-
- String coreurl = core;
- if (!coreurl.endsWith(".signed")) {
- permitUnsignedCore(coreurl);
- }
- File corefile = fetch(coreurl);
-
- List command = new ArrayList();
- command.add(findJvmBinary());
- if (mem!=null) {
- command.add("-Xmx" + mem);
- }
- command.add("-jar");
- command.add(corefile.getPath());
-
- String logfile = getParameter("logfile");
- if (logfile!=null) {
- createLog(logfile);
- command.add("-l");
- command.add("logs/"+logfile);
- }
- command.add("-biscuitid");
- command.add(DotVexi.urlUniqueName(codebase));
-
-
- for (int i = 0; i<10000;i++) {
- if (getParameter("option" + i) == null) {
- break;
- }
- command.add(getParameter("option" + i));
- }
-
-
- for (int i = 0; i<fetchVexis.size();i++) {
- File f = fetch((String)fetchVexis.get(i));
- command.add(f.getPath());
- }
-
-
- // REMARK - discovering os/architecture not relevant until
- // native builds are working again
- /*
- String os_name = System.getProperty("os.name", "").toLowerCase();
- log("os.name == " + os_name);
- Vector command = new Vector();
- String arch = null;
- if (os_name.indexOf("linux") != -1) {
- arch = new BufferedReader(new
InputStreamReader(Runtime.getRuntime().exec("/bin/uname
-m").getInputStream())).readLine();
- log("arch is " + arch);
- }*/
-
- spawn(command);
- }
-
- /** spawns the Vexi core
- * @param command contains the full command - including java */
- private void spawn(List<String> command) throws IOException {
- File dir = dotvexi.getBaseDir();
- String[] command_vec = command.toArray(new String[command.size()]);
- log("in directory : " + dir.getCanonicalPath());
- log("executing : ");
- for (int i=0; i<command_vec.length; i++) {
- log(" \"" + command_vec[i] + "\"");
- }
-
- final Process p = Runtime.getRuntime().exec(command_vec,null,dir);
-
- new Thread(new Runnable() {
- public void run() {
- // catch output
- StreamReader errorstream = new
StreamReader(p.getErrorStream(), "ERROR", true);
- StreamReader outputstream = new
StreamReader(p.getInputStream(), "OUTPUT", false);
- // kick off output streams
- errorstream.start();
- outputstream.start();
- try {
- updateStatus("Vexi loaded");
- int exitValue = p.waitFor();
- if (exitValue != 0) {
- updateError("Vexi exited abnormally with error code
'"+exitValue+"', see log output");
- } else {
- updateStatus("Vexi has finished running");
- }
- } catch (Throwable t) {
- log("Error exiting... " + p.exitValue());
- t.printStackTrace();
- }
- log("Exiting...");
- logflush();
- }
- }).start();
- }
-
-
- /**
- * @author [email protected]
- *
- * A very simple stream reader, copied from:
- * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
- */
- static class StreamReader extends Thread {
- InputStream is;
- String type;
-
- StreamReader(InputStream is, String type, boolean listenDisplay) {
- this.is = is;
- this.type = type;
- this.listenDisplay = listenDisplay;
- }
- private boolean listenDisplay;
-
- public void run() {
- try {
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
- String line=null;
- while ((line = br.readLine()) != null) {
- if (listenDisplay && line.contains("**display
launched**")) {
- Splash.close();
- }
- log(type + ">" + line);
- }
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
-
-
- ////////////////////
- //// Utility
- static private URLConnection connect(String url) throws IOException {
- try {
- URL u = new URL(url);
- final URLConnection uc = u.openConnection();
- uc.setUseCaches(false); // don't use the possibly short Java cache
- uc.connect();
- return uc;
- } catch (NullPointerException npe) {
- // WORKAROUND - sun libraries throw a NPE rather than
- // a more informative exception.
- throw new IOException("Invalid url: "+url);
- }
- }
-
- //////////////
- // Permission
- void permitAlternativeURL(String url) throws Problem {
- throw new Problem("Applet can not be run from unknown domain " + url +
"\nPermitted domains: " + join(getPermittedDomains()));
- }
- void permitUnsignedCore(String file) throws Problem {
- throw new Problem("Applet will not run unsigned core file: "+ file);
- }
-}
Deleted: trunk/org.vexi-launcher/LauncherApplet.java
===================================================================
--- trunk/org.vexi-launcher/LauncherApplet.java 2013-12-19 22:33:44 UTC (rev
4617)
+++ trunk/org.vexi-launcher/LauncherApplet.java 2013-12-19 23:55:02 UTC (rev
4618)
@@ -1,153 +0,0 @@
-package org.vexi.launcher;
-
-import java.applet.Applet;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Vector;
-
-import org.vexi.DotVexi;
-import org.vexi.launcher.Launcher.Problem;
-
-/**
- * @author [email protected]
- * @contributor [email protected]
- *
- * <p>The launcher is responsible for downloading the Vexi Core
- * and the principle application components (.vexi files)
- * and launching it as a separate process so that it can
- * exist and survive outside of the restrictive environment
- * that is imposed upon applets.</p>
- *
- */
-abstract public class LauncherApplet extends Applet {
- abstract protected Launcher createLauncher();
-
- ///////////////////////
- // APPLET
- ///////////////////////
-
- private Launcher launcher;
-
- /** applet entry point - this is where it all begins */
- public final void init() {
- launcher = createLauncher();
- launcher.initSplash();
- launcher.initDotVexi();
-
- // the rest is initialized outside of the restrictive applet sandbox
- // as we need to download several files and start up a new process
- // REMARK: this requires the applet to be signed, an unsigned applet
- // will most likely fail very soon after this next thread is started
- new Thread() {
- public void run() {
- java.security.AccessController.doPrivileged(new
java.security.PrivilegedAction() {
- public Object run() {
- launcher.go();
- return null;
- }
- });
- }
- }.start();
-
- }
-
- void log(String s){ Launcher.log(s);}
-
- public void go() {
- try{
- log("Launcher Build : "+launcher.getVersion());
-
- // Check codebase is permitted
- String codebase = getCodeBase()+"";
- updateStatus(""+codebase);
- if (!checkUrl(codebase)) {
- permitAlternativeURL(codebase);
- }
-
- String core = getParameter("core");
- if (core==null) {
- throw new Problem("Core property not set");
- }
-
- List<String> fetchVexis = new ArrayList(10);
- for (int i = 0; i<10000;i++) {
- String fetch = getParameter("vexi" + i);
- if (fetch == null) {
- break;
- }
- fetchVexis.add(fetch);
- }
-
- go(core, fetchVexis);
-
- } catch (Problem e) {
- updateError(e.getMessage());
- log(e.getMessage());
- } catch (Throwable e) {
- updateError("Error; please check the Java console");
- e.printStackTrace();
- } finally {
- Splash.close();
- }
- }
-
-
-
- final Font font = new Font("Sans-serif", Font.BOLD, 12);
- final private Object statusLock = new Object();
- private String statusText;
- private Color statusColor;
- private Image backbuffer = null;
-
- protected void updateStatus(String statusText) {
- updateStatus(statusText, Color.black);
- }
- protected void updateError(String statusText) {
- Launcher.log("Error: "+statusText);
- updateStatus(statusText, Color.red);
- }
-
- void updateStatus(String statusText, Color statusColor) {
- synchronized (statusLock) {
- this.statusText = statusText;
- this.statusColor = statusColor;
- }
- repaint();
- }
-
-
- public final void paint(Graphics g) { update(g); }
- public final void update(Graphics g2) {
- if (backbuffer == null || backbuffer.getWidth(null) != getSize().width
|| backbuffer.getHeight(null) != getSize().height) {
- backbuffer = createImage(getSize().width, getSize().height);
- }
- if (backbuffer == null) {
- return;
- }
- Graphics2D g = (Graphics2D)backbuffer.getGraphics();
-
- Color color;
- String text;
- synchronized(statusLock) {
- text = statusText;
- color = statusColor;
- }
-
- g.setColor(Color.white);
- g.fillRect(0, 0, getSize().width, getSize().height);
-
- int centerOffset = (getSize().width-(int)font.getStringBounds(text,
g.getFontRenderContext()).getWidth())/2;
- g.setColor(color);
- g.setFont(font);
- g.drawString(text, centerOffset, 15);
-
- g2.setClip(0, 0, getSize().width, getSize().height);
- g2.drawImage(backbuffer, 0, 0, null);
- }
-}
Modified: trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Launcher.java
===================================================================
--- trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Launcher.java
2013-12-19 22:33:44 UTC (rev 4617)
+++ trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Launcher.java
2013-12-19 23:55:02 UTC (rev 4618)
@@ -32,13 +32,11 @@
*/
abstract public class Launcher {
public interface Context {
- public void flush();
- public void log(String msg);
- public void warn(String msg);
- public void error(String msg);
public void updateStatus(String msg);
+ public void updateError(String msg);
public String getParameter(String s);
public void check() throws Problem;
+ public void exited();
}
// REMARK although a signed applet doesn't have any known securities
@@ -56,25 +54,27 @@
////////////////
// INIT
+ final public Log log;
final protected Context context;
DotVexi dotvexi;
String fetchCount = "?";
int fetchIndex = 1;
- public Launcher(Context feedback) {
- this.context = feedback;
+ public Launcher(Context context) {
+ this.log = new Log(context);
+ this.context = context;
}
protected void log(String s) {
- context.log(s);
+ log.log(s);
}
public Map getCerts() {
try {
return loadCerts();
} catch (Throwable e) {
- context.error("Error: applet unable to load root certificates");
+ log.error("Error: applet unable to load root certificates");
throw new Error(e);
}
}
@@ -180,6 +180,7 @@
public InputStream getInputStream(String url) throws IOException{
final URLConnection uc = connect(url);
InputStream is = uc.getInputStream();
+
int contentLength = uc.getContentLength();
lastDate = uc.getLastModified();
return progressInputStream(is, url, contentLength);
@@ -188,7 +189,7 @@
public void initDotVexi() {
dotvexi = new DotVexi(getCerts()) {
- protected void log(String s) { context.log(s); }
+ protected void log(String s) { log.log(s); }
protected InputStream getInputStream(Object fountain, Object
principal) throws IOException {
String url = (String)fountain;
@@ -202,7 +203,7 @@
public void initSplash(){
- Splash.init(context, getVersion(),getSplashImageResource(),
getTextColor(), getBorderColor(), getBarColor());
+ Splash.init(log, getVersion(),getSplashImageResource(), getTextColor(),
getBorderColor(), getBarColor());
}
@@ -310,7 +311,7 @@
throw new RuntimeException("Could not create log file: " +
f.getCanonicalPath());
}
- public void go() {
+ public void go() throws Exception {
try {
log("Launcher Build : "+getVersion());
@@ -387,12 +388,6 @@
}*/
spawn(command);
- } catch (Problem e) {
- context.error(e.getMessage());
- log(e.getMessage());
- } catch (Throwable e) {
- context.error("Error; please check the Java console");
- e.printStackTrace();
} finally {
Splash.close();
}
@@ -416,25 +411,26 @@
new Thread(new Runnable() {
public void run() {
// catch output
- StreamReader errorstream = new StreamReader(context,
p.getErrorStream(), "ERROR", true);
- StreamReader outputstream = new StreamReader(context,
p.getInputStream(), "OUTPUT", false);
+ StreamReader errorstream = new StreamReader(log,
p.getErrorStream(), "ERROR", true);
+ StreamReader outputstream = new StreamReader(log,
p.getInputStream(), "OUTPUT", false);
// kick off output streams
errorstream.start();
outputstream.start();
try {
- context.updateStatus("Vexi loaded");
+ log.status("Vexi loaded");
int exitValue = p.waitFor();
if (exitValue != 0) {
- context.error("Vexi exited abnormally with error code
'"+exitValue+"', see log output");
+ log.error("Vexi exited abnormally with error code
'"+exitValue+"', see log output");
} else {
- context.updateStatus("Vexi has finished running");
+ log.status("Vexi has finished running");
+ log.log("Exiting...");
+ context.exited();
}
} catch (Throwable t) {
- context.error("Error exiting... " + p.exitValue());
- t.printStackTrace();
+ log.error("Error exiting... " + p.exitValue());
+ log.error(t);
+ log.flush();
}
- context.log("Exiting...");
- context.flush();
}
}).start();
}
@@ -444,7 +440,7 @@
////////////////////
//// Utility
- static private URLConnection connect(String url) throws IOException {
+ public URLConnection connect(String url) throws IOException {
try {
URL u = new URL(url);
final URLConnection uc = u.openConnection();
@@ -455,7 +451,7 @@
// WORKAROUND - sun libraries throw a NPE rather than
// a more informative exception.
throw new IOException("Invalid url: "+url);
- }
+ }
}
//////////////
Modified:
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/LauncherApplet.java
===================================================================
--- trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/LauncherApplet.java
2013-12-19 22:33:44 UTC (rev 4617)
+++ trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/LauncherApplet.java
2013-12-19 23:55:02 UTC (rev 4618)
@@ -13,36 +13,53 @@
abstract public class LauncherApplet extends Applet implements Context{
Launcher launcher;
+ Log log;
abstract protected Launcher createLauncher();
/** applet entry point - this is where it all begins */
public final void init() {
- launcher = createLauncher();
- launcher.initSplash();
- launcher.initDotVexi();
-
- // the rest is initialized outside of the restrictive applet sandbox
- // as we need to download several files and start up a new process
- // REMARK: this requires the applet to be signed, an unsigned applet
- // will most likely fail very soon after this next thread is started
- new Thread() {
- public void run() {
- java.security.AccessController.doPrivileged(new
java.security.PrivilegedAction() {
- public Object run() {
- launcher.go();
- return null;
- }
- });
- }
- }.start();
+
+ launcher = createLauncher();
+ launcher.initSplash();
+ launcher.initDotVexi();
+ log = launcher.log;
+ // the rest is initialized outside of the restrictive applet
sandbox
+ // as we need to download several files and start up a new
process
+ // REMARK: this requires the applet to be signed, an unsigned
applet
+ // will most likely fail very soon after this next thread is
started
+ new Thread() {
+ public void run() {
+ java.security.AccessController.doPrivileged(new
java.security.PrivilegedAction() {
+ public Object run() {
+ go();
+ return null;
+ }
+ });
+ }
+ }.start();
+
}
+
+ public void exited(){}
+
+ public void go(){
+ try{
+ launcher.go();
+ } catch (Problem e) {
+ log.error(e.getMessage());
+ } catch (Throwable e) {
+ log.error("Unhandled exception");
+ log.error(e);
+ }
+ }
+
public void check() throws Problem {
String codebase = getCodeBase()+"";
- updateStatus(""+codebase);
+ log.status(""+codebase);
//log("Codebase is "+url);
if (!launcher.checkUrl(codebase)) {
@@ -72,20 +89,7 @@
* @param text
* message or error to display in the applet
*/
-
- public void log(String msg) {
- System.err.println(msg);
- }
- public void flush() {
- System.err.flush();
- }
-
- public void warn(String msg) { log("[WARNING]: "+msg); }
-
- public void error(String statusText) {
- log("[ERROR]: "+statusText);
- updateStatus(statusText, Color.red);
- }
+ public void updateError(String statusText) { updateStatus(statusText,
Color.red); }
public void updateStatus(String statusText) { updateStatus(statusText,
Color.black); }
private void updateStatus(String statusText, Color statusColor) {
synchronized (statusLock) {
Modified:
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/LauncherMain.java
===================================================================
--- trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/LauncherMain.java
2013-12-19 22:33:44 UTC (rev 4617)
+++ trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/LauncherMain.java
2013-12-19 23:55:02 UTC (rev 4618)
@@ -2,6 +2,9 @@
import java.io.File;
import java.io.InputStreamReader;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.URLConnection;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -16,20 +19,29 @@
*/
abstract public class LauncherMain implements Context{
+
+
+
+ final Launcher launcher;
+ final Log log;
+
private Map<String,String> params;
- private String application;
+ private String applicationUrl;
private String hash;
-
- abstract public Launcher getLauncher();
+ public LauncherMain() {
+ this.launcher = createLauncher();
+ this.log = launcher.log;
+ }
+ abstract public Launcher createLauncher();
void init(String[] args){
for(String s: args){
String[] k_v = s.split("=");
String k = k_v[0];
String v = k_v[1];
- if("application".equals(k)){
- this.application = v;
+ if("application_url".equals(k)){
+ this.applicationUrl = v;
}else if("hash".equals(k)){
this.hash = v;
}
@@ -37,49 +49,71 @@
}
public void run(String[] args) throws Exception{
- getLauncher().initSplash();
-
- File confFile = new File("conf");
- if(confFile.isFile()){
- String[] conf =
IOUtil.fileToString(confFile).split("/n");
- init(conf);
- }else{
- warn("conf file does not exist");
+ try{
+ launcher.initSplash();
+
+ File confFile = new File("conf");
+ if(confFile.isFile()){
+ String[] conf =
IOUtil.fileToString(confFile).split("/n");
+ init(conf);
+ }else{
+ log.warn("conf file does not exist");
+ }
+
+ init(args);
+ if(applicationUrl==null){
+ log.error("'application' not specified (in conf
or args)");
+ System.exit(1);
+ }
+
+ checkVersion();
+ fetchArgs();
+ launcher.initDotVexi();
+ launcher.go();
+ } catch (Problem e) {
+ log.error(e.getMessage());
+ } catch (Throwable e) {
+ log.error("Unexpected problem");
+ log.error(e);
}
- init(args);
- if(application==null){
- error("'application' not specified (in conf or args)");
- System.exit(1);
- }
-
- checkVersion();
- fetchArgs();
- getLauncher().initDotVexi();
- getLauncher().go();
-
}
- String readString(String path) throws Exception{
- return IOUtil.readerToString(new
InputStreamReader(getLauncher().getInputStream(path), "UTF8"));
+ String readString(String url) throws Exception{
+ try{
+ final URLConnection uc = launcher.connect(url);
+ if(uc instanceof HttpURLConnection){
+ HttpURLConnection huc = (HttpURLConnection)uc;
+
if(HttpURLConnection.HTTP_OK!=huc.getResponseCode()){
+ throw new Problem("Could not read
"+url+"\nHttp Code '"+huc.getResponseCode()+"'");
+ }
+ String contentType = huc.getContentType();
+ if(!contentType.contains("text/plain")){
+ throw new Problem("Could not read
"+url+"\nInvalid content type '"+contentType+"'");
+ }
+ }
+ return IOUtil.readerToString(new
InputStreamReader(uc.getInputStream(), "UTF8"));
+ }catch (ConnectException e) {
+ throw new Problem("Unable to connect: "+e.getMessage());
+ }
}
void checkVersion() throws Exception{
- String hashes = readString(application+"/launcherversions");
+ String hashes = readString(applicationUrl+"/launcherversions");
if(hash==null){
- warn("no version check");
+ log.warn("no version check");
}else{
for(String hash: hashes.split("\n")){
if(this.hash.equals(hash)){
return;
}
}
- log("** Launcher incompatible, please download new
version **");
- log("our hash: "+hash);
- log("allowed: ");
+ log.error("** Launcher incompatible, please download
new version **");
+ log.log("our hash: "+hash);
+ log.log("allowed: ");
for(String hash: hashes.split("\n")){
- log(" "+hash);
+ log.log(" "+hash);
}
System.exit(0);
}
@@ -87,7 +121,7 @@
void fetchArgs() throws Exception{
params = new LinkedHashMap();
- String args = readString(application+"/launcherargs");
+ String args = readString(applicationUrl+"/launcher/args");
String[] argArr = args.split("\n");
for(String s: argArr){
if("".equals(s.trim())) continue;
@@ -96,18 +130,17 @@
if(k_v.length==2){
params.put(k_v[0], k_v[1]);
}else{
- warn("invalid arg: "+s);
+ log.warn("invalid arg: "+s);
}
}
}
- public void flush() { System.err.flush(); }
- public void log(String msg) { System.err.println(msg); }
- public void warn(String msg) { log("[WARNING]: "+msg); }
- public void error(String msg) { log("[ERROR]: "+msg); }
- public void updateStatus(String msg) { log(msg); }
+ public void updateError(String msg) {}
+ public void updateStatus(String msg) { }
public String getParameter(String key) { return params.get(key); }
- public void check() throws Problem {}
+ public void check() throws Problem {}
+
+ public void exited(){ System.exit(0); }
}
Added: trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Log.java
===================================================================
--- trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Log.java
(rev 0)
+++ trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Log.java
2013-12-19 23:55:02 UTC (rev 4618)
@@ -0,0 +1,89 @@
+package org.vexi.launcher;
+
+import java.awt.BorderLayout;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+import org.vexi.launcher.Launcher.Context;
+
+
+public class Log {
+ final Context context;
+ private List<String> log = new ArrayList();
+ private JTextArea text;
+
+ Log(Context context){
+ this.context = context;
+ }
+
+ public void flush(){
+ System.err.flush();
+ }
+
+ public void status(String msg){
+ log(msg);
+ if(context!=null) context.updateStatus(msg);
+ }
+
+ public void log(String msg){
+ if(text!=null){
+ text.append(msg);
+ text.append("\n");
+ }else{
+ if(log.size()>1000){
+ log.remove(0);
+ }
+ log.add(msg);
+ }
+ System.err.println(msg);
+ }
+ public void warn(String msg){ log("[WARNING] "+msg); }
+ public void error(String msg){
+ log("[ERROR] "+msg);
+ if(context!=null) context.updateError(msg);
+ if(text==null){
+ text = new JTextArea();
+ text.setLineWrap(true);
+ text.setWrapStyleWord(true);
+ for(String s: log){
+ text.append(s);
+ text.append("\n");
+ }
+ text.setBounds(5, 35, 385, 330);
+ JScrollPane scroll = new JScrollPane(text);
+ JPanel panel = new JPanel(null);
+ panel.setLayout(new BorderLayout());
+ panel.add(scroll, BorderLayout.CENTER);
+
+ JFrame frame = new JFrame();
+ frame.setSize(400,400);
+
+ frame.setLocation(0,0);
+ frame.setTitle("Launcher Log");
+ frame.add(panel);
+ frame.setVisible(true);
+
+ frame.addWindowListener( new WindowAdapter() {
+ public void windowClosing(WindowEvent we) {
+ context.exited();
+ }
+ } );
+ }
+ }
+ public void error(Throwable e) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ pw.flush();
+ log(sw.toString());
+ }
+}
\ No newline at end of file
Property changes on:
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Log.java
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Splash.java
===================================================================
--- trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Splash.java
2013-12-19 22:33:44 UTC (rev 4617)
+++ trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/Splash.java
2013-12-19 23:55:02 UTC (rev 4618)
@@ -15,8 +15,6 @@
import java.io.IOException;
import java.net.URL;
-import org.vexi.launcher.Launcher.Context;
-
/**
*
* @author Mike Goodwin
@@ -31,24 +29,24 @@
static private SplashWindow initFallback() {
return new Fallback();
}
- static private SplashWindow initFast(Context context) {
+ static private SplashWindow initFast(Log log) {
SplashScreen splash = SplashScreen.getSplashScreen();
if (splash==null) {
- context.warn("could not find fast splash screen, using old style");
+ log.warn("could not find fast splash screen, using old style");
return initFallback();
} else {
return new Fast(splash);
}
}
- static public SplashWindow init(Context context, String version, URL
splashImage, Color textcolor, Color bordercolor, Color barcolor) {
+ static public SplashWindow init(Log log, String version, URL splashImage,
Color textcolor, Color bordercolor, Color barcolor) {
Splash.version = version;
Splash.textcolor = textcolor;
Splash.bordercolor = bordercolor;
Splash.barcolor = barcolor;
try {
Splash.class.getClassLoader().loadClass("java.awt.SplashScreen");
- instance = initFast(context);
+ instance = initFast(log);
} catch (ClassNotFoundException e) {
instance = initFallback();
}
Modified:
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/util/StreamReader.java
===================================================================
---
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/util/StreamReader.java
2013-12-19 22:33:44 UTC (rev 4617)
+++
trunk/org.vexi-launcher/src/main/java/org/vexi/launcher/util/StreamReader.java
2013-12-19 23:55:02 UTC (rev 4618)
@@ -5,7 +5,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
-import org.vexi.launcher.Launcher.Context;
+import org.vexi.launcher.Log;
import org.vexi.launcher.Splash;
/**
@@ -15,12 +15,12 @@
* http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
*/
public class StreamReader extends Thread {
- final Context feedback;
+ final Log log;
final InputStream is;
final String type;
- public StreamReader(Context feedback, InputStream is, String type, boolean
listenDisplay) {
- this.feedback = feedback;
+ public StreamReader(Log log, InputStream is, String type, boolean
listenDisplay) {
+ this.log = log;
this.is = is;
this.type = type;
this.listenDisplay = listenDisplay;
@@ -36,10 +36,10 @@
if (listenDisplay && line.contains("**display launched**")) {
Splash.close();
}
- feedback.log(type + ">" + line);
+ log.log(type + ">" + line);
}
} catch (IOException ioe) {
- ioe.printStackTrace();
+ log.error(ioe);
}
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT
organizations don't have a clear picture of how application performance
affects their revenue. With AppDynamics, you get 100% visibility into your
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn