Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Relaunching the VM  (Read 3052 times)
0 Members and 1 Guest are viewing this topic.
Offline CommanderKeith
« Posted 2007-03-14 11:22:27 »

Hi,

Does anyone know a way to relaunch the VM in a system-independent manner? 

I've got a problem where I need to get away from the WebStart class-loader and its signing crap and the only way I can see it working is if I relaunch a new VM using something like <a href="http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html">Runtime.exec()</a>.  Apart from getting around webstart, this code would be handy for relaunching the VM to use different Java2D pipeline flags  Cool.

So the code would look something like:

String javaExeName = "java.exe";   // this would only work on windows, anyone know the linux & mac version?
File myJarFile = new File("C:/myJarFile.jar");
String fileSeparator = System.getProperty("file.separator");

String commandString = System.getProperty("java.home") + fileSeparator + "bin" + fileSeparator + javaExeName +" ";
// would the classpath need to be set here?  Maybe that would that go like:
// String classPathOption = "-classpath"+" "+"\""+myJarFileName.getParent().getAbsolutePath()+"\"";
// commandString += classPathOption;
commandString += "\""+myJarFile.getAbsolutePath()+"\"";   
// I think the above would work so long as the main-class was specified in the manifest file (which is inside the jar).
Runtime.getRuntime().exec(commandString);

Googling the topic hasn't been successful for me but I did find <a href="http://www.centerkey.com/java/browser/">this (a system-independent way of launching the browser using Runtime.exec())</a>. 

If anyone can help with the 'javaExeName' variable for other OS's or anything else that would be great.  Smiley

Thanks,
Keith

PS: I've raised this issue before here: http://www.java-gaming.org/forums/index.php?topic=14092.15
Also, the below code actually works.  It spawns a new VM (on windows) but can't be used from Webstart since the classpath location isn't returned on a webstarted-app.
String fileSeparator = System.getProperty("file.separator");
String commandString = System.getProperty("java.home")+fileSeparator+"bin"+fileSeparator+"java.exe"+" ";
String classPathOption = "-classpath"+" "+"\""+System.getProperty("java.class.path")+"\"";
commandString += classPathOption+" ";
String fullClassName = Main.class.getCanonicalName();
commandString += fullClassName;
Runtime.getRuntime().exec(commandString);

PPS:  This is the problem I'm having with webstart: http://www.java-gaming.org/forums/index.php?topic=15397.0

Offline ryanm

Senior Member


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #1 - Posted 2007-03-14 11:33:23 »

On linux (and possibly OSX) it's just "java"
Offline g666

Junior Member





« Reply #2 - Posted 2007-03-14 12:15:18 »

On linux (and possibly OSX) it's just "java"

same on windows Tongue

desperately seeking sanity
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline endolf

JGO Coder


Medals: 7


Current project release date: sometime in 3003


« Reply #3 - Posted 2007-03-14 13:07:16 »

Erm, I don't think runtime.exec is allowed unless you have a signed webstart app.

Done some digging around, found this article and it seems to confirm it
Quote
In practical terms the sandbox restricts your program from talking to the host environment in any way. Files, network access, and most system functions are off-limits, as are various ways of getting around these restrictions, like using custom classloaders, Runtime.exec() calls, or native libraries.

Might be worth trying, but don't be surprised if it doesn't work unless your app is signed. I'd be worried if it does as it means the sandbox can be breached without my permission.

Endolf

Online Riven
« League of Dukes »

JGO Overlord


Medals: 744
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #4 - Posted 2007-03-14 15:45:33 »

Yup, my first thought.

This would never ever be allowed, as it would render all whole security-layer useless.

You simply can't break out of the sandbox...


maybe setting the reference (pointer) to the security-manager to null (0) with Unsafe..
but i think Reflection (which is required to use Unsafe), is heavily restricted by the security-manager
Sun just must have thought about this.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline ryanm

Senior Member


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #5 - Posted 2007-03-14 16:12:52 »

As I understand it from the second linked thread in the original post, his app is signed. He wants to spawn another VM to get around the fact that the classes he is generating at runtime do not inherit the signed-ness of the generating classes, and thus raise a security exception.
Online cylab

JGO Ninja


Medals: 38



« Reply #6 - Posted 2007-03-14 16:55:48 »

We will do something similar in the Xith3D project to be able to override the bootclasspath on Mac Os X. For the time being, Amos has started a little framework to start his digibots school project. You can download the jar and will find the "oneclick" source included: http://mk3d.free.fr/digibots/

Maybe we should join forces and make this framework a generic solution for this kind of webstart and single-jar deployment.

cylab.

Mathias - I Know What [you] Did Last Summer!
Offline Amos Wenger

Senior Member




Everything's possible, but not everything's fun...


« Reply #7 - Posted 2007-03-14 17:17:37 »

We will do something similar in the Xith3D project to be able to override the bootclasspath on Mac Os X. For the time being, Amos has started a little framework to start his digibots school project. You can download the jar and will find the "oneclick" source included: http://mk3d.free.fr/digibots/

