Frequently Asked Questions
This page lists a series of common questions and answers. It is of course work in progress ...
Scripts and Servlets
How to replace the default json renderer (for example) with my own?
The JSON rendering is done by the DefaultGetServlet, which is hardwired to use the JsonRendererServlet for .json extensions.
If a servlet or script is registered for the sling/servlet/default
resource type, but with a specific sling.servlet.extensions
property (set using the @scr.property
annotation), it will take over and process GET requests which have a .json extension and no specific servlet or script.
As scripts and servlets are equivalent in Sling, the simplest way to do this to create a script at apps/sling/servlet/default/json.esp
, for example.
The same logic applies to other extensions (html, txt, ...) handled by the DefaultGetServlet.
Working with bundles
Is there an easy way to update bundles in a running installation during development?
The Sling Maven Plugin provides an install goal which is able to install or update a bundle in a running Sling application (if the Sling web console is deployed). If the plugin properties are configured accordingly you can just mvn clean package org.apache.sling:maven-sling-plugin:install
and the bundle is uploaded.
You can use the settings.xml
to set the url to your Sling application. See the Sling Maven Plugin for more information.
Classloading issues
Accessing Classes from the Environment
Mostly when using the Sling Web Application, that is running Sling inside a web application deployed into some servlet container, you might want to share classes between the servlet container and Sling. Some examples of such sharing are:
- Accessing EJB from the Application Server
- Sharing classe with another web application such as a Jackrabbit instance
- Using other container features
For such cases the OSGi Core Specification provides a functionality to declare such class sharing. The functionality is defined in terms of two Framework properties org.osgi.framework.system.packages
and org.osgi.framework.bootdelegation
:
org.osgi.framework.bootdelegation
- All classes matching any entry in this list are always loaded from the parent class loader and not through the OSGi framework infrastructure. This property is a comma separated list of package names. A package name may be terminated by a wildcard character such that any package starting with the list entry matches the entry and thus will be used from the parent class loader.org.osgi.framework.system.packages
- Additional package declarations for packages to be exported from the system bundle. This property is a simple package declaration list just like anyExport-Package
manifest header. In a sense theorg.osgi.framework.system.packages
property may be seen as theExport-Package
manifest header of the system bundle. Namely these entries may not contain wildcards (as is allowed for thebootdelegation
property) and may contain directives and attributes such as theuses
directive and theversion
attribute. It is recommended to provide this additional information to help in resolving the bundles. The OSGi Core Specification even prescribes the use of theuses
directive.
The problem with the org.osgi.framework.bootdelegation
property is, that it completely bypasses any bundle import wirings and just asks the parent classloader. Such situations are not easily recognizable. Therefore the Sling Console will be enhanced to mark any package import which matchs an entry in the org.osgi.framework.bootdelegation
appropriately (SLING-148).
Also note, that any package listed as an import in a bundle must be resolveable for the bundle resolve. The import resolution process does not take the org.osgi.framework.bootdelegation
configuration into account. This means, that regardless of whether a package is listed in the org.osgi.framework.bootdelegation
property or not, if the package is listed as a required import in the Import-Package
header, it must be exported by some other bundle.
How are the sling.bootdelegation
properties used ?
Sling uses the sling.bootdelegation.class
property name prefix to define lists of classes that must be added to the org.osgi.framework.bootdelegation
property. In case you want to have a closer look, this is implemented in the org.apache.sling.launcher.app.Sling.resolve()
method.
If a Sling property name starts with the sling.bootdelegation.class.
prefix, the list of packages defined as the property value is appended to the org.osgi.framework.bootdelegation
property, but only if the fully qualified class taken from the rest of the property name exists in the parent class loader.
Here's an example, from the jcr-client.properties file:
sling.bootdelegation.class.javax.jcr.Repository = \ javax.jcr, \ javax.jcr.lock, \ javax.jcr.nodetype, \ javax.jcr.observation, \ javax.jcr.query, \ javax.jcr.util, \ javax.jcr.version
This means that, if the javax.jcr.Repository
class is available in the parent class loader, all packages listed will be added to the org.osgi.framework.bootdelegation
, making the corresponding classes available to OSGi bundles.
If the property name does not start with this sling.bootdelegation.class.
property, the list of packages is just appended to the org.osgi.framework.bootdelegation
property.
How dose Sling support the org.osgi.framework.system.packages
Property ?
Currently extending the org.osgi.framework.system.packages
property in a Sling configuration file is only possibly by setting the org.apache.sling.launcher.system.packages
property. The value of this property, which must start with a comma, is just appended to the org.osgi.framewrok.system.packages
property.
A more elaborate support as is supported for the org.osgi.framework.bootdelegation
Property is being prepared (SLING-147).
Should the org.osgi.framework.bootdelegation
or the org.osgi.framework.system.packages
Property be used ?
So, what mechanism should be used ? The answer is, that it depends.
Most of the time, you will want to use the org.osgi.framework.system.packages
property. Because this property ensures that you will allways benefit from the normal class resolution mechanism through package imports and exports.
This allows creating the bundles normally by having the package import lists being built according to the packages used by the bundle classes. For example you may use the Apache Felix Maven Bundle Plugin to build your OSGi bundles and the imports are automatically calculated (by default).
The drawback of this method is, that there may be bundles in your system, which export packages also listed in the org.osgi.framework.system.packages
property. Depending on the export version, the wrong package may be bound. So to prevent such collisions you should not install such bundles.
An example of such a declaration is the Servlet API packages (javax.servlet
, javax.servlet.http
and javax.servlet.resources
). These packages are imported into the OSGi framework by the SlingServlet
of the launcher/webapp
project as part of the org.osgi.framework.system.packages
property. To have this work correctly, no bundle should export the respective packages. In the case of Sling, this means, the org.apache.felix.commons.sling-api
bundle must not be installed.
If on the other hand you cannot prevent the installation of such bundles and hence the export of the respective packages, you might want to set the org.osgi.framework.bootdelegation
property conditionally as described above in the answer to how this property is supported in Sling. This ensures the property is only set, if the classes are actually available. This should be used as a fall back only, if the org.osgi.framework.system.packages
method does not work.