Hosted by Three Crickets

Sincerity
Packaging and Bootstrapping
For the JVM

Please note that Sincerity is still under development and that this documentation is incomplete.

Sincerity logo: jackrabbit and flowers

Feature Plugins

Sincerity Standalone Plugin

See also the redistribution plugin for a different approach to distribution.

Logging Plugin

This plugin makes it exceptionally easy to unify and configure your logging across a diverse set of technologies and dependencies. In most cases, simply installing this plugin into your container should handle all logging with sensible defaults. Should you need to customize and configure logging, you'll find Sincerity's scheme especially flexible and powerful.
Though the JVM includes a standard logging API, in the "java.util.logging Interface" ("JULI") package, the greater JVM ecology has adopted a few incompatible standards. In particular, Apache Log4j, which was the inspiration for JULI, enjoys broad support and a more robust implementation. Especially since Log4j 2.0, it provides state-of-the-art scalability for high loads using innovative asynchronous handling. We've thus preferred to use Log4j for our actual implementation, and rely on the excellent SLF4J library for bridging JULI to it. SLF4J has become popular enough that several libraries support it directly, so that we can avoid even the minimal overhead introduced by bridging.
To install:
sincerity add logging : install
To initialize logging, you can execute the "logging" command from within your programs. An example in JavaScript:
// Will do nothing if the logging plugin is not installed:
try { sincerity.run('logging:logging') } catch(x) {}
You can also test logging simply using the "log" command, which sends an "info" level message to the "sincerity" logger:
sincerity add logging : install : log "This is a test!"
Logs will appear under the "/logs/" directory. By default, all loggers are appended to "/logs/common.log", which is a rolling log file with a size of 5MB per file, and a maximum of 10 files.
Note for Restlet users: If you're using the Restlet skeleton, it's recommended to install the Restlet skeleton logging add-on, which adds a Restlet extension library that provides direct chute to SLF4J.
High CPU usage? On some rare combinations of operating systems and JVMs, Log4j 2.0 (well, actually the LMAX Disruptor library it uses) may use too much CPU time, even when idle. You can reduce CPU usage in these cases, at the expense of affecting the high-scalability profile, by using the following JVM switch:
-DAsyncLoggerConfig.WaitStrategy=Block

Fleshing Out

"Officially," Log4j configuration is based either on JVM properties files or XML. Both are hardcoded, inflexible and difficult to scale. Sincerity's logging plugin instead uses a powerful JavaScript-based scheme, which allows you to dynamically configure your loggers according to your operating environment.
Configure your loggers under "/configuration/logging/loggers/" and your appenders under "/configuration/logging/appenders/". Any JavaScript file you add to these directories will be executed upon logging initialization. Take a look at the defaults to get a sense of how this works: the /sincerity/log4j/ library makes it especially easy to use.
For example, here's a definition of a rolling file appender:
var logFile = sincerity.container.getLogsFile('main.log')
logFile.parentFile.mkdirs()
​
configuration.rollingFileAppender({
	name: 'main',
	layout: {
		pattern: '%d: %-5p [%c] %m%n'
	},
	fileName: String(logFile),
	filePattern: String(logFile) + '.%i',
	policy: {
		size: '5MB'
	},
	strategy: {
		min: '1',
		max: '9'
	}
})
Note that you can also use "official" Log4j configuration if you are more comfortable with it. If the file "/configuration/logging.conf" is present, it will be used. This file can either be a properties file, a JSON file, or an XML file (in which case it must begin with the "<?xml" header). The plugin comes with an example "logging.conf" named "logging.alt.conf", which you can rename to "logging.conf" if you wish to use it.
The logging plugin also comes with a simple "log" command to test your logging configuration. Example usage:
sincerity log "Hello, log!"

Extras

In distributed environments, such as grids and clouds, you may prefer to centralize your logging. To aid this common use case, Sincerity comes with two logging server solutions.
Log4j Server
You can create a simple Log4j TCP-based socket server, which comes with the logging plugin:
sincerity create logserver : add logging : install : start log4j-server
Note that we're creating the Log4j server in a separate container, and starting it as a separate process.
On this Log4j server, you want to configure your actual appenders. Then, on all your client processes, you want to disable all the appenders except the socket appender ("/configuration/logging/appenders/socket.js"). Uncomment all the code there to enable it and make it the default root appender.
The result is that all logging messages will be sent from the clients to the server, where they will be actually logged.
It's recommend to run the Log4j server with Sincerity's service plugin:
sincerity create logserver : add logging : add service : install : service log4j-server start
MongoDB Appender
You can install a MongoDB-backed appender:
sincerity add logging.mongodb : install
To configure the MongoDB connection, edit "/configuration/logging/appenders/common-mongo-db.js". By default, it connects to localhost at the default port (27017) without security, and logs to database "logs", collection "common".
It is strongly recommended that you use a capped collection for your log. This guarantees both excellent write performance as well as automatic rolling. You can create it from the "mongo" shell tool like so:
db.createCollection('common', {capped: true, size: 100000})
Or, convert an existing collection to capped:
db.runCommand({'convertToCapped': 'common', size: 100000})
This plugin also provides you with a very useful tool to "tail" your central log (works only with capped collections):
sincerity logtail
Press CTRL+C to quit. To test that this works, open another terminal and send a log message:
sincerity log "This is a test!"
You can provide "logtail" with the MongoDB connection parameters:
sincerity logtail --uri=localhost:27017 --username=admin --password=admin123 --db=logs --collection=common

