From a54b0bf6a30c3728f4dd7b5678e50be1d2539cf0 Mon Sep 17 00:00:00 2001 From: Kevin Downey Date: Mon, 19 Sep 2016 12:30:00 -0700 Subject: [PATCH 1/3] launching a clojure program, refs #140 --- content/guides/faq.adoc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/content/guides/faq.adoc b/content/guides/faq.adoc index c786120a..9c8cfb20 100644 --- a/content/guides/faq.adoc +++ b/content/guides/faq.adoc @@ -193,3 +193,25 @@ Because of its focus on immutable data, there is generally not a high value plac All Clojure vars are globally available so again there is not much in the way of encapsulation of functions within namespaces. However, the ability to mark vars private (either using `defn-` for functions or `def` with `^:private` for values) is a convenience for a developer to indicate which parts of an API should be considered public for use vs part of the implementation. +== Care and Feeding of a Clojure program + +[[launch]] +**<>** + +There are two important pieces of information that need to be conveyed to the JVM when launching a Clojure program: + + 1. Where to find the code. + 2. Where is the main entry point in the code. + +#1 usually comes down to setting what is called the "classpath". The classpath is the default way that the JVM finds code. You can setup the classpath using the `-jar` or `-cp` flags on the `java` command. The `-cp` flag takes a list of jars (or directories) separated by ':' on Unix or ';' on Windows. The `-jar` flag takes a single jarfile, and makes some assumptions about where the entry point for the code is. The `-cp` and the `-jar` flags are mutually exclusive. Which flag you use is often driven by the type of artifacts your build system produces. A common type of artifact to build is an uberjar. An uberjar is a jar that contains all of your code and its dependencies. Because an uberjar is a single jar file, they are often used with the `-jar` flag. + +As for #2, telling the JVM where the main entry point for your code is, that can be tricky becuase the JVM is expecting a main entry point in some classfile, but we are working in terms of Clojure code. You need a classfile to bootstrap from JVM land in to Clojure. Clojure has its own class it uses for bootstrapping, which you can use too. The name of this class is 'clojure.main'. If you run `java -jar clojure.jar clojure.main` a Clojure repl will be launched, and clojure.main is the class that does that. `java -jar clojure.jar clojure.main --help` will list all the command line flags that clojure.main takes. + The most useful for launching a Clojure program is `-m`. `-m` takes either a var name like `foo.bar/baz` or just a namespace name like `foo.bar`. When given just a namespace name, it will look the for `-main` function in that namespace. When given the `-m` option clojure.main will load and invoke your code, launching your program. + +That means, assuming you get an uberjar named `my-project.jar` and have a main function named `my.project/-main`, you can launch your Clojure program like `java -jar my-project.jar clojure.main -m my.project`. + +But, when using the `-jar` flag, you don't always need to specify which class is your main class. Jar files can contain a manifest and that manifest can specify what the main class is. How this is setup is dependant largely on your build tooling. The jar file containing clojure specifies clojure.main as its main class so `java -jar clojure.jar` will run clojure.main which starts a repl, without you having to specify clojure.main should be run at the command line. Some build tools (like Leiningen) will default to making clojure.main the main class if you don't specify one. + +If you have clojure.main specified as your main class in your uberjar, you can launch your Clojure program like `java -jar my-project.jar -m my.project`. + +You can also create your own main class, either by writing a stub in Java or AOT compiling some or all of your Clojure program, and use that as the main class for your Clojure program. From e52d6af2dd4b327eb04217672dae201720dcf633 Mon Sep 17 00:00:00 2001 From: Kevin Downey Date: Wed, 21 Sep 2016 11:02:09 -0700 Subject: [PATCH 2/3] remove incorrect information --- content/guides/faq.adoc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/content/guides/faq.adoc b/content/guides/faq.adoc index 9c8cfb20..83027f94 100644 --- a/content/guides/faq.adoc +++ b/content/guides/faq.adoc @@ -206,9 +206,7 @@ There are two important pieces of information that need to be conveyed to the JV #1 usually comes down to setting what is called the "classpath". The classpath is the default way that the JVM finds code. You can setup the classpath using the `-jar` or `-cp` flags on the `java` command. The `-cp` flag takes a list of jars (or directories) separated by ':' on Unix or ';' on Windows. The `-jar` flag takes a single jarfile, and makes some assumptions about where the entry point for the code is. The `-cp` and the `-jar` flags are mutually exclusive. Which flag you use is often driven by the type of artifacts your build system produces. A common type of artifact to build is an uberjar. An uberjar is a jar that contains all of your code and its dependencies. Because an uberjar is a single jar file, they are often used with the `-jar` flag. As for #2, telling the JVM where the main entry point for your code is, that can be tricky becuase the JVM is expecting a main entry point in some classfile, but we are working in terms of Clojure code. You need a classfile to bootstrap from JVM land in to Clojure. Clojure has its own class it uses for bootstrapping, which you can use too. The name of this class is 'clojure.main'. If you run `java -jar clojure.jar clojure.main` a Clojure repl will be launched, and clojure.main is the class that does that. `java -jar clojure.jar clojure.main --help` will list all the command line flags that clojure.main takes. - The most useful for launching a Clojure program is `-m`. `-m` takes either a var name like `foo.bar/baz` or just a namespace name like `foo.bar`. When given just a namespace name, it will look the for `-main` function in that namespace. When given the `-m` option clojure.main will load and invoke your code, launching your program. - -That means, assuming you get an uberjar named `my-project.jar` and have a main function named `my.project/-main`, you can launch your Clojure program like `java -jar my-project.jar clojure.main -m my.project`. + The most useful for launching a Clojure program is `-m`. The `-m` flag takes a namespace like `foo.bar`, and causes clojure.main to load that namespace and apply the function named `-main` to the rest of the command line arguments. But, when using the `-jar` flag, you don't always need to specify which class is your main class. Jar files can contain a manifest and that manifest can specify what the main class is. How this is setup is dependant largely on your build tooling. The jar file containing clojure specifies clojure.main as its main class so `java -jar clojure.jar` will run clojure.main which starts a repl, without you having to specify clojure.main should be run at the command line. Some build tools (like Leiningen) will default to making clojure.main the main class if you don't specify one. From df56aef005d5d867213a51c2d3bbec5a86b0acad Mon Sep 17 00:00:00 2001 From: Kevin Downey Date: Wed, 21 Sep 2016 11:12:44 -0700 Subject: [PATCH 3/3] move running a clojure program info out of the faq --- content/guides/faq.adoc | 21 ------------ content/guides/running_a_clojure_program.adoc | 34 +++++++++++++++++++ 2 files changed, 34 insertions(+), 21 deletions(-) create mode 100644 content/guides/running_a_clojure_program.adoc diff --git a/content/guides/faq.adoc b/content/guides/faq.adoc index 83027f94..5618a997 100644 --- a/content/guides/faq.adoc +++ b/content/guides/faq.adoc @@ -192,24 +192,3 @@ Example: Because of its focus on immutable data, there is generally not a high value placed on data encapsulation. Because data is immutable, there is no need to worry about someone else modifying a value. Likewise, because Clojure data is designed to be manipulated directly, there is significant value in providing direct access to data, rather than wrapping it in APIs. All Clojure vars are globally available so again there is not much in the way of encapsulation of functions within namespaces. However, the ability to mark vars private (either using `defn-` for functions or `def` with `^:private` for values) is a convenience for a developer to indicate which parts of an API should be considered public for use vs part of the implementation. - -== Care and Feeding of a Clojure program - -[[launch]] -**<>** - -There are two important pieces of information that need to be conveyed to the JVM when launching a Clojure program: - - 1. Where to find the code. - 2. Where is the main entry point in the code. - -#1 usually comes down to setting what is called the "classpath". The classpath is the default way that the JVM finds code. You can setup the classpath using the `-jar` or `-cp` flags on the `java` command. The `-cp` flag takes a list of jars (or directories) separated by ':' on Unix or ';' on Windows. The `-jar` flag takes a single jarfile, and makes some assumptions about where the entry point for the code is. The `-cp` and the `-jar` flags are mutually exclusive. Which flag you use is often driven by the type of artifacts your build system produces. A common type of artifact to build is an uberjar. An uberjar is a jar that contains all of your code and its dependencies. Because an uberjar is a single jar file, they are often used with the `-jar` flag. - -As for #2, telling the JVM where the main entry point for your code is, that can be tricky becuase the JVM is expecting a main entry point in some classfile, but we are working in terms of Clojure code. You need a classfile to bootstrap from JVM land in to Clojure. Clojure has its own class it uses for bootstrapping, which you can use too. The name of this class is 'clojure.main'. If you run `java -jar clojure.jar clojure.main` a Clojure repl will be launched, and clojure.main is the class that does that. `java -jar clojure.jar clojure.main --help` will list all the command line flags that clojure.main takes. - The most useful for launching a Clojure program is `-m`. The `-m` flag takes a namespace like `foo.bar`, and causes clojure.main to load that namespace and apply the function named `-main` to the rest of the command line arguments. - -But, when using the `-jar` flag, you don't always need to specify which class is your main class. Jar files can contain a manifest and that manifest can specify what the main class is. How this is setup is dependant largely on your build tooling. The jar file containing clojure specifies clojure.main as its main class so `java -jar clojure.jar` will run clojure.main which starts a repl, without you having to specify clojure.main should be run at the command line. Some build tools (like Leiningen) will default to making clojure.main the main class if you don't specify one. - -If you have clojure.main specified as your main class in your uberjar, you can launch your Clojure program like `java -jar my-project.jar -m my.project`. - -You can also create your own main class, either by writing a stub in Java or AOT compiling some or all of your Clojure program, and use that as the main class for your Clojure program. diff --git a/content/guides/running_a_clojure_program.adoc b/content/guides/running_a_clojure_program.adoc new file mode 100644 index 00000000..613f2ec9 --- /dev/null +++ b/content/guides/running_a_clojure_program.adoc @@ -0,0 +1,34 @@ += Running a Clojure Program +Kevin Downey +2016-09-21 +:type: guides +:toc: macro +:icons: font + +ifdef::env-github,env-browser[:outfilesuffix: .adoc] + +toc::[] + + +== How to Start + +// [[launch]] +// **<>** + +There are two important pieces of information that need to be conveyed to the JVM when launching a Clojure program: + + 1. Where to find the code. + 2. Where is the main entry point in the code. + +#1 usually comes down to setting what is called the "classpath". The classpath is the default way that the JVM finds code. You can setup the classpath using the `-jar` or `-cp` flags on the `java` command. The `-cp` flag takes a list of jars (or directories) separated by ':' on Unix or ';' on Windows. The `-jar` flag takes a single jarfile, and makes some assumptions about where the entry point for the code is. The `-cp` and the `-jar` flags are mutually exclusive. Which flag you use is often driven by the type of artifacts your build system produces. A common type of artifact to build is an uberjar. An uberjar is a jar that contains all of your code and its dependencies. Because an uberjar is a single jar file, they are often used with the `-jar` flag. + +As for #2, telling the JVM where the main entry point for your code is, that can be tricky becuase the JVM is expecting a main entry point in some classfile, but we are working in terms of Clojure code. You need a classfile to bootstrap from JVM land in to Clojure. Clojure has its own class it uses for bootstrapping, which you can use too. The name of this class is 'clojure.main'. If you run `java -jar clojure.jar clojure.main` a Clojure repl will be launched, and clojure.main is the class that does that. `java -jar clojure.jar clojure.main --help` will list all the command line flags that clojure.main takes. + The most useful for launching a Clojure program is `-m`. The `-m` flag takes a namespace like `foo.bar`, and causes clojure.main to load that namespace and apply the function named `-main` to the rest of the command line arguments. + +But, when using the `-jar` flag, you don't always need to specify which class is your main class. Jar files can contain a manifest and that manifest can specify what the main class is. How this is setup is dependant largely on your build tooling. The jar file containing clojure specifies clojure.main as its main class so `java -jar clojure.jar` will run clojure.main which starts a repl, without you having to specify clojure.main should be run at the command line. Some build tools (like Leiningen) will default to making clojure.main the main class if you don't specify one. + +If you have clojure.main specified as your main class in your uberjar, you can launch your Clojure program like `java -jar my-project.jar -m my.project`. + +You can also create your own main class, either by writing a stub in Java or AOT compiling some or all of your Clojure program, and use that as the main class for your Clojure program. + +If you don't have an uberjar `java -cp $CP clojure.main -m foo.bar`, where $CP is a ';' or ':' seperated list of jars will launch your program. If you don't have a jar at all, and your clojure source code lives in a directory named `src` then `java -cp clojure.jar:src clojure.main -m foo.bar` will run your program.