java web start and clojure application

Visto 129 veces
Saltar al primer mensaje no leído

Pawel Ostrowski

no leída,
22 abr 2008, 9:44:2722/4/08
a 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

no leída,
22 abr 2008, 12:44:2422/4/08
a 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

no leída,
22 abr 2008, 19:58:2422/4/08
a Clojure
Works here too! Excellent.

Jason Zwolak

no leída,
3 oct 2015, 19:30:293/10/15
a 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

no leída,
15 feb 2016, 12:48:4515/2/16
a 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:
Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos