java web start and clojure application

129 views
Skip to first unread message

Pawel Ostrowski

unread,
Apr 22, 2008, 9:44:27 AM4/22/08
to Clojure
Hello,

I managed to successfully deploy simple clojure application with java
web start. I will share my experience here, because I had some
problems with granting enough security privileges to run clojure
application as java web start applet (getting AccessControlException)
and I did not find complete solution in group's archive. Editing
java.policy file was not an option because I wanted to share my
application with users who might not understand java policies at all.

My application is written entirely in clojure except one java class
with static main method. This main method looks like this:

public static void main(String[] args) throws Exception {
RT.init();
// load clj resource
loadFromClasspath("alphabet/alphabet.clj");
// get clojure fun
StringReader sr = new StringReader("clojure-main");
PushbackReader r = new PushbackReader(sr);
IFn clojureFun = (IFn) Compiler.eval(LispReader.read(r, false,
null, false));
// call clojure fun
clojureFun.invoke();
...

So all I do here is: load clojure source file, get clojure main
function and then call it.

To run it as java web start applet I had to:

1) Include <security><all-permissions/></security> element in
my .jnlp file.
2) Sign clojure.jar and my application .jar files. Instructions found
on http://www.dallaway.com/acad/webstart/ were helpful
3) Put the following code in static section in class with the static
main method:

static {
Policy.setPolicy( new Policy() {
public PermissionCollection
getPermissions(CodeSource codesource) {
Permissions perms = new Permissions();
perms.add(new AllPermission());
return(perms);
}
public void refresh(){
}
});
}

Third step was necessary because all permissions from first step were
granted to javaws classloader only and clojure creates it's own
classloaders, at least I think so :).

ps. This is a simple alphabet typing swing application, it measures
your time to type whole alphabet. Time starts with typing letter a and
ends with letter z. Space resets the game. It may be run with javaws
from here: http://www.pasza.org/files/alphabet/alphabet.jnlp

clojure code may be found in this jar: http://www.pasza.org/files/alphabet/alphabet.jar

jon

unread,
Apr 22, 2008, 12:44:24 PM4/22/08
to Clojure
Works great here!
Thanks for this effort.. solves an obvious need.

ps. when trying this out, watch out you don't have caps lock on..
doh :)

jonathan...@gmail.com

unread,
Apr 22, 2008, 7:58:24 PM4/22/08
to Clojure
Works here too! Excellent.

Jason Zwolak

unread,
Oct 3, 2015, 7:30:29 PM10/3/15
to Clojure, pawel.o...@gmail.com
Fantastic!  Thanks for reporting this.  Your work helped me get my application working with Clojure code in a webstart environment.

I do have a question about security in relation to step 3 where the Policy is set.  Is this the strictest policy that will work with Clojure code compiled at runtime?  Does this policy leave an application open to security problems?  My interpretation of step 3 is that all class loaders now have all-privileges.  This could be a problem if some third party jar, which my have been compromised or contain malicious code, creates its own class loader and loads arbitrary code from a server.  All this code would then have all permissions where it wouldn't have them without step 3.  Is my assessment correct?

Thanks,
Jason

Jason Zwolak

unread,
Feb 15, 2016, 12:48:45 PM2/15/16
to Clojure, pawel.o...@gmail.com
I'd also like to point out for the record, since I ran into this problem, that the policy related static code must appear before any requires in the Java code that loads the application specific functions; like the "clojure-main" in the OPs example.

I believe a more modern load of the application Clojure code would look like this (before the setPolicy):

    public static final IFn require = Clojure.var("clojure.core", "require");
    static {
        require.invoke(Clojure.read("clojure-main"));
    }

After setPolicy code, it would look like this:

    public static final IFn require = Clojure.var("clojure.core", "require");
    static {
        Policy.setPolicy( new Policy() { 
            public PermissionCollection 
            getPermissions(CodeSource codesource) { 
                Permissions perms = new Permissions(); 
                perms.add(new AllPermission()); 
                return(perms); 
            } 
            public void refresh(){ 
            } 
        }); 
        require.invoke(Clojure.read("clojure-main"));
    }


On Tuesday, April 22, 2008 at 9:44:27 AM UTC-4, Pawel Ostrowski wrote:
Reply all
Reply to author
Forward
0 new messages