Service Plugin

This plugin lets you easily start and control any program as a daemon or service running in the background. This is achieved using Tanuki Software's excellent Java Service Wrapper (JSW). JSW deploys a native process to monitor your daemon's health, is able to detect failures and hangs, and restarts in such cases. It supports many configuration options to control the JVM process, as well as JMX-based management for the wrapper. While you can start any program using the "sincerity start" command, it is strongly recommended that you use this plugin instead for production environments. It's so well-designed, we wish it were included in the JVM!
JSW runs on an impressive array of JVM-capable operating systems: Linux, Mac OS X, Windows, Solaris, AIX, FreeBSD, HPUX, z/OS and z/Linux, supporting several 32-bit and 64-bit machine architectures for each. Of course, you do not want to install support for all of these platforms in your container, and so this plugin cleverly detects the underlying operating system and downloads the necessary native libraries on-demand the first time it is run. An error message will be displayed on unsupported platforms.
To install:
sincerity add service : install
To start a program as a daemon:
sincerity service myprogram start
The above assumes that you have a "/programs/myprogram.js" file. (Programs can be written in languages other than JavaScript if they are installed in your container.) See the service wrapper's log at "/logs/service-myprogram.log".
To stop the daemon:
sincerity service myprogram stop
To restart it:
sincerity service myprogram restart
To check its status:
sincerity service myprogram status
Additionally, you can run the wrapper in "console mode," which outputs the wrapper's log to the console, and lets you easily stop it using CTRL+C. This is very useful for testing and debugging:
sincerity service myprogram console
Note that Sincerity uses the Community Edition of JSW, which is licensed under the GPL (v2). Make sure that you understand the special implications of this license if you intend to redistribute your product. Furthermore, some Windows platforms (64bit x86 and Itanium) supported by the Standard/Professional Editions are not supported by the Community Edition. A commercial license is available for purchase without these limitations. See the license guide for more information.

Fleshing Out

This plugin generates some parts of the JSW configuration on the fly, but it can furthermore merge your custom settings into this configuration. To do so, edit "/configuration/service/service.conf". In particular, you might want to control the memory profile of your JVM, or configure the wrapper's logging (which works independently of JVM logging). See the JSW documentation for a complete guide.
Additionally, this plugin provides a flexible way for you to send arguments to the wrapped JVM. Any files under "/configuration/service/jvm/" with a ".conf" extension will be merged and added. The plugin comes installed with a few sensible defaults, and additionally other plugins may add their own ".conf" files to support the service plugin. These ".conf" files all support string interpolation using any JVM system property or environment variable. For example, here's a way to add garbage collection logging:
-Xloggc:{sincerity.container.root}/logs/gc.log
-XX:+PrintGCDetails
-XX:+PrintTenuringDistribution
It may furthermore be useful to run your Sincerity service as an operating system service. On Unix-like systems, you can use a "system init script." Below is a script template you may use, meant for the Restlet skeleton. It adds a special "###" comment block used by Linux's Standard Base (LSB) specification. Let's name it "/etc/init.d/restlet":
#!/bin/sh
​
### BEGIN INIT INFO
# Provides:          restlet
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the Restlet component
# Description:       starts the Restlet component using start-stop-daemon
### END INIT INFO
​
SINCERITY=/path/to/sincerity/sincerity
CONTAINER=/path/to/container
SERVICE=restlet
OWNER=myuser
​
COMMAND=$1
​
sudo -u "$OWNER" "$SINCERITY" use "$CONTAINER" : service "$SERVICE" "$COMMAND"
exit 0 
For consistency, make sure to change the "Provides:" entry to match the name of the file.
You can start/stop this service by running the above script directly, for example: "sudo /etc/init.d/restlet start". On some operating systems, you may also use your "service" command, for example: "sudo service restlet start".
Make sure to edit the variables to point to the paths on your system. Note that the "OWNER" user will be used to run your service, and that for security reasons you are strongly advised not to use "root": it is best to create a special user for your service, and to set its permissions according to only what it needs: read access to Sincerity and the container, and write access to the container's "/cache/", "/logs/" and other relevant directories.
To make your service start automatically when the system starts depends on your operating system. The above script should work on most Linux-based operating systems due to the "###" comment block. To process this file and the block, effectively installing the service into the operating system, run "sudo update-rc.d restlet defaults". That command uses "insserv" internally, so run "man insserv" to get documentation for the comment block format.

