diff -r 3405d5fc4339 netx/net/sourceforge/jnlp/config/Defaults.java --- a/netx/net/sourceforge/jnlp/config/Defaults.java Thu Mar 28 14:40:11 2013 -0400 +++ b/netx/net/sourceforge/jnlp/config/Defaults.java Fri Mar 29 16:49:02 2013 +0100 @@ -391,6 +391,12 @@ DeploymentConfiguration.KEY_SECURITY_LEVEL, new SecurityValueValidator(), null + }, + //JVM executable for itw + { + DeploymentConfiguration.KEY_JRE_DIR, + null, + null } }; diff -r 3405d5fc4339 netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java --- a/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java Thu Mar 28 14:40:11 2013 -0400 +++ b/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java Fri Mar 29 16:49:02 2013 +0100 @@ -166,6 +166,7 @@ * JVM arguments for plugin */ public static final String KEY_PLUGIN_JVM_ARGUMENTS= "deployment.plugin.jvm.arguments"; + public static final String KEY_JRE_DIR= "deployment.jre.dir"; public enum ConfigType { System, User @@ -178,6 +179,10 @@ private File systemPropertiesFile = null; /** The user's deployment.config file */ private File userPropertiesFile = null; + + /*default user file*/ + public static final File USER_DEPLOYMENT_PROPERTIES_FILE = new File(System.getProperty("user.home") + File.separator + DEPLOYMENT_DIR + + File.separator + DEPLOYMENT_PROPERTIES); /** the current deployment properties */ private Map> currentConfiguration; @@ -221,8 +226,7 @@ */ public void load(boolean fixIssues) throws ConfigurationException { // make sure no state leaks if security check fails later on - File userFile = new File(System.getProperty("user.home") + File.separator + DEPLOYMENT_DIR - + File.separator + DEPLOYMENT_PROPERTIES); + File userFile = new File(USER_DEPLOYMENT_PROPERTIES_FILE.getAbsolutePath()); SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -415,8 +419,25 @@ return etcFile; } - File jreFile = new File(System.getProperty("java.home") + File.separator + "lib" - + File.separator + DEPLOYMENT_CONFIG); + String jrePath = null; + try { + Map> tmpProperties = parsePropertiesFile(USER_DEPLOYMENT_PROPERTIES_FILE); + Setting jreSetting = tmpProperties.get(KEY_JRE_DIR); + if (jreSetting != null) { + jrePath = jreSetting.getValue(); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + File jreFile; + if (jrePath != null) { + jreFile = new File(jrePath + File.separator + "lib" + + File.separator + DEPLOYMENT_CONFIG); + } else { + jreFile = new File(System.getProperty("java.home") + File.separator + "lib" + + File.separator + DEPLOYMENT_CONFIG); + } if (jreFile.isFile()) { return jreFile; } diff -r 3405d5fc4339 netx/net/sourceforge/jnlp/controlpanel/ControlPanel.java --- a/netx/net/sourceforge/jnlp/controlpanel/ControlPanel.java Thu Mar 28 14:40:11 2013 -0400 +++ b/netx/net/sourceforge/jnlp/controlpanel/ControlPanel.java Fri Mar 29 16:49:02 2013 +0100 @@ -53,6 +53,7 @@ import javax.swing.event.ListSelectionListener; import net.sourceforge.jnlp.config.DeploymentConfiguration; +import net.sourceforge.jnlp.controlpanel.JVMPanel.JvmValidationResult; import net.sourceforge.jnlp.runtime.Translator; import net.sourceforge.jnlp.security.KeyStores; import net.sourceforge.jnlp.security.viewer.CertificatePane; @@ -157,6 +158,20 @@ topPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); return topPanel; } + + private int validateJdk() { + String s = ControlPanel.this.config.getProperty(DeploymentConfiguration.KEY_JRE_DIR); + JvmValidationResult validationResult = JVMPanel.validateJvm(s); + if (validationResult.id == JvmValidationResult.ID.NOT_DIR + || validationResult.id == JvmValidationResult.ID.NOT_VALID_DIR + || validationResult.id == JvmValidationResult.ID.NOT_VALID_JDK) { + return JOptionPane.showConfirmDialog(ControlPanel.this, + ""+Translator.R("CPJVMNotokMessage1", s)+"
" + + validationResult.formatedText+"
" + + Translator.R("CPJVMNotokMessage2", DeploymentConfiguration.KEY_JRE_DIR, DeploymentConfiguration.USER_DEPLOYMENT_PROPERTIES_FILE)+""); + } + return JOptionPane.OK_OPTION; + } /** * Creates the "ok" "apply" and "cancel" buttons. @@ -173,6 +188,10 @@ @Override public void actionPerformed(ActionEvent e) { ControlPanel.this.saveConfiguration(); + int i = validateJdk(); + if (i!= JOptionPane.OK_OPTION){ + return; + } ControlPanel.this.dispose(); } }); @@ -183,6 +202,7 @@ @Override public void actionPerformed(ActionEvent e) { ControlPanel.this.saveConfiguration(); + validateJdk(); } }); buttons.add(applyButton); diff -r 3405d5fc4339 netx/net/sourceforge/jnlp/controlpanel/JVMPanel.java --- a/netx/net/sourceforge/jnlp/controlpanel/JVMPanel.java Thu Mar 28 14:40:11 2013 -0400 +++ b/netx/net/sourceforge/jnlp/controlpanel/JVMPanel.java Fri Mar 29 16:49:02 2013 +0100 @@ -40,17 +40,44 @@ import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; - +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JTextField; - +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.Document; import net.sourceforge.jnlp.config.DeploymentConfiguration; import net.sourceforge.jnlp.runtime.Translator; +import net.sourceforge.jnlp.util.StreamUtils; @SuppressWarnings("serial") public class JVMPanel extends NamedBorderPanel { - private DeploymentConfiguration config; + + public static class JvmValidationResult { + + public static enum ID{ + EMPTY, NOT_DIR, NOT_VALID_DIR, NOT_VALID_JDK, VALID_JDK; + } + public final String formatedText; + public final ID id; + + public JvmValidationResult(String formatedText, ID id) { + this.id = id; + this.formatedText = formatedText; + } + + + } + + private DeploymentConfiguration config; + private File lastPath = new File("/usr/lib/jvm/java/jre/"); JVMPanel(DeploymentConfiguration config) { super(Translator.R("CPHeadJVMSettings"), new GridBagLayout()); @@ -59,22 +86,130 @@ } private void addComponents() { - JLabel description = new JLabel("" + Translator.R("CPJVMPluginArguments") + "
"); - JTextField testFieldArguments = new JTextField(25); + final JLabel description = new JLabel("" + Translator.R("CPJVMPluginArguments") + "
"); + final JTextField testFieldArguments = new JTextField(25); testFieldArguments.getDocument().addDocumentListener(new DocumentAdapter(config, DeploymentConfiguration.KEY_PLUGIN_JVM_ARGUMENTS)); testFieldArguments.setText(config.getProperty(DeploymentConfiguration.KEY_PLUGIN_JVM_ARGUMENTS)); + + final JLabel descriptionExec = new JLabel("" + Translator.R("CPJVMitwExec") + "
"); + final JTextField testFieldArgumentsExec = new JTextField(100); + final JLabel validationResult = new JLabel(resetValidationResult(testFieldArgumentsExec.getText(), "", "CPJVMnone")); + final JCheckBox allowTypoTimeValidation = new JCheckBox(Translator.R("CPJVMPluginAllowTTValidation"), true); + allowTypoTimeValidation.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + validationResult.setText(resetValidationResult(testFieldArgumentsExec.getText(), "", "CPJVMnone")); + } + }); + testFieldArgumentsExec.getDocument().addDocumentListener(new DocumentListener() { + String last = ""; + int c = 0; + + private String documentToString(Document d) { + try { + return d.getText(0, d.getLength()); + } catch (Exception ex) { + return ""; + } + } + + @Override + public void insertUpdate(DocumentEvent e) { + if (allowTypoTimeValidation.isSelected()) { + JvmValidationResult s = validateJvm(testFieldArgumentsExec.getText()); + validationResult.setText(resetValidationResult(testFieldArgumentsExec.getText(), s.formatedText, "CPJVMvalidated")); + } + } + + @Override + public void removeUpdate(DocumentEvent e) { + if (allowTypoTimeValidation.isSelected()) { + JvmValidationResult s = validateJvm(testFieldArgumentsExec.getText()); + validationResult.setText(resetValidationResult(testFieldArgumentsExec.getText(), s.formatedText, "CPJVMvalidated")); + } + } + + @Override + public void changedUpdate(DocumentEvent e) { + if (allowTypoTimeValidation.isSelected()) { + JvmValidationResult s = validateJvm(testFieldArgumentsExec.getText()); + validationResult.setText(resetValidationResult(testFieldArgumentsExec.getText(), s.formatedText, "CPJVMvalidated")); + } + } + }); + + testFieldArgumentsExec.getDocument().addDocumentListener(new DocumentAdapter(config, DeploymentConfiguration.KEY_JRE_DIR)); + testFieldArgumentsExec.setText(config.getProperty(DeploymentConfiguration.KEY_JRE_DIR)); + + final JButton selectJvm = new JButton(Translator.R("CPJVMPluginSelectExec")); + selectJvm.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser jfch; + if (lastPath != null && lastPath.exists()) { + jfch = new JFileChooser(lastPath); + } else { + jfch = new JFileChooser(); + } + jfch.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int i = jfch.showOpenDialog(JVMPanel.this); + if (i == JFileChooser.APPROVE_OPTION && jfch.getSelectedFile() != null) { + lastPath = jfch.getSelectedFile().getParentFile(); + String nws = jfch.getSelectedFile().getAbsolutePath(); + String olds = testFieldArgumentsExec.getText(); + if (!nws.equals(olds)) { + validationResult.setText(resetValidationResult(testFieldArgumentsExec.getText(), "", "CPJVMnone")); + } + testFieldArgumentsExec.setText(nws); + } + + } + }); + final JButton validateJvm = new JButton(Translator.R("CPJVMitwExecValidation")); + validateJvm.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JvmValidationResult s = validateJvm(testFieldArgumentsExec.getText()); + validationResult.setText(resetValidationResult(testFieldArgumentsExec.getText(), s.formatedText, "CPJVMvalidated")); + + } + }); + // Filler to pack the bottom of the panel. GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.weightx = 1; + c.gridwidth = 4; c.gridx = 0; c.gridy = 0; + c.insets = new Insets(2, 2, 4, 4); this.add(description, c); c.gridy++; this.add(testFieldArguments, c); + c.gridy++; + this.add(descriptionExec, c); + c.gridy++; + this.add(testFieldArgumentsExec, c); + c.gridy++; + GridBagConstraints cb1 = (GridBagConstraints) c.clone(); + cb1.fill = GridBagConstraints.NONE; + cb1.gridwidth = 1; + this.add(selectJvm, cb1); + GridBagConstraints cb3 = (GridBagConstraints) c.clone(); + cb3.fill = GridBagConstraints.NONE; + cb3.gridx = 2; + cb3.gridwidth = 1; + this.add(allowTypoTimeValidation, cb3); + GridBagConstraints cb2 = (GridBagConstraints) c.clone(); + cb2.fill = GridBagConstraints.NONE; + cb2.gridx = 3; + cb2.gridwidth = 1; + this.add(validateJvm, cb2); + c.gridy++; + this.add(validationResult, c); // This is to keep it from expanding vertically if resized. Component filler = Box.createRigidArea(new Dimension(1, 1)); @@ -82,4 +217,104 @@ c.weighty++; this.add(filler, c); } + + public static JvmValidationResult validateJvm(String cmd) { + if (cmd == null || cmd.trim().equals("")) { + return new JvmValidationResult("" + Translator.R("CPJVMvalueNotSet") + "", + JvmValidationResult.ID.EMPTY); + } + String validationResult = ""; + File jreDirFile = new File(cmd); + JvmValidationResult.ID latestOne = JvmValidationResult.ID.EMPTY; + if (jreDirFile.isDirectory()) { + validationResult += "" + Translator.R("CPJVMisDir") + "
"; + } else { + validationResult += "" + Translator.R("CPJVMnotDir") + "
"; + latestOne = JvmValidationResult.ID.NOT_DIR; + } + File javaFile = new File(cmd + File.separator + "bin" + File.separator + "java"); + if (javaFile.isFile()) { + validationResult += "" + Translator.R("CPJVMjava") + "
"; + } else { + validationResult += "" + Translator.R("CPJVMnoJava") + "
"; + if (latestOne != JvmValidationResult.ID.NOT_DIR) { + latestOne = JvmValidationResult.ID.NOT_VALID_JDK; + } + } + File rtFile = new File(cmd + File.separator + "lib" + File.separator + "rt.jar"); + if (javaFile.isFile()) { + validationResult += "" + Translator.R("CPJVMrtJar") + "
"; + } else { + validationResult += "" + Translator.R("CPJVMnoRtJar") + "
"; + if (latestOne != JvmValidationResult.ID.NOT_DIR) { + latestOne = JvmValidationResult.ID.NOT_VALID_JDK; + } + } + ProcessBuilder sb = new ProcessBuilder(javaFile.getAbsolutePath(), "-version"); + Process p = null; + String processErrorStream = ""; + String processStdOutStream = ""; + Integer r = null; + try { + p = sb.start(); + p.waitFor(); + processErrorStream = StreamUtils.readStreamAsString(p.getErrorStream()); + processStdOutStream = StreamUtils.readStreamAsString(p.getInputStream()); + r = p.exitValue(); + //System.err.println(processErrorStream); + //System.out.println(processStdOutStream); + processErrorStream = processErrorStream.toLowerCase(); + processStdOutStream = processStdOutStream.toLowerCase(); + } catch (Exception ex) {; + ex.printStackTrace(); + + } + if (r == null) { + validationResult += "" + Translator.R("CPJVMnotLaunched") + ""; + if (latestOne != JvmValidationResult.ID.NOT_DIR) { + latestOne = JvmValidationResult.ID.NOT_VALID_JDK; + } + return new JvmValidationResult(validationResult, latestOne); + } + if (r.intValue() != 0) { + validationResult += "" + Translator.R("CPJVMnoSuccess") + ""; + if (latestOne != JvmValidationResult.ID.NOT_DIR) { + latestOne = JvmValidationResult.ID.NOT_VALID_JDK; + } + return new JvmValidationResult(validationResult, latestOne); + } + if (processErrorStream.contains("openjdk") || processStdOutStream.contains("openjdk")) { + validationResult += "" + Translator.R("CPJVMopenJdkFound") + ""; + return new JvmValidationResult(validationResult, JvmValidationResult.ID.VALID_JDK); + } + if (processErrorStream.contains("ibm") || processStdOutStream.contains("ibm")) { + validationResult += "" + Translator.R("CPJVMibmFound") + ""; + if (latestOne != JvmValidationResult.ID.NOT_DIR) { + latestOne = JvmValidationResult.ID.NOT_VALID_JDK; + } + return new JvmValidationResult(validationResult, latestOne); + } + if (processErrorStream.contains("gij") || processStdOutStream.contains("gij")) { + validationResult += "" + Translator.R("CPJVMgijFound") + ""; + if (latestOne != JvmValidationResult.ID.NOT_DIR) { + latestOne = JvmValidationResult.ID.NOT_VALID_JDK; + } + return new JvmValidationResult(validationResult, latestOne); + } + if (processErrorStream.contains("oracle") || processStdOutStream.contains("oracle") + || processErrorStream.contains("Java(TM)") || processStdOutStream.contains("Java(TM)")) { + validationResult += "" + Translator.R("CPJVMoracleFound") + ""; + if (latestOne != JvmValidationResult.ID.NOT_DIR) { + latestOne = JvmValidationResult.ID.NOT_VALID_JDK; + } + return new JvmValidationResult(validationResult, latestOne); + } + validationResult += "" + Translator.R("CPJVMstrangeProcess") + ""; + return new JvmValidationResult(validationResult, JvmValidationResult.ID.NOT_VALID_JDK); + + } + + private String resetValidationResult(final String value, String result, String headerKey) { + return "" + Translator.R(headerKey) + ":
" + value + "
" + result + "
"; + } } diff -r 3405d5fc4339 netx/net/sourceforge/jnlp/resources/Messages.properties --- a/netx/net/sourceforge/jnlp/resources/Messages.properties Thu Mar 28 14:40:11 2013 -0400 +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties Fri Mar 29 16:49:02 2013 +0100 @@ -310,6 +310,29 @@ CPDebuggingDescription=Enable options here to help with debugging CPDesktopIntegrationDescription=Set whether or not to allow creation of desktop shortcut. CPJVMPluginArguments=Set JVM arguments for plugin. +CPJVMitwExec=Set JVM for icedtea-web - working best with OpenJDK +CPJVMitwExecValidation=Validate JVM for icedtea-web +CPJVMPluginSelectExec=Select JVM for icedtea-web +CPJVMnone=None validation result for +CPJVMvalidated=Validation result for +CPJVMvalueNotSet=Value is not set. Hardcoded JVM will be used. +CPJVMnotLaunched=Error, process was not launched, see console output for more info. +CPJVMnoSuccess=Error, process have not ended successfully, see output for details, but your java is not set correctly. +CPJVMopenJdkFound=Excellent, OpenJDK detected +CPJVMoracleFound=Great, Oracle java detected +CPJVMibmFound=Good, IBM java detected +CPJVMgijFound=Warning, gij detected +CPJVMstrangeProcess=Your path had an executable process, but it was not recognized. Verify the Java version in the console output. +CPJVMnotDir=Error, The path you chose is not a directory. +CPJVMisDir=Ok, the path you chose is a directory. +CPJVMnoJava=Error, the directory you chose does not contain bin/java. +CPJVMjava=Ok, the directory you chose contains bin/java. +CPJVMnoRtJar=Error, the directory you chose does not contain lib/rt.jar +CPJVMrtJar=Ok, the directory you chose contains lib/rt.jar. +CPJVMPluginAllowTTValidation=Allow type-time validation +CPJVMNotokMessage1=You have entered invalid JDK value ({0}) with following error message: +CPJVMNotokMessage2=With invalid JDK IcedTea-Web will probably not able to start.
You will have to modify or remove {0} property in your configuration file {1}.
You should try to search for OpenJDK in your system or be sure you know what you are doing. + # Control Panel - Buttons CPButAbout=About... diff -r 3405d5fc4339 netx/net/sourceforge/jnlp/util/StreamUtils.java --- a/netx/net/sourceforge/jnlp/util/StreamUtils.java Thu Mar 28 14:40:11 2013 -0400 +++ b/netx/net/sourceforge/jnlp/util/StreamUtils.java Fri Mar 29 16:49:02 2013 +0100 @@ -37,9 +37,11 @@ package net.sourceforge.jnlp.util; +import java.io.BufferedReader; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; public class StreamUtils { @@ -71,4 +73,21 @@ } } } + + + public static String readStreamAsString(InputStream stream) throws IOException { + InputStreamReader is = new InputStreamReader(stream); + StringBuilder sb = new StringBuilder(); + BufferedReader br = new BufferedReader(is); + while (true) { + String read = br.readLine(); + if (read == null) { + break; + } + sb.append(read); + + } + + return sb.toString(); + } }