Prudence
The Scalable REST/JVM
Web Development Platform

Creative Commons License

Prudence Applications

Prudence applications live in the /applications/ subdirectory, with one subdirectory per application. The subdirectories mentioned below should all be considered as subdirectories of an application subdirectory. Deploying an application to a Prudence instance involves nothing more than creating a subdirectory here with the application files.

Deploy by Zip

The /applications/ and /common/ subdirectories are both "zip-aware," meaning that any archive file with the .zip extension placed there will automatically be unzipped when Prudence starts up.
The unzipping will happen again only if the zip's modification date changes: Prudence creates a ".properties" file to keep track of the modification dates.
Zips can contain pre-packaged single applications, groups of applications, common libraries, and even patches for individual applications. Zip-awareness makes it very easy to package, deploy and upgrade components and even large sites containing many applications.
We encourage you to follow our convention and name your deployable zips with versioning information and the ".prudence.zip" extension, for example "wackywiki-1.1.prudence.zip".

Subdirectory Structure

Note that these subdirectory names are defaults, but they can be configured in the application's settings.

/web/dynamic/

This is where you'll put your dynamic HTML files. By "dynamic" is meant that they are generated on demand, such that each request can potentially produce a different, cacheable result. Prudence has a powerful framework for embedding programming language code into HTML as "scriptlets." (Actually, it supports textual formats other than HTML, such as XML, RSS, JSON, etc.) See generating HTML.
The names of the files and subdirectories under /web/dynamic/ attach to URLs, with simple intelligence to make it easy for you to create sensible, pretty URL schemes. See pretty URIs for more information.

/web/static/

This subdirectory works like a standard static web server. Files put here are attached to URLs and accessible to clients as is. Prudence uses non-blocking I/O for high performance, scalable delivery of data to clients.
The "/common/web/static/" instance subdirectory is used as a fallback for files not found in the application's "/web/static/" subdirectory. You can thus use "/common/web/static/" to serve static web files for all applications.
Like many web servers, MIME types for HTTP headers are automatically assigned according to the filename extension. For example. ".html" files will be sent as "application/html", and ".png" files will be sent as "image/png".
The static web subdirectory will likely "just work" for you as is. See static web for extras, such as adding filename-extension-to-MIME-type mappings and compressing JavaScript/CSS.

/web/fragments/

Your dynamic pages in /web/dynamic/ can include any page fragments from here. The advantage of putting them here rather than there is that here they will not be attached to URLs. Fragments are normally hidden from users, visible only if they're included into a page in /web/dynamic/.
The "/common/web/fragments/" instance subdirectory is used as a fallback for files not found in the application's "/web/fragments/" subdirectory. You can thus use "/common/web/fragments/" to serve web fragments for all applications.
Fragments allow you to compose complex pages out of reusable building blocks. Another important use is for fine-grained caching: each fragment has its own caching behavior. See generating HTML.

/resources/

Whereas the /web/dynamic/ subdirectory has HTML (or other textual) files with embedded programming language code, /resources/ is pure code. This is Prudence's most flexible development feature: files here are attached to URLs as REST resources, capable of handling all HTTP verbs and responding with appropriate representations in any format.
From the perspective of web development, consider that if /web/dynamic/ lets you write HTML-based front ends for "thin" clients, such as simple web browsers, /resources/ lets you handle "rich" clients, such as AJAX, Flash and other dynamic platforms.
See resources for a complete guide.

/handlers/

Handlers work similarly to resources, except that they are much simpler: they are not mapped to URLs. Instead, they must be explicitly used for specific purposes.
The "/common/handlers/" instance subdirectory is used as a fallback for files not found in the application's "/handlers/" subdirectory. You can thus use "/common/handlers/" to install handlers for all applications.

/tasks/

