<commit_before>= boot-gae-example

A simple https://cloud.google.com/appengine/docs/java/[Google App
Engine] webapp, written in 100% https://clojure.org/[Clojure], built
with http://boot-clj.com/[Boot].

IMPORTANT: you do not need a GAE account to experiment!  The GAE SDK
contains everything you need to run webapps on the local devserver;
you only need a GAE account if you want to deploy to the production
servers.

[NOTE]
====
Use of App Engine services such as the Datastore is beyond the scope of
this example.  Its sole purpose is to demonstrate the how easy it is
to use https://github.com/migae/boot-gae[boot-gae] to get a Clojure
webapp up and running on GAE with a repl-like development environment.
====

== getting started

This project has not been pushed to clojars, so you'll need to
fork/clone it.  It uses https://github.com/migae/boot-gae[boot-gae],
which also has not yet been pushed to clojars, so you'll need to
fork/clone and install that too.

[source,shell]
----
$ git clone https://github.com/migae/boot-gae.git
$ cd boot-gae
$ boot pom jar install
$ cd ..
$ git clone https://github.com/migae/gae-hello-boot
$ cd gae-hello-boot
$ boot gae/install-sdk
$ boot prep
$ boot run
----

WARNING: The GAE java sdk is quite large, so don't be alarmed if `gae/install-sdk` takes a while to run.

To get a repl-like dev environment, open a second terminal and start a
watcher:

[source,shell]
----
$ cd gae-hello-boot
$ boot watch sift -i "clj$" target -d "build/WEB-INF/classes" -C
----

If you want live reloading of other resources, like css files, you'll
need to add another watcher and adjust the -d string of `target`
accordingly; for example:

[source,shell]
----
$ cd gae-hello-boot
$ boot watch sift -i "css$" target -d "build" -C
----

If you need to change the configuration, for example to add another
servlet, you'll have to restart the server.  First run `boot prep` to
reconfigure the webapp, then run `boot gae/run` again.

== troubleshooting

```
java.lang.NoClassDefFoundError: clojure/lang/Var
```

Check `<build-root>/WEB-INF/lib` to make sure your jars are there.
You probably did not run `gae/libs`.

== the code

The App Engine functions as a servlet container (it's actually a
modified version of Jetty).  Servlet containers look on disk for
compiled byte code when they need to load a servlet.  That means a
Clojure webapp must aot-compile a servlet; usually this is done using
`gen-class` in some form.
<commit_msg>fix README<commit_after>= hello-gae

A simple https://cloud.google.com/appengine/docs/java/[Google App
Engine] webapp, written in 100% https://clojure.org/[Clojure], built
with http://boot-clj.com/[Boot].

IMPORTANT: you do not need a GAE account to experiment!  The GAE SDK
contains everything you need to run webapps on the local devserver;
you only need a GAE account if you want to deploy to the production
servers.

[NOTE]
====
Use of App Engine services such as the Datastore is beyond the scope of
this example.  Its sole purpose is to demonstrate the how easy it is
to use https://github.com/migae/boot-gae[boot-gae] to get a Clojure
webapp up and running on GAE with a repl-like development environment.
====

== getting started

[source,shell]
----
$ git clone https://github.com/migae/boot-gae.git
$ cd boot-gae/tasklib
$ boot pom jar install
$ cd ../hello-gae
$ boot gae/build
$ boot gae/run
----

WARNING: The GAE java sdk is quite large, so don't be alarmed if
`gae/build` takes a while to run the first time.

To get a repl-like dev environment, open a second terminal and start a
watcher:

[source,shell]
----
$ boot gae/watch
----

If you need to change the configuration, for example to add another
servlet, you'll have to restart the server.  Rerun `boot gae/build` to
reconfigure the webapp, then run `boot gae/run` again.

== troubleshooting

```
java.lang.NoClassDefFoundError: clojure/lang/Var
```

Check `<build-root>/WEB-INF/lib` to make sure your jars are there.
You probably did not run `gae/libs`.

== the code

The App Engine functions as a servlet container (it's actually a
modified version of Jetty).  Servlet containers look on disk for
compiled byte code when they need to load a servlet.  That means a
Clojure webapp must aot-compile a servlet; usually this is done using
`gen-class` in some form.

{'fraction_non_alphanumeric': 0.09696969696969697, 'fraction_numerical': 0.0013986013986013986, 'mean_word_length': 3.7730812013348163, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 10, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5247588', 'n_tokens_mistral': 1397, 'n_tokens_neox': 1327, 'n_words': 602}