packaging App (cross-platform) without scripts, only jar

27 views
Skip to first unread message

Pascal

unread,
Sep 20, 2008, 10:17:17 AM9/20/08
to Clojure
I needed a single jar file that if you double clicked
on it (be in Mac OS X or Windows) it will just launch
my Clojure App.

No CLASSPATH or bash or anything, cross platform.

I didn't found anything like these so I just made it
(I know it's not difficult, let say this is for Newbie!)

The archi is:
- one App on directory: Let say Blop/
- inside one jar: Launcher.jar (double click to start)
- and 2 directories:
- clj/ : with your clojure sources, the entry point must be
named: main.clj
- jar/ : with your needed jar, including: clojure.jar

Look for the "Launcher.jar" file in this Google group.
Here is the source:
(note: Inspired freely from clojure.lang.Script java class)
------------------------------------------------------------

import java.io.OutputStreamWriter;
import java.io.IOException;

import clojure.lang.RT;
import clojure.lang.Compiler;


public class Launcher {
public static void main(String[] args) throws Exception {
try {
RT.processCommandLine(args); // must do that...
Compiler.loadFile("clj/main.clj");

} finally {
OutputStreamWriter w = (OutputStreamWriter) RT.OUT.get();
try {
w.flush();
w.close();
} catch(IOException e) {
e.printStackTrace();
}
} // try
} // main
}
------------------------------------------------------------
The Manifest must add:

Main-Class: Launcher
Class-Path: jar/clojure.jar

------------------------------------------------------------

As an example I zipped the "Ant" example from Rich Hickey
(only made small modification at the end so that it start right away),
with the lastest (20080916) Clojure.jar .
Look for the "Ant_App.zip" file in this Google group.

Am I re-inventing the wheel ?
Brgds.

budu

unread,
Sep 20, 2008, 11:23:28 AM9/20/08
to Clojure
Thanks a lot! It's funny that you wrote this post now because I was
about to try to figure it out myself this week-end.

akopa

unread,
Oct 1, 2008, 2:12:05 PM10/1/08
to Clojure


On Sep 20, 9:17 am, Pascal <pascal.droui...@gmail.com> wrote:
> I needed a single jar file that if you double clicked
> on it (be in Mac OS X or Windows) it will just launch
> my Clojure App.
>
...
>
> As an example I zipped the "Ant" example from Rich Hickey
> (only made small modification at the end so that it start right away),
> with the lastest (20080916) Clojure.jar .
> Look for the "Ant_App.zip" file in this Google group.
>

In Windows XP, when I unzip Ant_App.zip and double click on
Launcher.jar nothing happens.

I have a 1.6.x jdk and jre installed, are there any special setting I
need?

Matt

Michael Beauregard

unread,
Oct 1, 2008, 2:25:50 PM10/1/08
to clo...@googlegroups.com
Is there a reason why setting the "Main-Class" field in the jar's manifest doesn't work. I'm surprised that any code has to be written at all for this work.

http://java.sun.com/developer/Books/javaprogramming/JAR/basics/manifest.html#applications

I've used this before and I think that the launcher (in Windows at least) would execute: java -jar %f

I haven't used Windows in a long time so I'm not sure if this still works. Anyway, I may be out to lunch on what you guys are trying to do.

Michael

akopa

unread,
Oct 1, 2008, 3:01:52 PM10/1/08
to Clojure


On Oct 1, 1:12 pm, akopa <akopa.gmane.pos...@gmail.com> wrote:
...
> In Windows XP, when I unzip Ant_App.zip and double click on
> Launcher.jar nothing happens.
>
> I have a 1.6.x jdk and jre installed, are there any special setting I
> need?
>

The problem "magically" went away. hmmm.

Matt

Stuart Sierra

unread,
Oct 1, 2008, 11:15:25 PM10/1/08
to Clojure
On Oct 1, 3:01 pm, akopa <akopa.gmane.pos...@gmail.com> wrote:
> > In Windows XP, when I unzip Ant_App.zip and double click on
> > Launcher.jar nothing happens.
>
> The problem "magically" went away. hmmm.

Sometimes the JRE takes a long time to start up on Windows...
-Stuart

Pascal

unread,
Oct 2, 2008, 10:23:01 AM10/2/08
to Clojure
Hi all,

for Michael Beauregard,
> Is there a reason why setting the "Main-Class" field in the jar's manifest
> doesn't work.

It work, and since the manifest had to be edited to set the Class-Path
why not set correctly the Main-Class ? maybe if my main class would
be called "Main" instead of "Launcher" it will be automatic.
But still, the Class-Path is needed so I changed the manifest.

> I'm surprised that any code has to be written at all for this work.
> ...
> I've used this before and I think that the launcher (in Windows at least)
> would execute: java -jar %f

Exactly and it work! but to be able to click on a "jar"
you must *have* a jar, something that was not by default in Clojure
since you cannot compile ahead into a jar.

For akopa:
>> In Windows XP, when I unzip Ant_App.zip and double click on
>> Launcher.jar nothing happens.

random Msft windows things...
It work on my WindowsXP...

>> ... are there any special setting I need?
nothing.

>> The problem "magically" went away. hmmm.
ha.

Brgds,

Asbjørn Bjørnstad

unread,
Oct 14, 2008, 1:04:34 PM10/14/08
to Clojure


On Oct 2, 10:23 pm, Pascal <pascal.droui...@gmail.com> wrote:
> Hi all,
>
> for Michael Beauregard,
>
> > Is there a reason why setting the "Main-Class" field in the jar's manifest
> > doesn't work.
>
> It work, and since the manifest had to be edited to set the Class-Path
> why not set correctly the Main-Class ? maybe if my main class would
> be called "Main" instead of "Launcher" it will be automatic.
> But still, the Class-Path is needed so I changed the manifest.
>
> > I'm surprised that any code has to be written at all for this work.
> > ...
> > I've used this before and I think that the launcher (in Windows at least)
> > would execute: java -jar %f
>
> Exactly and it work! but to be able to click on a "jar"
> you must *have* a jar, something that was not by default in Clojure
> since you cannot compile ahead into a jar.

So it is not possible to put the clj files into the jar so that no
unzipping
is neccessary? I tried, but my java/jar knowledge is basically zero.
--
-asbjxrn

R. P. Dillon

unread,
Oct 14, 2008, 4:57:19 PM10/14/08
to Clojure
I put together an quick tutorial of how I made an executable jar for
an example "Hello World" app in Clojure. Suggestions welcome.

http://rpdillon.googlepages.com/creatingexecutablejarswithclojure

Cheers,
Rick

red...@gmail.com

unread,
Oct 14, 2008, 5:12:24 PM10/14/08
to Clojure


On Oct 14, 10:04 am, Asbjørn Bjørnstad <asbj...@gmail.com> wrote:
>
[..snip..]
> So it is not possible to put the clj files into the jar so that no
> unzipping
> is neccessary? I tried, but my java/jar knowledge is basically zero.
> --
>  -asbjxrn

it is definitely possible. To make a jar that doesn't need clojure in
the classpath you need to unpack the clojure jar and repack those
files inside the new jar with your own clojure files.

I have a make-class.clj for a project using what I think maybe
deprecated syntax these days:

(in-ns 'TFC)
(clojure/refer 'clojure)
(load-file "/media/windows/clojure/src/genclass.clj")
(load-file "TFC.clj")
(clojure/gen-and-save-class (first *command-line-args*) 'TFC :main
true)

this makes a class file named TFC.class from the TFC namespace with a
"main" function. The "main" function in the TFC namespace looks like:
(defn main [& strings] ...)
dunno if the [& strings] is required, but it seems like the closest
clojure mapping to java's "main" method signature.

to build the standalone jar file:

1) run make-class.clj which gives me TFC.class from TFC.clj
2) extract clojure.jar into the same directory as TFC.class and
TFC.clj
3) create the jar file specifying "TFC" as the "application entry
point". the exact command line is:
jar cevf TFC tcp-flow.jar *