Tasks are straightforward scripts that can be run on-demand or scheduled to run and specific times. They are straightforward in that, upon execution, the code is simply run as is. There is no particular entry point as with /resources/ or /handlers/.
The "/common/tasks/" instance subdirectory is used as a fallback for files not found in the application's "/tasks/" subdirectory. You can thus use "/common/tasks/" to install tasks for all applications.

/libraries/

All your code, whether it's in /resources/, /handlers/, /tasks/ or in scriptlets embedded in /web/dynamic/ and /fragments/, can include code from /libraries/.
Use whatever mechanism is appropriate for your language: "import" for Python or Ruby, "use" for Clojure, etc. For languages that don't have inclusion mechanisms—Groovy, JavaScript—you can use Prudence's inclusion mechanism, document.execute.
The "/common/libraries/" instance subdirectory is used as a fallback for files not found in the application's "/handlers/" subdirectory. You can thus use "/common/libraries/" to install libraries for all applications.
To share source code with all your applications, use the instance's /libraries/ directory.

/uploads/

Files uploaded via HTML forms will be placed here, if they are larger than a configurable threshold. Otherwise, they are stored in memory. See conversation.form for more information.
Note: You need to create this subdirectory explicitly for file uploads to work!

Configuration Scripts

The application's configuration scripts are in its base subdirectory.
Make sure you read the section on configuration scripts for the Prudence instance for general guidelines.

/default.*

You'll rarely need to do it, but you can also override Prudence's default application bootstrap.
Here you can modify an application's filename extensions to media type mappings. An example "default.js":
document.execute('/defaults/application/')
applicationInstance.metadataService.addExtension('jsp', MediaType.TEXT_HTML)

/settings.*

Here you can override some of Prudence's defaults for your application, such as the subdirectory structure detailed here, the default URLs, include some distribution information, configure the logging name, etc.
You can also add your own runtime settings for your code to use, such as database usernames and passwords.
See the settings section for full detail on overrides and default settings.

/routing.*

The settings file gives you some control over the default URLs, but here you can manipulate them extensively. Your routing tools are very powerful, including redirection based on URL patterns, regular expressions, and route scoring.
In particular, this is where you install URL patterns for your resources. For example, you can attach /item/{id}/ to your item resource, and have "id" automatically extracted from the URL.
This is also where you can attach your own custom (non-Prudence) resources to URLs. Actually, anything that's a "restlet" will do, because Prudence uses Restlet for its resource routing. See the section on integrating custom restlets.
See routing.

/application.*

Use this to install non-Prudence Restlet applications into Prudence. By default, Prudence creates a PrudenceApplication, but you can override that creation in this file. See the section on integrating Restlets.

/crontab

This is the configuration file that not a script. It lets you schedule tasks to run at certain calendrical times. See tasks (1).

Settings

Each application's subdirectory name under the /applications/ directory is used as a default for many settings.
In this manual, we've used setting names in camel case, as is used by JavaScript and Groovy. For Python, Ruby and PHP use lowercase underscore notation, for example: "application_home_url." For Clojure, use lowercase hyphenated notation, for example "application-home-url."

Information

These are for administrative purposes, such as the Prudence administration application, and are also used for the default error message pages.
They are directly available at runtime via application.application.
applicationName
Defaults to the application's subdirectory name.
applicationDescription
A short description to help explain what the application is, in case the application name is too obscure.
applicationAuthor
The entity (person, corporation) that created the application.
applicationOwner
The entity (person, corporation) that owns the rights to the application.
applicationHomeURL
The URL (Internet or intranet) of the application. This may be displayed in certain default error messages, as a way to contact the application administrators or technical support. Note that there is only one home URL, even if the application is attached to multiple virtual hosts. In fact, the home URL does not have to be service by this Prudence instance, and can lead to a different site.
applicationContactEmail
This may be displayed in certain default error messages, as a way to contact the application administrators or technical support.

Debugging

