incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject [CONF] Apache Sling > FAQ
Date Sat, 07 Nov 2009 00:20:00 GMT
    <base href="">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=SLING&amp;forWysiwyg=true"
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="">FAQ</a></h2>
     <h4>Page <b>edited</b> by             <a href="">J.
Aaron Farr</a>
     adding some simple notes on the RESTful API
          <div id="versionComment" class="noteMacro" style="display:none; padding: 5px;">
     adding some simple notes on the RESTful API<br />
     <div class="notificationGreySide">
         <h1><a name="FAQ-FrequentlyAskedQuestions"></a>Frequently Asked

<p>This page lists a series of common questions and answers. It is of course work in
progress ...</p>

    <li><a href='#FAQ-HowdoIcreateanodebypostingajsondocumenttoaURL%3F'>How do
I create a node by posting a json document to a URL?</a></li>
    <li><a href='#FAQ-HowdoIfindoutwhyagivenscriptorservletispreferredtoanotherwhenprocessingarequest%3F'>How
do I find out why a given script or servlet is preferred to another when processing a request?</a></li>
    <li><a href='#FAQ-Howtoreplacethedefaultjsonrenderer%28forexample%29withmyown%3F'>How
to replace the default json renderer (for example) with my own?</a></li>
    <li><a href='#FAQ-Howtoexecutescriptsdirectly%3F'>How to execute scripts directly?</a></li>
    <li><a href='#FAQ-HowdoIcreateanewscriptengine%3F'>How do I create a new script
    <li><a href='#FAQ-Isthereaneasywaytoupdatebundlesinarunninginstallationduringdevelopment%3F'>Is
there an easy way to update bundles in a running installation during development?</a></li>
    <li><a href='#FAQ-AccessingClassesfromtheEnvironment'>Accessing Classes from
the Environment</a></li>
    <li><a href='#FAQ-Howarethe%7B%7Bsling.bootdelegation%7D%7Dpropertiesused%3F'>How
are the <tt>sling.bootdelegation</tt> properties used ?</a></li>
    <li><a href='#FAQ-HowdoesSlingsupportthe%7B%7Borg.osgi.framework.system.packages%7D%7DProperty%3F'>How
does Sling support the <tt>org.osgi.framework.system.packages</tt> Property ?</a></li>
    <li><a href='#FAQ-Shouldthe%7B%7Borg.osgi.framework.bootdelegation%7D%7Dorthe%7B%7Borg.osgi.framework.system.packages%7D%7DPropertybeused%3F'>Should
the <tt>org.osgi.framework.bootdelegation</tt> or the <tt>org.osgi.framework.system.packages</tt>
Property be used ?</a></li>

<h2><a name="FAQ-RESTfulAPI"></a>RESTful API</h2>

<h3><a name="FAQ-HowdoIcreateanodebypostingajsondocumenttoaURL%3F"></a>How
do I create a node by posting a json document to a URL?</h3>