the resulting is tcp-flow.jar is standalone in the sense that it does
not need a separate clojure.jar in the classpath and all .clj files
are inside the jar
this is a very simple app so there is only one clojure source file. I
am not sure how this would work out with multiple files and such.

Asbjørn Bjørnstad

unread,
Oct 15, 2008, 10:39:33 AM10/15/08
to Clojure
Cool, thanks. That worked (http://jalat.com/static-files/
ChordLib.jar). Is it possible to have a subdirectory in the classpath
as well, or does everything have to be from the root? (Ie. Could
clojure have been in a subdirectory lib and classpath have been set to
". lib/"?)
I tried that but it seems like that was parsed to a pathname outside
of the jar.
--
-asbjxrn

R. P. Dillon

unread,
Oct 15, 2008, 12:19:41 PM10/15/08
to Clojure
> Cool, thanks. That worked (http://jalat.com/static-files/
> Is it possible to have a subdirectory in the classpath
> as well, or does everything have to be from the root? (Ie. Could
> clojure have been in a subdirectory lib and classpath have been set to
> ". lib/"?)
> I tried that but it seems like that was parsed to a pathname outside
> of the jar.

From what I've done with Executable jars, the classpath specified in
the manifest will tend to be the root (".").

As an aside, another way to approach this if you don't feel like
tearing apart clojure.jar is to create your own jar without clojure,
and specify a relative path to clojure.jar:

Project
|_YourJar.jar
|_lib
|_clojure.jar

and then you can put make your manifest in YourJar.jar say something
like:

Class-Path: .:lib/clojure.jar

Maybe someone else know if there is any other way to get the Class-
Path in a jar to point to a subdirectory of the jar -- I haven't seen
that.

-Rick

Zak Wilson

unread,
Oct 18, 2008, 4:04:05 PM10/18/08
to Clojure
When I try this, I get the following if I try to run the jar:

Exception in thread "main" java.lang.NoSuchMethodError:
clojure.lang.RT.loadResourceScript(Ljava/lang/Class;Ljava/lang/
String;Z)V

This is using the latest stable Clojure and a single source file.
Reply all
Reply to author
Forward
0 new messages