Extras

JMX is a powerful technology for remote monitoring and management of your JVM and applications. Local JMX (using pipes) is automatically supported, however you may also need remote JMX over the network. To add it:
sincerity add service.remote-jmx : install
The default configuration is adequate for accessing JMX via SSH tunneling, which is very secure. To create the tunnel, use the "-L" switch of SSH when connecting to your remote server:
ssh -L 1650:localhost:1650 -L 1651:localhost:1651 mysite.org
Note that we actually create two tunnels, one for JMX on port 1650 and one for the RMI registry on port 1651. With the tunnel in place, start VisualVM (it's included with the JDK), choose "Add JMX Connection," and use "localhost:1650" for the connection string. Note that you do not want to use "Add Remote Host": tunneling makes the remote host appear local. Of course, you will need to keep the tunnel open for as long as you're connected with VisualVM.
If this is your first time using VisualVM, it is recommended that you install its "VisualVM-MBean" plugin, which will, among other things, allows you to access JSW's bean ("org.tanukisoftware.wrapper") for remotely restarting your service.
You can configure remote JMX by editing "/configuration/service/jvm/remote-jmx.conf". For example, you may change the port numbers, enable authentication, and also SSL if you prefer it to SSH tunneling.
Important note if you are using a version of the JVM prior to 7u4: Unfortunately, old versions of the JVM do not support the "com.sun.management.jmxremote.rmi.port" property, without which the RMI registry port is assigned randomly, thus making it difficult to use SSH tunneling. To solve this problem, this Sincerity add-on comes with a special "firewall-friendly-agent" library that allows for this functionality. You must specifically enable it in "/configuration/service/jvm/remote-jmx.conf".

Redistribution Plugin

This plugin lets you package your Sincerity container for convenient redistribution. See the Sincerity standalone plugin for a different approach to distribution.
Currently, it supports creating a powerful cross-platform JVM-based graphical installer, using the excellent IzPack library. In the future, we hope to support additional distribution media.
To install:
sincerity add redistribution : install
To use:
sincerity izpack [application name] [version (optional, defaults to "1.0")]
For example, in a single command let's create an installable Nexus repository manager with a few plugins:
sincerity create nexus : add nexus : add logging : add service : add redistribution : install : izpack "Nexus Repository Manager"
The result will be an "installer.jar" file in your container's root directory, which you can distribute. To install your application from this jar:
java -jar installer.jar
(Note that on some desktop environments double-clicking this file would also run it.)
The installed directory will contain a convenient "uninstaller.jar".

Fleshing Out

To change the license, edit "/configuration/izpack/license.txt".
The "/configuration/izpack/installer.xml" included with this plugin has sensible defaults that should work fine for many use cases, but you'll likely want to customize it. By default, it merges your Sincerity install in, and excludes IzPack itself, as well as the "/cache/" and "/logs/" directory. This guarantees that it would "just work" cleanly on any JVM with no pre-requisites.
Please see the IzPack documentation for full details. IzPack is very powerful, and can let you create modular, flexible distributions.

Markup Plugin

Need to quickly render markup text into HTML? Markdown, Confluence, MediaWiki, Twiki, Trac, Textile and Bugzilla Textile are all supported by this plugin. Markdown is supported by the Pegdown engine, and the rest by Mylyn WikiText. (While useful in itself, this plugin is intended to serve as a code example for using these libraries.)
The rendering engines themselves are not at first installed: the plugin will make sure that the engine you need is available, and install it if it's not, on demand.
To install:
sincerity add markup : install
To use:
sincerity render [language] [marked up source path] [rendered output path]
For example:
sincerity render markdown README.md readme.html

Batik SVG Plugin

Need to quickly render SVG into PDF, PNG or JPEG? This plugin uses Apache Batik to do so. (While useful in itself, this plugin is intended to serve as a code example for using Batik.)
To install:
sincerity add batik : install
To use:
sincerity render [SVG source path] [rendered output path]
The output path extension will determine the output type. For example:
sincerity render test.svg test.pdf

JsDoc Plugin

"jsdoc.sincerity"

The Sincerity Manual is provided for you under the terms of the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. The complete manual is available for download as a PDF.

Download manual as PDF Creative Commons License