Runtime jar loading

Started by smith, February 27, 2011, 01:40:55

Previous topic - Next topic

smith

Is it possible to load and jars into lwjgl's AppletLoader cache after the applet has started?

Say I have a game that is several hundred megabytes with each level in a jar file that are only a few megabytes each. I only want to download (and cache) each level as the previous one is completed so you don't have to wait for the whole thing to download before starting the game?

Is this possible with lwjgl?

kappa

After the AppletLoader is done downloading the jars and switches over to your applet then its pretty much done doing its work. So no its not possible using the AppletLoader as it is now nor is it possible atm for the loaded applet to access code/methods of the AppletLoader but that doesn't mean its not possible.

Once your applet starts you can do pretty much what you like (including downloading more jars). So yeh you can download jars into the AppletLoader directory and cache but I wouldn't recommend that since the directory or caching style can change between different versions of LWJGL. Instead its a better idea that you should create your own directory somewhere on the computer and download further stuff there. You can easily rip out the bits of code you need from the AppletLoader (like downloading code) and put it in the loaded applet.

smith

I should also point out I would like to keep the applet unsigned. These days people are allot more likely to have accepted the lwjgl certificate already and so probably won't have to see a scary security dialog.

kappa

hmm, you've raised an interesting problem, one that I've also liked to solve a few times (download jars later, i.e. the game in bits). So you could for example have a full Quake like game (over 200mb) where levels/resources are downloaded only as they are needed like at the start of each mission.

Maybe we could put the AppletLoader on the classpath so that you are given access to its API which could allow downloading further files. Not an impossible problem but guess will have to think about it further.

Anyone got idea's how this could be handled?

Matthias

The applet loader needs to implement an interface which is also accessible to the application class loader. Then the applet loader can inject this interface via a 2nd interface implemented by the user applet:

interface AppletLoaderAPI {
   public ClassLoader loadJARs(URL[] url);
}

interface KnowsAboutAppletLoader {
   public void setAppletLoaderAPI(AppletLoaderAPI api);
}

jediTofu

Personally, I don't think that this should be added to the applet code; it isn't really related (since this is downloading after the applet is loaded), and then there will just be more and more things piled on top of the applet code, when it'd be better to just keep it simple and maintain it's original design/function.

Just create a ".myapplication" (or without a dot) folder or something else in the home folder.  A lot of applets do this on both Windows and Linux.  Then just download the files using Java's URL class.  The only problem that may arise is setting a proxy, as you'll have to ask the user to enter that information in.  However, this has two advantages over being inside the applet code.  (1)  You have more control and can resume download (reconnect) if it times out in 10 seconds or so.  If it is a large amount of data with a slower internet connection, it will most likely need to be resumed some time.  (2) If it is stored in the home folder and not the applet cache, when you make updates (bug fixes, etc.) to the core Jar, it won't need to re-download all of the level data, just the core Jar.  Also, if there is a change to 1 level, you could do a check over the data and just re-download/update that 1 level.  This could be difficult to implement in the applet code as it's program specific.

Granted, (1) & (2) can be implemented, but in my opinion, it will be difficult and require a lot of code.  I'd rather LWJGL focus on maintaining and improving the core LWJGL/jnlp/applet code, instead of dealing with tons of user-specific extensions, but again, just my opinion :)
cool story, bro

arielsan

Maybe LWJGL could provide a signed jar (separated from applet loader and others) with utilities like "downloadJar" or things like that, to be used by anyone.

smith

A sand-boxed AppletToolkit class that had methods for downloading/caching jar's into the AppletLoader cache would be a great addition to the AppletUtils package.


CodeBunny

It'd be useful, certainly, but such functionality would go beyond just Applets and work for games in general. One possibility that comes to mind is using it for easy patch capabilities - check for additional levels/content/whatever, and download them using the pre-built methods or what have you.

However, all of this could be accomplished with regular Java, so I don't know why it would have to be LWJGL in particular. It seems like it would make more sense as another, standalone package - that way people not using LWJGL could still get use out of it, and if someone uses LWJGL but isn't interested, they needn't bother.

bobjob

Currently In my applet loader I do a few things along this line. Because I needed to access the perant Applet as Mozilla couldnt save cookies otherwise. And I take multiple lists of jars from the applet paramaters.

The problem is the applet loader will need a bit of a make over.

1. you can access the AppletLoader via getAppletContext().getApplets() from the child applet by cycling through the elements, until it was a instanceof Applet (maybe compare the name that is set in HTML, but I havnt used this in a while so I forgot the exact details).

2. In order to take multiple lists of jars I split the AppletLoader class into two by making a PackageLoader class (that stores the array list) that is seperate to the actual AppletLoader class, and creates an instace to load the jars then add it to the classloader object at the end.

3. I havnt tried this, but a logical way to add a list of jars at runtime from the client applet would be roughly something like:

i. get the perant applet class and call a overriden method in the perant applet (eg. getPerameter(String)) so that if the string startsWith "lwjgl_status: " or "lwjgl_loadjar: " then it means that it will be used for LWJGL to load a new jar at runtime. Otherwise the method should naturally call perant.getPerameter(String)).

ii. The method should create a new instance of PackageLoader that gets placed in its own Thread or queue if a jar is already loading.

iii. The overriden method should return a "String" detailing the PackageLoader progress if "lwjgl_status: <jar name>" is passed to it.

But like I said the AppletLoader would need a big make over, from memory i had a few issues that needed to be fixed list a static vector object to keep track of loaded natives in each native jar that would load if seperate_jvm wasnt used in HTML.

smith

QuoteHowever, all of this could be accomplished with regular Java, so I don't know why it would have to be LWJGL in particular. It seems like it would make more sense as another, standalone package - that way people not using LWJGL could still get use out of it, and if someone uses LWJGL but isn't interested, they needn't bother.

Presently LWJGL has a big enough install base that you can deploy a full browser based 3D game without having to present any scary security dialogs to a user. Using a lib signed with a cert other than the LWJGL one means you just lost this ability and it is a huge deal for getting people to try your stuff.