<p>At the moment, you cannot do this. (Soon to change!)  Instead, each value must be
a field in the request POST.  For example, suppose you have the json document:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>json</b></div><div class="codeContent
<pre class="code-java">
    <span class="code-quote">"greetings"</span>:<span class="code-quote">"Hello,
    <span class="code-quote">"multi"</span> : [<span class="code-quote">"first"</span>,<span
    <span class="code-quote">"translations"</span> : { <span class="code-quote">"en"</span>:
<span class="code-quote">"Hello"</span>, <span class="code-quote">"zh"</span>,
<span class="code-quote">"你好"</span> }

<p>You would do a post such as:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>post</b></div><div class="codeContent
<pre class="code-java">
curl -F<span class="code-quote">"greetings=Hello, World!"</span> -F<span class="code-quote">"mult=first"</span>
-F<span class="code-quote">"multi=second"</span> -F<span class="code-quote">"translations/en=Hello"</span>
-F<span class="code-quote">"translations/zh=你好"</span> http:<span class="code-comment">//admin:admin@localhost:8080/content/../../..</span>

<h2><a name="FAQ-ScriptsandServlets"></a>Scripts and Servlets</h2>

<h3><a name="FAQ-HowdoIfindoutwhyagivenscriptorservletispreferredtoanotherwhenprocessingarequest%3F"></a>How
do I find out why a given script or servlet is preferred to another when processing a request?</h3>
<p>See <a href="" rel="nofollow">SLING-580</a>,
the SlingServletResolver class logs detailed information (at the DEBUG level) to indicate
in which order the candidate scripts and servlets are considered for processing a request.</p>

<h3><a name="FAQ-Howtoreplacethedefaultjsonrenderer%28forexample%29withmyown%3F"></a>How
to replace the default json renderer (for example) with my own?</h3>

<p>The JSON rendering is done by the DefaultGetServlet, which is hardwired to use the
JsonRendererServlet for .json extensions. </p>

<p>If a servlet or script is registered for the <tt>sling/servlet/default</tt>
resource type, but with a specific <tt>sling.servlet.extensions</tt> property
(set using the <tt></tt> annotation), it will take over and process
GET requests which have a .json extension and no specific servlet or script.</p>

<p>As scripts and servlets are equivalent in Sling, the simplest way to do this to create
a script at <tt>apps/sling/servlet/default/json.esp</tt>, for example.</p>

<p>The same logic applies to other extensions (html, txt, ...) handled by the DefaultGetServlet.</p>

<h3><a name="FAQ-Howtoexecutescriptsdirectly%3F"></a>How to execute scripts
<p>The following servlet (inspired from the <a href=""
rel="nofollow">Sakai ScriptRunner</a>) executes scripts directly when called with
the script URL and a <em>.runscript</em> selector (for example <em>/foo/myscript.esp.runscript.html</em>).</p>

<p>Note that this can be <b>insecure</b>: if users are allowed to upload
scripts, they can execute any code supported by Sling, so use that only if you know what you're

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>ScriptRunnerServlet</b></div><div
class="codeContent panelContent">
<pre class="code-java">
/* @scr.component 
 *    immediate=<span class="code-quote">"<span class="code-keyword">true</span>"</span>
label=<span class="code-quote">"ScriptRunner"</span>
 *    description=<span class="code-quote">"Runs scripts using the .runscript selector"</span>
 * @scr.service 
 *    <span class="code-keyword">interface</span>=<span class="code-quote">"javax.servlet.Servlet"</span>
 *    name=<span class="code-quote">"sling.servlet.resourceTypes"</span>
 *    value=<span class="code-quote">"sling/servlet/<span class="code-keyword">default</span>"</span>
 *    name=<span class="code-quote">"sling.servlet.selectors"</span> 
 *    value=<span class="code-quote">"runscript"</span>
 *    name=<span class="code-quote">"sling.servlet.methods"</span> 
 *    value=<span class="code-quote">"GET"</span>
<span class="code-keyword">public</span> class ScriptRunnerServlet <span class="code-keyword">extends</span>
SlingAllMethodsServlet {

<span class="code-keyword">protected</span> void doGet(
  SlingHttpServletRequest req, 
  SlingHttpServletResponse resp) 
  <span class="code-keyword">throws</span> ServletException, IOException {
    Servlet s = req.getResource().adaptTo(Servlet.class);
    <span class="code-keyword">if</span>(s == <span class="code-keyword">null</span>)
      <span class="code-keyword">throw</span> <span class="code-keyword">new</span>

        ServletException(<span class="code-quote">"Resource "</span> 
        + req.getResource() 
        + <span class="code-quote">" does not adapt to a Servlet"</span>);
    s.service(req, resp);

<h3><a name="FAQ-HowdoIcreateanewscriptengine%3F"></a>How do I create a
new script engine?</h3>
<p>As I write this, we don't have documentation on how to create more script engines,
but that's not too hard to do if you take one of the simple existing engines as an example.</p>

<p>The <a href=""
rel="nofollow">JRuby engine</a> for example, implemented in the <em>scripting/ruby</em>
module, is built out of two simple classes, one that inherits from AbstractSlingScriptEngine,
and one that inherits from AbstractScriptEngineFactory. The code is very simple, it's basically
only a wrapper around the JRuby engine, that adapts it for Sling.</p>

<p>If creating a script engine, don't forget the <em>META-INF/services/javax.script.ScriptEngineFactory</em>
file, which lets scripting subsystem know about the factory class, so that the engine is activated
when the bundle that contains it is loaded.</p>

<p>Once the script engine is created, loading its bundle into Sling should be enough
to activate scripts having the extension defined by the engine. If several scripts are found
with the same name but different script extensions, the priority in selecting them is currently

<p>The javascript and freemarker engines source code also shows how to add automated
tests to a script engine, including making a JCR repository available to the tests.</p>

<p>To go further, the javascript and jsp script engines are the most interesting ones
to study. </p>

<p>The javascript engine provides <a href=""
rel="nofollow">wrappers</a> to make it easier to access JCR and Sling objects from
server-side javascript, and also uses a clever <a href=""
rel="nofollow">EspReader</a> (sorry it's not <em>that</em> <a href=""
rel="nofollow">ESP</a>) to convert <em>.esp</em> scripts to plain javascript

<p>The jsp engine is actually a compiler, so it can be an interesting example if your
language needs or can benefit from compiling.</p>

<h2><a name="FAQ-Workingwithbundles"></a>Working with bundles</h2>

<h3><a name="FAQ-Isthereaneasywaytoupdatebundlesinarunninginstallationduringdevelopment%3F"></a>Is
there an easy way to update bundles in a running installation during development?</h3>

<p>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 <tt>mvn clean package</tt>
and the bundle is uploaded.</p>

<p>You can use the <tt>settings.xml</tt> to set the url to your Sling application.
See the <a href="/confluence/pages/createpage.action?spaceKey=SLING&amp;title=Plugins&amp;linkCreation=true&amp;fromPageId=73883"
class="createlink">Sling Maven Plugin</a> for more information.</p>

<h2><a name="FAQ-Classloadingissues"></a>Classloading issues</h2>

<h3><a name="FAQ-AccessingClassesfromtheEnvironment"></a>Accessing Classes
from the Environment</h3>

<p>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:</p>
	<li>Accessing EJB from the Application Server</li>
	<li>Sharing classe with another web application such as a Jackrabbit instance</li>
	<li>Using other container features</li>

<p>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 <tt>org.osgi.framework.system.packages</tt>
and <tt>org.osgi.framework.bootdelegation</tt>:</p>
	<li><tt><b>org.osgi.framework.bootdelegation</b></tt> &#45;
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
	<li><tt><b>org.osgi.framework.system.packages</b></tt> &#45;
Additional package declarations for packages to be exported from the system bundle. This property
is a simple package declaration list just like any <tt>Export-Package</tt> manifest
header. In a sense the <tt>org.osgi.framework.system.packages</tt> property may
be seen as the <tt>Export-Package</tt> manifest header of the system bundle. Namely
these entries may not contain wildcards (as is allowed for the <tt>bootdelegation</tt>
property) and may contain directives and attributes such as the <tt>uses</tt>
directive and the <tt>version</tt> attribute. It is recommended to provide this
additional information to help in resolving the bundles. The OSGi Core Specification even
prescribes the use of the <tt>uses</tt> directive.</li>

<p>The problem with the <tt>org.osgi.framework.bootdelegation</tt> 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 <tt>org.osgi.framework.bootdelegation</tt>
appropriately (<a href="ttps://" rel="nofollow">SLING-148</a>).</p>

<p>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 <tt>org.osgi.framework.bootdelegation</tt>
configuration into account. This means, that regardless of whether a package is listed in
the <tt>org.osgi.framework.bootdelegation</tt> property or not, if the package
is listed as a required import in the <tt>Import-Package</tt> header, it must
be exported by some other bundle.</p>

<h3><a name="FAQ-Howarethe%7B%7Bsling.bootdelegation%7D%7Dpropertiesused%3F"></a>How
are the <tt>sling.bootdelegation</tt> properties used ?</h3>

<p>Sling uses the <tt>sling.bootdelegation.class</tt> property name prefix
to define lists of classes that must be added to the <tt>org.osgi.framework.bootdelegation</tt>
property. In case you want to have a closer look, this is implemented in the <tt></tt>

<p>If a Sling property name starts with the <tt>sling.bootdelegation.class.</tt>
prefix, the list of packages defined as the property value is appended to the <tt>org.osgi.framework.bootdelegation</tt>
property, but only if the fully qualified class taken from the rest of the property name exists
in the parent class loader.</p>

<p>Here's an example, from the file:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
sling.bootdelegation.class.javax.jcr.Repository = \
 javax.jcr, \
 javax.jcr.lock, \
 javax.jcr.nodetype, \
 javax.jcr.observation, \
 javax.jcr.query, \
 javax.jcr.util, \

<p>This means that, if the <tt>javax.jcr.Repository</tt> class is available
in the parent class loader, all packages listed will be added to the <tt>org.osgi.framework.bootdelegation</tt>,
making the corresponding classes available to OSGi bundles.</p>

<p>If the property name does not start with this <tt>sling.bootdelegation.class.</tt>
property, the list of packages is just appended to the <tt>org.osgi.framework.bootdelegation</tt>

<h3><a name="FAQ-HowdoesSlingsupportthe%7B%7Borg.osgi.framework.system.packages%7D%7DProperty%3F"></a>How
does Sling support the <tt>org.osgi.framework.system.packages</tt> Property ?</h3>

<p>Currently extending the <tt>org.osgi.framework.system.packages</tt> property
in a Sling configuration file is only possibly by setting the <tt></tt>
property. The value of this property, which <em>must</em> start with a comma,
is just appended to the <tt>org.osgi.framewrok.system.packages</tt> property.</p>

<p>A more elaborate support as is supported for the <tt>org.osgi.framework.bootdelegation</tt>
Property has been prepared (<a href="" rel="nofollow">SLING-147</a>).</p>

<h3><a name="FAQ-Shouldthe%7B%7Borg.osgi.framework.bootdelegation%7D%7Dorthe%7B%7Borg.osgi.framework.system.packages%7D%7DPropertybeused%3F"></a>Should
the <tt>org.osgi.framework.bootdelegation</tt> or the <tt>org.osgi.framework.system.packages</tt>
Property be used ?</h3>

<p>So, what mechanism should be used ? The answer is, that it depends.</p>

<p>Most of the time, you will want to use the <tt>org.osgi.framework.system.packages</tt>
property. Because this property ensures that you will allways benefit from the normal class
resolution mechanism through package imports and exports.</p>

<p>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).</p>

<p>The drawback of this method is, that there may be bundles in your system, which export
packages also listed in the <tt>org.osgi.framework.system.packages</tt> property.
Depending on the export version, the wrong package may be bound. So to prevent such collisions
you should not install such bundles.</p>

<p>An example of such a declaration is the Servlet API packages (<tt>javax.servlet</tt>,
<tt>javax.servlet.http</tt> and <tt>javax.servlet.resources</tt>).
These packages are imported into the OSGi framework by the <tt>SlingServlet</tt>
of the <tt>launcher/webapp</tt> project as part of the <tt>org.osgi.framework.system.packages</tt>
property. To have this work correctly, no bundle should export the respective packages. In
the case of Sling, this means, the <tt></tt>
bundle must not be installed.</p>

<p>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 <tt>org.osgi.framework.bootdelegation</tt>
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 <tt>org.osgi.framework.system.packages</tt>
method does not work.</p>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href=""
class="grey">Change Notification Preferences</a>

       <a href="">View Online</a>
       <a href="">View
       <a href=";showCommentArea=true#addcomment">Add

View raw message