Maybe we should join forces and make this framework a generic solution for this kind of webstart and single-jar deployment.
Yeah, exactly.

Runtime.exec() doesn't care about the extension of the executables. I mean, if you give it a ".exe" file, then fine. But if you just give it "java", on windows it'll find "java.exe" (and maybe others, java.lnk, java.pif, java.bat, who knows ?) and I guess on mac it'll find the right file Smiley

At least in OneClick I do just java.home + "java" and it works perfectly on Linux + Windows.

(NOTE : In the current OneClick version, you will find sometimes that Digibots (which is the only example I have, so far) doesn't launch until you kill the "javaw.exe" process and leave the "java.exe" exe running. This will be fixed soon and is not related to the "java"/"java.exe" issue).

"Once you start working on something, don't be afraid of failure and don't abandon it. People who work sincerely are the happiest"
Offline CommanderKeith
« Reply #8 - Posted 2007-03-15 23:13:09 »

Thanks for the help everyone.  About java vs java.exe I didn't know it would work but yes you're right, it does!  Cool

So this code appears to work for me (on Windows, java1.6):

      String javaExeName = "java";
      File myJarFile = new File("E:/JavaFiles/STG/dist/STG.jar");
      String fileSeparator = System.getProperty("file.separator");
      String jreJavaFileName = System.getProperty("java.home") + fileSeparator + "bin" + fileSeparator + javaExeName;// +" ";
      String jarOption = "-jar";//+" ";
      String classPathOption = "-classpath";
      ArrayList<String> commands = new ArrayList<String>();
      commands.add(jreJavaFileName);
      commands.add(jarOption);
      commands.add(myJarFile.getAbsolutePath());

      System.out.println("About to launch new VM with the following commands:");
      for (String aCommand : commands){
         System.out.print(aCommand);
         if (commands.indexOf(aCommand) != commands.size()-1){
            System.out.print(" ");
         }
      }
      System.out.println();

      try{
         ProcessBuilder processBuilder = new ProcessBuilder(commands);
         Process process = processBuilder.start();
      }catch(IOException ex){
         ex.printStackTrace();
      }

Now my plan is to use WebStart to launch the program, then restart my app from there.  Webstart caches the jar in all different inaccessible spots (which are different depending on the VM). I think the best solution to get my jar files on the user's system is to bundle the jar as a resource in the webstart-downloaded jar file then use:

InputStream in = Main.class.getResourceAsStream("jarDirectory/myJarFile.jar");
And then write the bytes to a file on the user's hard drive, labelling that file myJarFile.jar.  That way I get WebStart functionality (like auto-update etc) and my app can start itself without the security-shackled webstart classsloader.  The only disadvantage is that I have to wait for 2 VM's to load before my app starts.

Good idea or do have you a better one??

Thanks,
Keith

Offline TheAnalogKid

JGO Coder


Projects: 2



« Reply #9 - Posted 2007-03-16 20:59:03 »

Migrate to Slick!  Grin

You're probably not happy with that answer but it solves a lot of webstart issues since it isn't based on Java 2D. Or you can switch to Java 6 and choose not supporting previous versions of Java, which is not really a good idea if you want to run your game anywhere.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline CommanderKeith
« Reply #10 - Posted 2007-03-17 06:25:10 »

Good news!  I think i've got it working, test it out here (it launches the BeanShell front-end app I've been working on):     http://www.freewebs.com/commanderkeith/SlaveBot/SlaveBot.jnlp

I'd really appreciate it if people could try it out and let me know if it works (that is, that it starts at all and that after clicking 'run' the program automatically types 'Hello World'). 

Maybe we should join forces and make this framework a generic solution for this kind of webstart and single-jar deployment.
Yeah, exactly.

I'd love some help improving this relaunching code, feel free to suggest imnprovements to the source.  By the way I couldn't get the Digibot program to work, probably that problem you mentioned.

Migrate to Slick!  Grin

You're probably not happy with that answer but it solves a lot of webstart issues since it isn't based on Java 2D. Or you can switch to Java 6 and choose not supporting previous versions of Java, which is not really a good idea if you want to run your game anywhere.
Yeah the Slick games are really impressive.  I just don't know enough about OGL and all the associated troubles there are with drivers etc.

Thanks,
Keith

PS: 2 problems with the code at the moment are:
1. The jar files are re-written on every invocation of the program.  I do this since I want the jars to be up to date if the webstart jar was re-downloaded.  Maybe there's a more clever way to do it?
2. The jar files are written to the user.home directory and there's no fail-over if that directory is off-limits for whatever reason.

To use it, just dump your app's jars in the same directory as wherever you put this class, then change the relevant parameters in the main method.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
package wrapper;

import java.io.*;
import java.util.*;
import java.net.*;

/**
 *
 * @author woodwardk
 */

public class Main {
   
   ArrayList<String> jarList = new ArrayList<String>();
   File jarDirectory;
   
