development tools
Increase development productivity: run, debug and auto-reload Jooby applications!!
maven
Maven 3+ plugin for running, debugging and reloading your application.
usage
mvn jooby:run
Prints something similar to:
>>> jooby:run[info|main]: Hotswap available on: /my-app
>>> jooby:run[info|main]: includes: [**/*.class,**/*.conf,**/*.properties,*.js, src/*.js]
>>> jooby:run[info|main]: excludes: []
INFO [2015-03-31 17:47:33,000] [dev@netty]: App server started in 401ms
GET /assets/** [*/*] [*/*] (anonymous)
GET / [*/*] [*/*] (anonymous)
listening on:
http://localhost:8080/
hot reload
The jooby:run
tool restart the application every time a change is detected on:
- classes (*.class)
- config files (*.conf and *.properties)
Changes on templates and/or static files (*.html, *.js, *.css) wont restart the application, because they are not compiled or cached while running on application.env = dev
.
It’s worth to mention that dynamic reload of classes is done via JBoss Modules.
options
<plugin>
<groupId>org.jooby</groupId>
<artifactId>jooby-maven-plugin</artifactId>
<version>1.6.6</version>
<configuration>
<mainClass>${application.class}</mainClass>
<commands>
</commands>
<compiler>on</compiler>
<fork>false</fork>
<vmArgs></vmArgs>
<debug>true</debug>
<includes>
<include>**/*.class</include>
<include>**/*.conf</include>
<include>**/*.properties</include>
</includes>
<excludes>
</excludes>
<srcExtensions>.java,.kt,.conf,.properties</srcExtensions>
</configuration>
</plugin>
${application.class}
A Maven 3+ property that contains the fully qualified name of the main class
. Required.
fork
Allows running the application in a separate JVM. If false it uses the JVM started by Maven 3+, while if true it will use a new JVM. Default is: false
.
This property can be set from command line using the application.fork
system property:
mvn jooby:run -Dapplication.fork=true
compiler
The compiler is on
by default, unless:
-
A
.classpath
file is present in the project directory. If present, means you’re a Eclipse user and we turn off the compiler and let Eclipse recompiles the code on save. -
The compiler is set to
off
.
On compilation success, the application is effectively reloaded.
On compilation error, the application won’t reload.
Compilation success or error messages are displayed in the console (not at the browser).
debug
Start the JVM
in debug mode so you can attach a remote debugger at the 8000
port. Available when fork = true
, otherwise is ignored.
This property can be one of these:
true
: Turn on debug mode using: -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=nfalse
: Turn off debug mode (run normally)int
: Turn on debug mode using the given number as debug port:<debug>8000</debug>
string
: Turn on debug viastring
value, something like: -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n
This property can be set from command line using the application.debug
system property:
mvn jooby:run -Dapplication.debug=9999
commands
List of commands to execute before starting the application
. Useful for npm, npm, etc…
<plugin>
<groupId>org.jooby</groupId>
<artifactId>jooby-maven-plugin</artifactId>
<version>1.6.6</version>
<configuration>
<mainClass>${application.class}</mainClass>
<commands>
<command>npm install</command>
<command>grunt local</command>
</commands>
</configuration>
</plugin>
All processes are stopped it on CTRL+C
vmArgs
Set one or more JVM args
:
<plugin>
<groupId>org.jooby</groupId>
<artifactId>jooby-maven-plugin</artifactId>
<version>1.6.6</version>
<configuration>
<mainClass>${application.class}</mainClass>
<fork>true</fork>
<vmArgs>
<vmArg>-Xms512m</vmArg>
<vmArg>-Xmx1024m</vmArg>
</vmArgs>
</configuration>
</plugin>
Make sure to enable the fork
option too, otherwise vmArgs
are ignored.
includes / excludes
List of file patterns to listen for file changes and trigger restarting the server.
srcExtensions
List of file extensions to listen for file changes and trigger re-compilation.
gradle
Gradle plugin for running, debugging and reloading your application.
usage
buildscript {
repositories {
mavenCentral()
}
dependencies {
/**
* joobyRun
*/
classpath group: 'org.jooby', name: 'jooby-gradle-plugin', version: '1.6.6'
}
}
apply plugin: 'jooby'
}
gradle joobyRun
It will print something like this:
>>> jooby:run[info|main]: Hotswap available on: /my-app
>>> jooby:run[info|main]: includes: [**/*.class,**/*.conf,**/*.properties,*.js, src/*.js]
>>> jooby:run[info|main]: excludes: []
INFO [2015-03-31 17:47:33,000] [dev@netty]: App server started in 401ms
GET /assets/** [*/*] [*/*] (anonymous)
GET / [*/*] [*/*] (anonymous)
listening on:
http://localhost:8080/
hot reload
The joobyRun
tool restarts the application each time a change is detected on:
- classes (*.class)
- config files (*.conf and *.properties)
Changes on templates and/or static files (*.html, *.js, *.css) won’t restart the application, because they are not compiled or cached while running on application.env = dev
.
It’s worth mentioning that dynamic reload of classes is done via JBoss Modules.
options
joobyRun {
mainClassName = 'com.mycompany.App'
compiler = 'on'
includes = ['**/*.class', '**/*.conf', '**/*.properties']
excludes = []
logLevel = 'info'
srcExtensions = [".java", ".kt", ".conf", ".properties"]
}
mainClassName
A Gradle property that contains the fully qualified name of the main class
. Required.
compiler
The compiler is on
by default, unless:
-
A
.classpath
file is present in the project directory. If present, it’s assumed you’re using Eclipse and the compiler is disabled, letting Eclipse recompile the code on save. -
The compiler is set to
off
.
On compilation success, the application is effectively reloaded.
On compilation error, the application won’t reload.
Compilation success or error messages are displayed in the console (not in the browser).
includes / excludes
List of file patterns to watch for file changes and trigger restarting the server.
srcExtensions
List of file extensions watch for changes and trigger re-compilation.
liveReload
LiveReload monitors changes in the file system. As soon as you save a file, it is preprocessed as needed, and the browser is refreshed.
Even cooler, when you change a CSS file or an image, the browser is updated instantly without reloading the page.
exports
livereload.js
routelivereload
websocket
dependency
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-livereload</artifactId>
<version>1.6.6</version>
</dependency>
usage
{
use(new Jackson());
use(new LiveReload());
}
This module is available as long you run in development: application.env=dev
.
configuration
browser extension
Install the LiveReload browser extension.
livereload.js
Add the livereload.js
to your web page.
You can do this manually:
<script src="/livereload.js"></script>
Or use the liveReload
local variable with your preferred template engine. Here is an example using Handlebars
:
{{liveReload}}
json module
The LiveReload Protocol run on top of a WebSocket
and uses JSON
as protocol format. That’s is why we also need to install a JSON module
, like Jackson.
watcher
It automatically reload static resources from public
, target
(Maven projects) or build
folders (Gradle projects).
Every time a change is detected the websocket send a reload command
.
starter project
We do provide a livereload-starter project. Go and fork it.
That’s all folks!!
whoops
Pretty error page that helps you debug your web application.
NOTE: This module is base on whoops and uses the same front end resources.
dependency
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-whoops</artifactId>
<version>1.6.6</version>
</dependency>
exports
usage
{
use(new Whoops());
get("/", req -> {
throw new IllegalStateException("Something broken!");
});
}
The pretty error page handler is available in development mode: application.env = dev
custom err pages
The pretty error page is implemented via err(req, rsp, err). You might run into troubles if your application require custom error pages. On those cases you probably won’t use this module or apply one of the following options:
whoops as last err handler
This option is useful if you have custom error pages on some specific exceptions:
{
err(NotFoundException.class, (req, rsp, err) -> {
// custom not found
});
err(AccessDeniedException.class, (req, rsp, err) -> {
// custom access denied
});
// not handled it use whoops
use(new Whoops());
}
Here the custom error page for NotFoundException
or AccessDeniedException
will be render before the Whoops
error handler.
whoops on dev
This options will active Whoops
in dev
and the custom err pages in prod-like
environments:
{
on("dev", () -> {
use(new Whoops());
})
.orElse(() -> {
err((req, rsp, err) -> {
// custom not found
});
});
}