showDebugOnError
Set to true to show debug information on error. See debugging.
showSourceCodeURL
The base URL for showing source code (only relevant when showDebugOnError is true).
minimumTimeBetweenValidityChecks
This is the time (in milliseconds) allowed to pass until a script file is tested to see if it was changed. During development, you'd want this to be low, but during production, it should be high in order to avoid unnecessary hits on the filesystem. Defaults to 1000 (1 second).

Logging

applicationLoggerName
Defaults to the application's subdirectory name.

Documents

librariesBasePath
If documents are not found in the main locations, they are looked for here. Relative to the application's subdirectory. Defaults to "/libaries/".
documentsDefaultName
If the document name points to a directory rather than a file, and that directory contains a file with this name, then it will be used. This allows you to use the directory structure to create nice URLs without relying on filenames. This is true for "/resources/", "/tasks/", "/handlers/" and "/libraries/". Defaults to "default".

Routing

hosts
This is a array of array of two elements: the first is the virtual host to which our application will be attached, the second is the base URLs on the hosts. This lets you attach the application to multiple virtual hosts with a different base URL per host.
Specify null for the URL to default to the application's subdirectory name. Use "component.defaultHost" for the default virtual host, as defined by the "hosts" configuration script.
If not "hosts" setting is specified, it defaults to attach to the default virtual host via the application's subdirectory name. This is equivalent to:
hosts = [[component.defaultHost, null]]
Here's an example of a more complex "hosts" setting:
hosts = [[myorgHost, null], [intranetServiceHost, '/'], [b2bHost, '/b2b/service/']]
Note that URLs in the virtual host may overlap as far as hierarchy is concerned. Thus, an application at "/b2b/" can have its own URLs, such as "/b2b/access/", and this would not interfere with the application at "/b2b/service/". The application is routed before URLs internal to the application. See routing for a full explanation on how URLs reach their destinations in Prudence.

Resources

Sets up a directory under which you can place script files that implement RESTful resources. The directory structure underneath the base directory is directly linked to the base URL.
resourcesBaseURL
Defaults to the root ("/"), meaning that the directory and file structure maps directly to URLs at the application's base URL on the virtual host. See routing for more information.
resourcesBasePath
Relative to the application's subdirectory. Defaults to "/resources/".
resourcesPassThrough
An array of document names that can "pass through," meaning they can exist in the "/libraries/" as well as "/resources/". In fact, the can exist in "/common/libraries/", too.
resourcesDefrost
Set this to true if you want to start to load and compile your resources as soon as Prudence starts. Defaults to true.
resourcesSourceViewable
This is so we can see the source code for scripts by adding ?source=true to the URL. You probably wouldn't want this for production environments. Defaults to true.

Dynamic Web

Sets up a directory under which you can place text files that support embedded scriptlets. Note that the generated result can be cached for better performance. See generating HTML.
dynamicWebBaseURL
Defaults to the root ("/"), meaning that the directory and file structure maps directly to URLs at the application's base URL on the virtual host. See routing for more information.
dynamicWebBasePath
Relative to the application's subdirectory. Defaults to "/web/dynamic/".
fragmentsBasePath
Relative to the application's subdirectory. Defaults to "/web/fragments/".
dynamicWebDefaultDocument
If the URL points to a directory rather than a file, and that directory contains a file with this name, then it will be used. This allows you to use the directory structure to create nice URLs that do not contain filenames. Defaults to "index".
dynamicWebPassThrough
An array of document names that can "pass through," meaning they can exist in the "/web/fragments/" as well as "/web/dynamic/". In fact, the can exist in "/common/web/fragments/", too.
dynamicWebDefrost
Set this to true if you want to compile your scriptlets as soon as Prudence starts. Defaults to true.
dynamicWebPreheat
Set this to true if you want to load all your dynamic web documents as soon as Prudence starts. Defaults to true.
Also see preheatResources.
dynamicWebSourceViewable
This is so we can see the source code for scripts by adding ?source=true to the URL. You probably wouldn't want this for most applications. Defaults to true.
dynamicWebClientCachingMode
If you set server-side caching with document.cacheDuration, then you can use this setting to define whether client-side caching should be enabled, too:
  • 0: Disabled. Client caching headers are not sent.
  • 1: Conditional (the default). The client is asked to use conditional mode HTTP to verify that the cache has not changed, via the modificationDate and expirationDate headers. This is a good default, because it generally offers most of the advantages of caching with no risks. See conditional requests for HTML generation for a complete discussion.
  • 2: Offline. The client is asked to cache without verification, via the maxAge header. This involves some risk: if you ask to cache a page for one week, but then find out that you have a mistake in your application, then users will not see any fix you publish until their local cache expires, which can take up to a week! It's important that you understand the implications before using this mode.