   static final String fileSeparator = System.getProperty("file.separator");
   
   /** Creates a new instance of Main */
   public Main(File jarDirectory, ArrayList<String> jarList) {
      this.jarList = jarList;
      this.jarDirectory = jarDirectory;
   }
   
   public File buildJars() throws IOException{
      /*if (jarDirectory.isDirectory() == false){
         throw new IllegalArgumentException(jarDirectory.getAbsolutePath() + " doesn't exist!");
      }*/

      File mainJarFile = null;
      for (String jarName : jarList){
         // replace any '/' characters with the system's file separator.
        // need to use quoteReplacement or else the windows '\' character behaves wierdly with replaceAll().
        jarName = jarName.replaceAll("/", java.util.regex.Matcher.quoteReplacement(fileSeparator));
         String jarFilePath = jarDirectory.getAbsolutePath()+fileSeparator+jarName;
         File jarFile = new File(jarFilePath);
         System.out.println(jarFilePath);
         // save the file if its not already on the system
        if (jarFile.isFile() == false){
            jarFile.getParentFile().mkdirs();
            jarFile.createNewFile();
         }
         
         // now have to switch the fileSearator back to the java-style '/'    grrr....
        jarName = jarName.replaceAll(java.util.regex.Matcher.quoteReplacement(fileSeparator), "/");
         InputStream in = this.getClass().getResourceAsStream(jarName);
         if (in == null){
            throw new IllegalArgumentException(jarName + " wasn't found!");
         }
         BufferedInputStream bin = new BufferedInputStream(in);
         byte[] bytes = new byte[bin.available()];
         bin.read(bytes);
         bin.close();
         BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(jarFile));
         bout.write(bytes);
         bout.flush();
         bout.close();
         if (jarList.indexOf(jarName) == 0){
            mainJarFile = jarFile;
         }
         
      }
      return mainJarFile;
   }
   
   
   public void relaunchVM(File mainJarFile) throws IOException{
      String javaExeName = "java";
      File myJarFile = mainJarFile;
      String jreJavaFilePath = System.getProperty("java.home") + fileSeparator + "bin" + fileSeparator + javaExeName;// +" ";
     String jarOption = "-jar";//+" ";
     //String classPathOption = "-classpath "+myJarFile.getParent() + fileSeparator;   // don't need to specify classpath
     ArrayList<String> commands = new ArrayList<String>();
      commands.add(jreJavaFilePath);
      commands.add(jarOption);
      commands.add(myJarFile.getAbsolutePath());
     
      System.out.println("About to launch new VM with the following commands:");
      for (String aCommand : commands){
         System.out.print(aCommand);
         if (commands.indexOf(aCommand) != commands.size()-1){
            System.out.print(" ");
         }
      }
      System.out.println();
     
      ProcessBuilder processBuilder = new ProcessBuilder(commands);
      Process process = processBuilder.start();
     
   }
   
   /**
    * @param args the command line arguments
    */

   public static void main(String[] args) {
     
      ArrayList<String> jarList = new ArrayList<String>();
      jarList.add("SlaveBot.jar");   // the first one should contain the main-class.
     jarList.add("lib/bsh-2.0b4.jar");
      jarList.add("lib/jnlp.jar");
      jarList.add("lib/substance.jar");
      File jarDirectory = new File(System.getProperty("user.home")+"/SlaveBot");
      Main main = new Main(jarDirectory, jarList);
      try{
         File mainJarFile = main.buildJars();
         main.relaunchVM(mainJarFile);
      }catch(IOException e){
         e.printStackTrace();
      }
      System.exit(0);
   }
   
}

Offline Kova

Senior Member





« Reply #11 - Posted 2007-03-17 10:13:39 »

it works here... winXP, jre6
Although downloading was extreamly slow and stalled 2 times.

Very nice GUI, how did you make it?
Offline CommanderKeith
« Reply #12 - Posted 2007-03-17 12:10:15 »

Thanks!   Smiley i just made a custom skin using Kirill's Substance look and feel: https://substance.dev.java.net/

The program download is only 1.8m but freewebs sucks as a host.

If anyone with a mac or linux box would let me know if it works that'd be great.

Thanks,
Keith

Offline TheAnalogKid

JGO Coder


Projects: 2



« Reply #13 - Posted 2007-03-17 16:59:20 »

The beauty with Slick is that you don't have to know OGL actually! And the API is really straight forward. About the drivers, I don't think it's much an issue now.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Riven (7 views)
2014-07-29 18:09:19

Riven (5 views)
2014-07-29 18:08:52

Dwinin (8 views)
2014-07-29 10:59:34

E.R. Fleming (25 views)
2014-07-29 03:07:13

E.R. Fleming (10 views)
2014-07-29 03:06:25

pw (39 views)
2014-07-24 01:59:36

Riven (39 views)
2014-07-23 21:16:32

Riven (26 views)
2014-07-23 21:07:15

Riven (28 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!