It's generally safer to apply offline caching for some of your /web/static/ resources, such as graphics and other resources, which, by nature of being static, do not tend to change on their own. See CacheControlFilter. For /resources/, you have precise control over each header; see conversation.modificationDate, conversation.expirationDate and conversation.tag.

Static Web

Sets up a directory under which you can place static files of any type. See static web.
staticWebBaseURL
Defaults to the root ("/"), meaning that the directory and file structure maps directly to URLs at the application's base URL on the virtual host. See routing for more information.
staticWebBasePath
Relative to the application's subdirectory. Defaults to "/web/static/".
staticWebCompress
Whether to enable smart compression before sending files over HTTP. Only uncompressed files will be compressed, and only if there are bandwidth savings will the compressed version be used. Defaults to true.
If you're running Prudence behind a proxy that already does compression, and are worried that you're compressing twice, then stop worrying: any decent proxy will know not to compress content that's already compressed.
staticWebDirectoryListingAllowed
If the URL points to a directory rather than a file, then this will allow automatic creation of a simple HTML page with a directory listing. Defaults to true.

File Uploads

fileUploadBasePath
Relative to the application's subdirectory. Defaults to "/uploads/".
File uploads will be stored here. Note that you have to create this directory yourself in order to handle file uploads.
fileUploadSizeThreshold
The size in bytes beyond which uploaded files will be stored to disk. Defaults to zero, meaning that all uploaded files will be stored to disk. See conversation.form.

Handlers

handlersBasePath
Relative to the application's subdirectory. Defaults to "/handlers/".
handlersDefaultName
If the handler name points to a directory rather than a file, and that directory contains a file with this name, then it will be used. This allows you to use the directory structure to create nice names without relying on filenames. Defaults to "default".

Tasks

tasksBasePath
Relative to the application's subdirectory. Defaults to "/tasks/".
tasksDefaultName
If the task name points to a directory rather than a file, and that directory contains a file with this name, then it will be used. This allows you to use the directory structure to create nice names without relying on filenames. Defaults to "default".

Preheater

"Heating up" means that an internal GET verb is sent to them, with the result discarded. This is a good way to ensure that resources, such as database connection pools, are initialized and ready to service user requests as soon as possible.
preheatResources
Note that all /resources/ and /web/dynamic/ files are automatically preheated. List additional URLs here that you want heated up as soon as Prudence starts. This is most useful in conjunction with custom routing, such as capturing.
Also see dynamicWebPreheat.

Miscellaneous

urlAddTrailingSlash
The URLs in this array will automatically be redirected to have a trailing slash added to them if it's missing.
By default, URLs in /dynamic/web/ and /resources/ have trailing slash required. See the trailing slash requirement for routing if you wish to disable this.
predefinedGlobals
Values set in this map will be available in application.globals at runtime. This is useful for custom configuration of your application. For example, you can set resource IP addresses, service usernames and passwords, etc.
predefinedSharedGlobals
Values set in this map will be available in application.sharedGlobals at runtime. This is useful for custom configuration of your application. For example, you can set resource IP addresses, service usernames and passwords, etc.