<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5750351649256467689</id><updated>2011-04-21T21:12:29.877+02:00</updated><category term='jcr'/><category term='osgi'/><category term='sling'/><category term='howto'/><category term='crx'/><title type='text'>in the sling</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5750351649256467689.post-7496544646489672769</id><published>2008-09-22T16:09:00.001+02:00</published><updated>2008-09-22T16:09:49.092+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sling'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><title type='text'>Inside Sling: How Sling boots</title><content type='html'>&lt;p&gt;In this post, I will give an overview on how Sling starts up, how Felix is started as the OSGi framework, how Sling is configured, and how Sling loads other bundles.    &lt;br /&gt;For this, we need to have a look at the org.apache.sling.launchpad.base project ( sling/launchpad/base ). &lt;/p&gt;  &lt;h3&gt;Class overview&lt;/h3&gt;  &lt;p&gt;Let's start with an overview of the most important classes involved in the startup process:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;blue boxes are Sling classes, from package org.apache.sling.launcher.base &lt;/li&gt;    &lt;li&gt;green boxes are Felix classes, from package org.apache.felix.framework &lt;/li&gt;    &lt;li&gt;the violet box is an OSGi framework interface, the BundleActivator &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/moritz.havelock/SNenIJgmcRI/AAAAAAAAACI/5zHItztXUFg/s1600-h/launchpad%20classes%5B13%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="446" alt="launchpad classes" src="http://lh3.ggpht.com/moritz.havelock/SNenJUN2ANI/AAAAAAAAACM/hnQeFx8FFZM/launchpad%20classes_thumb%5B7%5D.png?imgmax=800" width="616" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The ResourceProvider abstract class forms an interface for Sling to be able to locate arbitrary resources. In this case, the only implementation is the ClassLoaderResourceProvider, which will load resources from the class loader passed in the constructor. Note that this is &lt;strong&gt;not&lt;/strong&gt; the org.apache.sling.api.ResourceProvider interface, but an abstract class in the package org.apache.sling.launcher.base.&lt;/p&gt;  &lt;p&gt;The Sling class holds a reference to a Felix instance (as it starts the instance), and to a Logger instance (which it also instantiates). At the same time, it implements the BundleActivator interface. This is an OSGi framework interface that needs to be implemented by classes that start and stop a bundle. Felix accepts a list of BundleActivators in it's constructor, and these will serve as the bundles that are initially started, and which are responsible for starting any other bundles required. We'll look at Sling's bundle start and stop methods in a minute.&lt;/p&gt;  &lt;p&gt;BootstrapInstaller also implements BundleActivator and is also passed to Felix at startup. The BootstrapInstaller will load all the other bundles that make up Sling. We'll look at that as well.&lt;/p&gt;  &lt;h3&gt;Sequence overview&lt;/h3&gt;  &lt;p&gt;Before we go into details, let's look at the startup sequence from a high level:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;a logger is instantiated &lt;/li&gt;    &lt;li&gt;a ClassLoaderResourceProvider is created, passing the Main class' class loader &lt;/li&gt;    &lt;li&gt;a Sling instance is created, passing the previous two objects &lt;/li&gt;    &lt;li&gt;install bundles are set &lt;/li&gt;    &lt;li&gt;the OSGi execution environment is set &lt;/li&gt;    &lt;li&gt;an instance of BootstrapInstaller is created &lt;/li&gt;    &lt;li&gt;a Felix instance is created, passing the Logger and a list of BundleActivators, consisting of the sling instance itself and the BootstrapInstaller just created &lt;/li&gt;    &lt;li&gt;Felix' start method is called &lt;/li&gt;    &lt;li&gt;eventually, as it will start up the bundles passed in the constructor, Felix will call the start() method of the sling instance &lt;/li&gt;    &lt;li&gt;Felix will also call the start() method of the BootstrapInstaller &lt;/li&gt;    &lt;li&gt;this in turn will call installBundles() and &lt;/li&gt;    &lt;li&gt;startBundles(), which I will dicuss a little later &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/moritz.havelock/SNenJ2ejPfI/AAAAAAAAACQ/onmnI5n58eU/s1600-h/launchpad%20sequence%5B3%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="676" alt="launchpad sequence" src="http://lh3.ggpht.com/moritz.havelock/SNenKtvRipI/AAAAAAAAACU/W4zu0vEFzHU/launchpad%20sequence_thumb%5B1%5D.png?imgmax=800" width="706" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Details&lt;/h3&gt;  &lt;p&gt;Now that we have seen that objects involved and the high level sequence of things, let's dig down a bit deeper, along the lines of the sequence:&lt;/p&gt;  &lt;h4&gt;the main method&lt;/h4&gt;  &lt;p&gt;First, let's have a look at the Main class' main method (see below: &lt;a href="#org.apache.sling.launcher.app.main.Main"&gt;&lt;code&gt;org.apache.sling.launcher.app.main.Main&lt;/code&gt;&lt;/a&gt;)&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Line 102 creates a Map, &lt;code&gt;props&lt;/code&gt; to store properties that will be passed to Sling when instantiated. &lt;/li&gt;    &lt;li&gt;Line 105 creates another Map, &lt;code&gt;commandLine&lt;/code&gt; in which command line configuration statements will be collected. This collection is deferred to the &lt;code&gt;parseCommandline&lt;/code&gt; method. That method will scan the commandline for switches that affect the port, log file, log level or sling home directory, and collect the configuration into the &lt;code&gt;commandLine&lt;/code&gt; Map which it was passed. &lt;/li&gt;    &lt;li&gt;Line 110 propagates a setting of sling.home from the &lt;code&gt;commandLine&lt;/code&gt; Map to the &lt;code&gt;props&lt;/code&gt; Map &lt;/li&gt;    &lt;li&gt;Lines 119-126 determine the log level from the command line and sets it in the &lt;code&gt;commandLine&lt;/code&gt; Map accordingly. This won't take effect until Sling later calls back to the loadPropertiesOverride() method. For a start, a Logger is instantiated and set to a log level of &lt;code&gt;LOG_ERROR&lt;/code&gt; in lines 127 and 131. &lt;/li&gt;    &lt;li&gt;Line 138 creates the &lt;code&gt;ClassLoaderResourceProvider&lt;/code&gt; &lt;/li&gt;    &lt;li&gt;Line 140 instantiates a Sling instance and makes an inline overrive of the &lt;code&gt;loadPropertiesOverride&lt;/code&gt; method. This method is an overrideable callback provided for classes extending &lt;code&gt;Sling&lt;/code&gt;, and will be called by &lt;code&gt;Sling.loadConfigProperties&lt;/code&gt;. &lt;/li&gt;    &lt;li&gt;Line 159 establishes a VM shutdown hook which will call &lt;code&gt;Sling.destroy()&lt;/code&gt; before the VM shuts down &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Sling configuration&lt;/h4&gt;  &lt;p&gt;Actual Sling startup takes place in the constructor, so let's have a closer look at that (Line numbers refer to &lt;a href="#org.apache.sling.launcher.app.main.Main"&gt;&lt;code&gt;org.apache.sling.launcher.app.main.Main&lt;/code&gt;&lt;/a&gt;). Line 182 delegates configuration setup to &lt;code&gt;loadConfigProperties()&lt;/code&gt;, so let's first have a look at how the Sling configuration is calculated.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;load the properties file (l.299) and all includes (l.302) &lt;/li&gt;    &lt;li&gt;overwrite the loaded properties with properties passed in the constructor (if any duplicates) (l.306) &lt;/li&gt;    &lt;li&gt;look for the &lt;code&gt;sling.home&lt;/code&gt; property in the system properties, the properties just merged, and set to &amp;quot;sling&amp;quot; if not found (l.310-321) &lt;/li&gt;    &lt;li&gt;merge any properties found in &lt;code&gt;${sling.home}/sling.properties&lt;/code&gt; (l.328-330). &lt;/li&gt;    &lt;li&gt;overwrite properties with any system properties that have the same name (&lt;code&gt;sling.home&lt;/code&gt; is not affected). This step can be prevented by setting &lt;code&gt;sling.ignoreSystemProperties&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;. (l.338-346) &lt;/li&gt;    &lt;li&gt;load includes that have been added through the last steps (l.349) &lt;/li&gt;    &lt;li&gt;call &lt;code&gt;loadPropertiesOverride&lt;/code&gt; -- &lt;code&gt;Sling&lt;/code&gt;'s own implementation does nothing, but subclasses may override this to inject configuration &lt;/li&gt;    &lt;li&gt;append to the list of boot delegation and system packages (l.355, 357): given the prefix sling.bootdelegation. and the osgiProp org.osgi.framework.bootdelegation, it will      &lt;ul&gt;       &lt;li&gt;look for an entry that starts with sling.bootdelegation. and add the value to the end of the current value of org.osgi.framework.bootdelegation (adding a comma if that value is not empty so far) &lt;/li&gt;        &lt;li&gt;&lt;i&gt;unless&lt;/i&gt; the entry starts with sling.bootdelegation.class. &amp;amp;ldash; in that case, it will interpret the rest of the property name as a class name, and add the value only if the class can be loaded. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;substitute variables (e.g. ${sling.home}) (l.368-371) &lt;/li&gt;    &lt;li&gt;substitute &lt;code&gt;context:&lt;/code&gt; values (l.374 - 419) (in short: for any value that starts with &lt;code&gt;context:/&lt;/code&gt;, copy the file that is specified by the remainder of the value to &lt;code&gt;sling.home&lt;/code&gt; and replace the original value of the property with the absolute path of the copied file) &lt;/li&gt;    &lt;li&gt;as a last step, the unsubstituted properties are written back to &lt;code&gt;${sling.home}/sling.properties&lt;/code&gt;. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;The remainder of the Sling constructor&lt;/h4&gt;  &lt;p&gt;So, we have reached line 183 in &lt;code&gt;Sling.java&lt;/code&gt;, and are before step (4) in the sequence diagram above. Let's see what happens in the rest of Sling's constructor.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;code&gt;setInstallBundles()&lt;/code&gt; is called in line 185. I have not seen any use of this in a sling properties file, but it looks like properties of the pattern &lt;code&gt;&lt;b&gt;sling.install.&lt;/b&gt;&lt;i&gt;some.bundle.name.here&lt;/i&gt;&lt;/code&gt; will result in &lt;code&gt;,some.bundle.name.here&lt;/code&gt; being appended to &lt;code&gt;sling.install.bundles&lt;/code&gt;. &lt;/li&gt;    &lt;li&gt;&lt;code&gt;setExecutionEnvironment()&lt;/code&gt; is called in line 188. This will set the property &lt;code&gt;org.osgi.framework.executionenvironment&lt;/code&gt; (see section 3.3 of the OSGi R4 core specification). &lt;/li&gt;    &lt;li&gt;A list of &lt;code&gt;BundleActivator&lt;/code&gt;s is created, including the &lt;code&gt;Sling&lt;/code&gt; instance in construction and a new &lt;code&gt;BootstrapInstaller&lt;/code&gt;. &lt;/li&gt;    &lt;li&gt;In line 199, a new Felix instance is created, passing the list of bundle activators just created, the properties, and the logger &lt;/li&gt;    &lt;li&gt;Line 200 starts the Felix environment. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now we're at step (8) in the sequence diagram. Felix has started up, the Sling constructor returns. And all that was to be seen so far didn't look like very much, so where's all the rest happening? We'll take up the thread by looking at the &lt;code&gt;start()&lt;/code&gt; methods of &lt;code&gt;Sling&lt;/code&gt; and &lt;code&gt;BootstrapInstaller&lt;/code&gt;. These were both registered as startup bundle activators when calling the Felix constructor, so this is how Felix again plays the ball to Sling.&lt;/p&gt;  &lt;p&gt;&lt;code&gt;Sling.start()&lt;/code&gt; will just do one thing: it will register a &lt;code&gt;ContextProtocolHandler&lt;/code&gt; to handle URLs that start with &lt;code&gt;context:&lt;/code&gt;. Any such URL will Sling's &lt;code&gt;resourceProvider&lt;/code&gt; (so in this case, the &lt;code&gt;ClassLoaderResourceProvider&lt;/code&gt;) to resolve these URLs.&lt;/p&gt;  &lt;p&gt;&lt;code&gt;BootstrapInstaller.start()&lt;/code&gt; does a bit more. For one thing, it should be noted that this method will be run only once: when Sling is started for the first time. This is achieved by persisting the installation state to a data file managed by Felix (l 147-165), and by reading that data back on method start and not running the code if it was run before (l 103-127).&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Lines 129-134: the &lt;code&gt;DeploymentPackageInstaller&lt;/code&gt; will wait until Framework and Deployment Admin service have started up, and then look for deployment packages in &lt;code&gt;resources/bundles&lt;/code&gt; (on the class loader), and install any found (if not already installed). See also section 114 of the OSGi Compendium R4. &lt;/li&gt;    &lt;li&gt;Lines 143-145 install any bundles provided as jar files in &lt;code&gt;resources/corebundles&lt;/code&gt; or &lt;code&gt;resources/bundles&lt;/code&gt;, if not already installed, keeping track of the bundles so installed &lt;/li&gt;    &lt;li&gt;Line 168 will call &lt;code&gt;startBundles&lt;/code&gt;, which will start all the bundles just installed. It will also try to set the start level of each bundle to &lt;code&gt;1&lt;/code&gt;, if the start level service is available (OSGi Core R4, Section 8). &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Code&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="#org.apache.sling.launcher.app.Sling"&gt;&lt;code&gt;org.apache.sling.launcher.app.Sling&lt;/code&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#org.apache.sling.launcher.app.BootstrapInstaller"&gt;&lt;code&gt;org.apache.sling.launcher.app.BootstrapInstaller&lt;/code&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="#org.apache.sling.launcher.app.main.Main"&gt;&lt;code&gt;org.apache.sling.launcher.app.main.Main&lt;/code&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;a name="org.apache.sling.launcher.app.Sling"&gt;&lt;/a&gt;  &lt;h4&gt;&lt;code&gt;org.apache.sling.launcher.app.Sling&lt;/code&gt;, Revision 657002&lt;/h4&gt;  &lt;pre class="java" name="code"&gt;/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the &amp;quot;License&amp;quot;); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sling.launcher.app;

import static org.apache.felix.framework.util.FelixConstants.EMBEDDED_EXECUTION_PROP;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Map.Entry;

import org.apache.felix.framework.Felix;
import org.apache.felix.framework.Logger;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.service.url.URLConstants;
import org.osgi.service.url.URLStreamHandlerService;

/**
 * The &amp;lt;code&amp;gt;Sling&amp;lt;/code&amp;gt; serves as the starting point for Sling.
 * &amp;lt;ul&amp;gt;
 * &amp;lt;li&amp;gt;The {@link #Sling(Logger, ResourceProvider, Map)} method launches
 * Apache &amp;lt;code&amp;gt;Felix&amp;lt;/code&amp;gt; as the OSGi framework implementation we use.
 * &amp;lt;/ul&amp;gt;
 * &amp;lt;p&amp;gt;
 * &amp;lt;b&amp;gt;Launch Configuration&amp;lt;/b&amp;gt;
 * &amp;lt;p&amp;gt;
 * The Apache &amp;lt;code&amp;gt;Felix&amp;lt;/code&amp;gt; framework requires configuration parameters
 * to be specified for startup. This servlet builds the list of parameters from
 * three locations:
 * &amp;lt;ol&amp;gt;
 * &amp;lt;li&amp;gt;The &amp;lt;code&amp;gt;com/day/osgi/servlet/Sling.properties&amp;lt;/code&amp;gt; is read from
 * the servlet class path. This properties file contains default settings.&amp;lt;/li&amp;gt;
 * &amp;lt;li&amp;gt;Extensions of this servlet may provide additional properties to be
 * loaded overwriting the {@link #loadPropertiesOverride(Map)} method.
 * &amp;lt;li&amp;gt;Finally, web application init parameters are added to the properties and
 * may overwrite existing properties of the same name(s).
 * &amp;lt;/ol&amp;gt;
 * &amp;lt;p&amp;gt;
 * After loading all properties, variable substitution takes place on the
 * property values. A variable is indicated as &amp;lt;code&amp;gt;${&amp;amp;lt;prop-name&amp;amp;gt;}&amp;lt;/code&amp;gt;
 * where &amp;lt;code&amp;gt;&amp;amp;lt;prop-name&amp;amp;gt;&amp;lt;/code&amp;gt; is the name of a system or
 * configuration property (configuration properties override system properties).
 * Variables may be nested and are resolved from inner-most to outer-most. For
 * example, the property value &amp;lt;code&amp;gt;${outer-${inner}}&amp;lt;/code&amp;gt; is resolved by
 * first resolving &amp;lt;code&amp;gt;${inner}&amp;lt;/code&amp;gt; and then resolving the property whose
 * name is the catenation of &amp;lt;code&amp;gt;outer-&amp;lt;/code&amp;gt; and the result of resolving
 * &amp;lt;code&amp;gt;${inner}&amp;lt;/code&amp;gt;.
 * &amp;lt;p&amp;gt;
 */
public class Sling implements BundleActivator {

    /** Pseduo class version ID to keep the IDE quite. */
    private static final long serialVersionUID = 1L;

    /**
     * The name of the configuration property defining the Sling home directory
     * (value is &amp;quot;sling.home&amp;quot;). This is a Platform file system directory below
     * which all runtime data, such as the Felix bundle archives, logfiles, CRX
     * repository, etc., is located.
     * &amp;lt;p&amp;gt;
     * The value of this property, if not set as a system property defaults to
     * the &amp;lt;i&amp;gt;sling&amp;lt;/i&amp;gt; directory in the current working directory.
     *
     * @see #SLING_HOME_URL
     */
    public static final String SLING_HOME = &amp;quot;sling.home&amp;quot;;

    /**
     * The name of the configuration property defining the Sling home directory
     * as an URL (value is &amp;quot;sling.home.url&amp;quot;).
     * &amp;lt;p&amp;gt;
     * The value of this property is assigned the value of
     * &amp;lt;code&amp;gt;new File(${sling.home}).toURI().toString()&amp;lt;/code&amp;gt; before
     * resolving the property variables.
     *
     * @see #SLING_HOME
     */
    public static final String SLING_HOME_URL = &amp;quot;sling.home.url&amp;quot;;

    /**
     * The name of the configuration property defining a properties file
     * defining a list of bundles, which are installed into the framework when
     * it has been launched (value is &amp;quot;org.apache.osgi.bundles&amp;quot;).
     * &amp;lt;p&amp;gt;
     * This configuration property is generally set in the web application
     * configuration and may be referenced in all property files (default, user
     * supplied and web application parameters) used to build the framework
     * configuration.
     */
    public static final String OSGI_FRAMEWORK_BUNDLES = &amp;quot;org.apache.osgi.bundles&amp;quot;;

    /**
     * The property to be set to ignore the system properties when building the
     * Felix framework properties (value is &amp;quot;sling.ignoreSystemProperties&amp;quot;). If
     * this is property is set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; (case does not matter),
     * the system properties will not be used by
     * {@link #loadConfigProperties(Map)}.
     */
    public static final String SLING_IGNORE_SYSTEM_PROPERTIES = &amp;quot;sling.ignoreSystemProperties&amp;quot;;

    /**
     * The name of the default launcher properties file to setup the environment
     * for the &amp;lt;code&amp;gt;Felix&amp;lt;/code&amp;gt; framework (value is &amp;quot;sling.properties&amp;quot;).
     * &amp;lt;p&amp;gt;
     * Extensions of this class may overwrite some or all properties in this
     * file through Web Application parameters or other properties files.
     */
    public static final String CONFIG_PROPERTIES = &amp;quot;sling.properties&amp;quot;;

    public static final String PROP_SYSTEM_PACKAGES = &amp;quot;org.apache.sling.launcher.system.packages&amp;quot;;

    /**
     * The simple logger to log messages during startup and shutdown to
     */
    protected final Logger logger;

    private ResourceProvider resourceProvider;

    /**
     * The &amp;lt;code&amp;gt;Felix&amp;lt;/code&amp;gt; instance loaded on {@link #init()} and stopped
     * on {@link #destroy()}.
     */
    private Felix felix;

    /**
     * The &amp;lt;code&amp;gt;BundleContext&amp;lt;/code&amp;gt; of the OSGi framework system bundle.
     * This is used for service registration and service access to get at the
     * delegatee servlet.
     */
    private BundleContext bundleContext;

    /**
     * Initializes this servlet by loading the framework configuration
     * properties, starting the OSGi framework (Apache Felix) and exposing the
     * system bundle context and the &amp;lt;code&amp;gt;Felix&amp;lt;/code&amp;gt; instance as servlet
     * context attributes.
     *
     * @throws BundleException if the framework cannot be initialized.
     */
    public Sling(Logger logger, ResourceProvider resourceProvider,
            Map&amp;lt;String, String&amp;gt; propOverwrite) throws BundleException {

        this.logger = logger;
        this.resourceProvider = resourceProvider;

        this.logger.log(Logger.LOG_INFO, &amp;quot;Starting Sling&amp;quot;);

        // read the default parameters
        Map&amp;lt;String, String&amp;gt; props = this.loadConfigProperties(propOverwrite);

        // check for auto-start bundles
        this.setInstallBundles(props);

        // ensure execution environment
        this.setExecutionEnvironment(props);

        // make sure Felix does not exit the VM when terminating ...
        props.put(EMBEDDED_EXECUTION_PROP, &amp;quot;true&amp;quot;);

        // the custom activator list just contains this servlet
        List&amp;lt;BundleActivator&amp;gt; activators = new ArrayList&amp;lt;BundleActivator&amp;gt;();
        activators.add(this);
        activators.add(new BootstrapInstaller(logger, resourceProvider));

        // create the framework and start it
        Felix tmpFelix = new Felix(logger, props, activators);
        tmpFelix.start();

        // only assign field if start succeeds
        this.felix = tmpFelix;

        // log sucess message
        this.logger.log(Logger.LOG_INFO, &amp;quot;Sling started&amp;quot;);
    }

    /**
     * Destroys this servlet by shutting down the OSGi framework and hence the
     * delegatee servlet if one is set at all.
     */
    public final void destroy() {
        // shutdown the Felix container
        if (felix != null) {
            logger.log(Logger.LOG_INFO, &amp;quot;Shutting down Sling&amp;quot;);
            felix.stopAndWait();
            logger.log(Logger.LOG_INFO, &amp;quot;Sling stopped&amp;quot;);
            felix = null;
        }
    }

    // ---------- BundleActivator ----------------------------------------------

    /**
     * Called when the OSGi framework is being started. This implementation
     * registers as a service listener for the
     * &amp;lt;code&amp;gt;javax.servlet.Servlet&amp;lt;/code&amp;gt; class and calls the
     * {@link #doStartBundle()} method for implementations to execute more
     * startup tasks. Additionally the &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; URL protocol
     * handler is registered.
     *
     * @param bundleContext The &amp;lt;code&amp;gt;BundleContext&amp;lt;/code&amp;gt; of the system
     *            bundle of the OSGi framework.
     * @throws Exception May be thrown if the {@link #doStartBundle()} throws.
     */
    public final void start(BundleContext bundleContext) throws Exception {
        this.bundleContext = bundleContext;

        // register the context URL handler
        Hashtable&amp;lt;String, Object&amp;gt; props = new Hashtable&amp;lt;String, Object&amp;gt;();
        props.put(URLConstants.URL_HANDLER_PROTOCOL, new String[] { &amp;quot;context&amp;quot; });
        ContextProtocolHandler contextHandler = new ContextProtocolHandler(
            this.resourceProvider);
        bundleContext.registerService(URLStreamHandlerService.class.getName(),
            contextHandler, props);

        // execute optional bundle startup tasks of an extension
        this.doStartBundle();
    }

    /**
     * Called when the OSGi framework is being shut down. This implementation
     * first calls the {@link #doStopBundle()} method method before
     * unregistering as a service listener and ungetting an servlet delegatee if
     * one has been acquired.
     *
     * @param bundleContext The &amp;lt;code&amp;gt;BundleContext&amp;lt;/code&amp;gt; of the system
     *            bundle of the OSGi framework.
     */
    public final void stop(BundleContext bundleContext) {
        // execute optional bundle stop tasks of an extension
        try {
            this.doStopBundle();
        } catch (Exception e) {
            this.logger.log(Logger.LOG_ERROR, &amp;quot;Unexpected exception caught&amp;quot;, e);
        }

        // drop bundle context reference
        this.bundleContext = null;
    }

    // ---------- Configuration Loading ----------------------------------------

    /**
     * Loads the configuration properties in the configuration property file
     * associated with the framework installation; these properties are
     * accessible to the framework and to bundles and are intended for
     * configuration purposes. By default, the configuration property file is
     * located in the &amp;lt;tt&amp;gt;conf/&amp;lt;/tt&amp;gt; directory of the Felix installation
     * directory and is called &amp;quot;&amp;lt;tt&amp;gt;config.properties&amp;lt;/tt&amp;gt;&amp;quot;. The
     * installation directory of Felix is assumed to be the parent directory of
     * the &amp;lt;tt&amp;gt;felix.jar&amp;lt;/tt&amp;gt; file as found on the system class path property.
     * The precise file from which to load configuration properties can be set
     * by initializing the &amp;quot;&amp;lt;tt&amp;gt;felix.config.properties&amp;lt;/tt&amp;gt;&amp;quot; system
     * property to an arbitrary URL.
     *
     * @return A &amp;lt;tt&amp;gt;Properties&amp;lt;/tt&amp;gt; instance or &amp;lt;tt&amp;gt;null&amp;lt;/tt&amp;gt; if there was
     *         an error.
     */
    private Map&amp;lt;String, String&amp;gt; loadConfigProperties(
            Map&amp;lt;String, String&amp;gt; propOverwrite) throws BundleException {
        // The config properties file is either specified by a system
        // property or it is in the same directory as the Felix JAR file.
        // Try to load it from one of these places.
        Map&amp;lt;String, String&amp;gt; props = new HashMap&amp;lt;String, String&amp;gt;();

        // Read the properties file.
        this.load(props, CONFIG_PROPERTIES);

        // resolve inclusions (and remove property)
        this.loadIncludes(props, null);

        // overwrite default properties with initial overwrites
        if (propOverwrite != null) {
            props.putAll(propOverwrite);
        }

        // check whether sling.home is overwritten by system property
        String slingHome = System.getProperty(SLING_HOME);
        if (slingHome == null || slingHome.length() == 0) {

            // no system property, ensure default setting
            slingHome = props.get(SLING_HOME);
            if (slingHome == null || slingHome.length() == 0) {
                slingHome = &amp;quot;sling&amp;quot;;
                this.logger.log(Logger.LOG_INFO,
                    &amp;quot;sling.home is not defined. Using '&amp;quot; + slingHome + &amp;quot;'&amp;quot;);
            }
        }

        // resolve variables and ensure sling.home is an absolute path
        slingHome = substVars(slingHome, SLING_HOME, null, props);
        File slingHomeFile = new File(slingHome).getAbsoluteFile();
        slingHome = slingHomeFile.getAbsolutePath();

        // overlay with ${sling.home}/sling.properties
        this.logger.log(Logger.LOG_INFO, &amp;quot;Starting sling in &amp;quot; + slingHome);
        File propFile = new File(slingHome, CONFIG_PROPERTIES);
        this.load(props, propFile);

        // create a copy of the properties to perform variable substitution
        Map&amp;lt;String, String&amp;gt; origProps = props;
        props = new HashMap&amp;lt;String, String&amp;gt;();
        props.putAll(origProps);

        // check system properties for any overrides (except sling.home !)
        String ignoreSystemProperties = props.get(SLING_IGNORE_SYSTEM_PROPERTIES);
        if (!&amp;quot;true&amp;quot;.equalsIgnoreCase(ignoreSystemProperties)) {
            for (String name : props.keySet()) {
                String sysProp = System.getProperty(name);
                if (sysProp != null) {
                    props.put(name, sysProp);
                }
            }
        }

        // resolve inclusions again
        this.loadIncludes(props, slingHome);

        // overwrite properties, this is not persisted as such
        this.loadPropertiesOverride(props);

        // resolve boot delegation and system packages
        this.resolve(props, &amp;quot;org.osgi.framework.bootdelegation&amp;quot;,
            &amp;quot;sling.bootdelegation.&amp;quot;);
        this.resolve(props, &amp;quot;org.osgi.framework.system.packages&amp;quot;,
            &amp;quot;sling.system.packages.&amp;quot;);

        // reset back the sling home property
        // might have been overwritten by system properties, included
        // files or the sling.properties file
        origProps.put(SLING_HOME, slingHome);
        props.put(SLING_HOME, slingHome);
        props.put(SLING_HOME_URL, slingHomeFile.toURI().toString());

        // Perform variable substitution for system properties.
        for (Entry&amp;lt;String, String&amp;gt; entry : props.entrySet()) {
            entry.setValue(substVars(entry.getValue(), entry.getKey(), null,
                props));
        }

        // look for context:/ URLs to substitute
        for (Entry&amp;lt;String, String&amp;gt; entry : props.entrySet()) {
            String name = entry.getKey();
            String value = entry.getValue();
            if (value != null &amp;amp;&amp;amp; value.startsWith(&amp;quot;context:/&amp;quot;)) {
                String path = value.substring(&amp;quot;context:/&amp;quot;.length() - 1);

                InputStream src = this.resourceProvider.getResourceAsStream(path);
                if (src != null) {
                    File target = new File(slingHome, path);
                    OutputStream dest = null;
                    try {
                        // only copy file if not existing
                        if (!target.exists()) {
                            target.getParentFile().mkdirs();
                            dest = new FileOutputStream(target);
                            byte[] buf = new byte[2048];
                            int rd;
                            while ((rd = src.read(buf)) &amp;gt;= 0) {
                                dest.write(buf, 0, rd);
                            }
                        }

                        // after copying replace property and add url property
                        entry.setValue(target.getAbsolutePath());

                        // also set the new property on the unsubstituted props
                        origProps.put(name, &amp;quot;${sling.home}&amp;quot; + path);

                    } catch (IOException ioe) {
                        this.logger.log(Logger.LOG_ERROR, &amp;quot;Cannot copy file &amp;quot;
                            + value + &amp;quot; to &amp;quot; + target, ioe);
                    } finally {
                        if (dest != null) {
                            try {
                                dest.close();
                            } catch (IOException ignore) {
                            }
                        }
                        try {
                            src.close();
                        } catch (IOException ignore) {
                        }
                    }
                }
            }
        }

        // write the unsubstituted properties back to the overlay file
        OutputStream os = null;
        try {
            // ensure parent folder(s)
            propFile.getParentFile().mkdirs();

            os = new FileOutputStream(propFile);

            // copy the values into a temporary properties structure to store
            Properties tmp = new Properties();
            tmp.putAll(origProps);
            tmp.store(os, &amp;quot;Overlay properties for configuration&amp;quot;);
        } catch (Exception ex) {
            this.logger.log(Logger.LOG_ERROR,
                &amp;quot;Error loading overlay properties from &amp;quot; + propFile, ex);
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException ex2) {
                    // Nothing we can do.
                }
            }
        }

        return props;
    }

    /**
     * Scans the properties for any properties starting with the given
     * &amp;lt;code&amp;gt;prefix&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;sling.bootdelegation.&amp;lt;/code&amp;gt;).
     * &amp;lt;ol&amp;gt;
     * &amp;lt;li&amp;gt;Each such property is checked, whether it actually starts with
     * &amp;lt;code&amp;gt;prefix&amp;lt;b&amp;gt;class.&amp;lt;/b&amp;gt;&amp;lt;/code&amp;gt;. If so, the rest of the property
     * name is assumed to be a fully qualified class name which is check,
     * whether it is visible. If so, the value of the property is appended to
     * the value of the &amp;lt;code&amp;gt;osgiProp&amp;lt;/code&amp;gt;. If the class cannot be loaded,
     * the property is ignored.
     * &amp;lt;li&amp;gt;Otherwise, if the property does not contain a fully qualified class
     * name, the value of the property is simply appended to the
     * &amp;lt;code&amp;gt;osgiProp&amp;lt;/code&amp;gt;.
     * &amp;lt;/ol&amp;gt;
     *
     * @param props The &amp;lt;code&amp;gt;Properties&amp;lt;/code&amp;gt; to be scanned.
     * @param osgiProp The name of the property in &amp;lt;code&amp;gt;props&amp;lt;/code&amp;gt; to which
     *            any matching property values are appended.
     * @param prefix The prefix of properties to handle.
     */
    private void resolve(Map&amp;lt;String, String&amp;gt; props, String osgiProp,
            String prefix) {
        final String propVal = props.get(osgiProp);
        StringBuffer prop = new StringBuffer(propVal == null ? &amp;quot;&amp;quot; : propVal);
        boolean mod = false;
        for (Entry&amp;lt;String, String&amp;gt; pEntry : props.entrySet()) {
            String key = pEntry.getKey();
            if (key.startsWith(prefix)) {
                if (key.indexOf(&amp;quot;class.&amp;quot;) == prefix.length()) {
                    // prefix is followed by checker class name
                    String className = key.substring(prefix.length()
                        + &amp;quot;class.&amp;quot;.length());
                    try {
                        Class.forName(className, true,
                            this.getClass().getClassLoader());
                    } catch (Throwable t) {
                        // don't really care, but class checking failed, so we
                        // do not add
                        this.logger.log(Logger.LOG_DEBUG, &amp;quot;Class &amp;quot; + className
                            + &amp;quot; not found. Ignoring '&amp;quot; + pEntry.getValue()
                            + &amp;quot;' for property &amp;quot; + osgiProp);
                        continue;
                    }
                }

                // get here if class is known or no checker class
                this.logger.log(Logger.LOG_DEBUG, &amp;quot;Adding '&amp;quot;
                    + pEntry.getValue() + &amp;quot;' to property &amp;quot; + osgiProp);
                if (prop.length() &amp;gt; 0) {
                    prop.append(',');
                }
                prop.append(pEntry.getValue());
                mod = true;
            }
        }

        // replace the property with the modified property
        if (mod) {
            this.logger.log(Logger.LOG_DEBUG, &amp;quot;Setting property &amp;quot; + osgiProp
                + &amp;quot; to &amp;quot; + prop.toString());
            props.put(osgiProp, prop.toString());
        }
    }

    private void setInstallBundles(Map&amp;lt;String, String&amp;gt; props) {
        String prefix = &amp;quot;sling.install.&amp;quot;;
        Set&amp;lt;String&amp;gt; levels = new TreeSet&amp;lt;String&amp;gt;();
        for (String key : props.keySet()) {
            if (key.startsWith(prefix)) {
                levels.add(key.substring(prefix.length()));
            }
        }

        StringBuffer buf = new StringBuffer();
        for (String level : levels) {
            if (buf.length() &amp;gt; 0) {
                buf.append(',');
            }
            buf.append(level);
        }

        props.put(prefix + &amp;quot;bundles&amp;quot;, buf.toString());
    }

    /**
     * Ensures sensible Execution Environment setting. If the
     * &amp;lt;code&amp;gt;org.osgi.framework.executionenvironment&amp;lt;/code&amp;gt; property is set in
     * the configured properties or the system properties, we ensure that older
     * settings for J2SE-1.2, J2SE-1.3 and J2SE-1.4 are included. If the
     * property is neither set in the configuration properties nor in the system
     * properties, the property is not set.
     *
     * @param props The configuration properties to check and optionally ammend.
     */
    private void setExecutionEnvironment(Map&amp;lt;String, String&amp;gt; props) {
        // get the current Execution Environment setting
        String ee = props.get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
        if (ee == null) {
            ee = System.getProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
        }

        // if there is a setting, ensure J2SE-1.2/3/4/5 is included in the list
        if (ee != null) {
            int javaMinor;
            try {
                String specVString = System.getProperty(&amp;quot;java.specification.version&amp;quot;);
                javaMinor = Version.parseVersion(specVString).getMinor();
            } catch (IllegalArgumentException iae) {
                // don't care, assume minimal sling version (1.5)
                javaMinor = 5;
            }

            for (int i = 2; i &amp;lt;= javaMinor; i++) {
                String exEnv = &amp;quot;J2SE-1.&amp;quot; + i;
                if (ee.indexOf(exEnv) &amp;lt; 0) {
                    ee += &amp;quot;,&amp;quot; + exEnv;
                }
            }

            this.logger.log(Logger.LOG_INFO,
                &amp;quot;Using Execution Environment setting: &amp;quot; + ee);
            props.put(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, ee);
        } else {
            this.logger.log(Logger.LOG_INFO,
                &amp;quot;Not using Execution Environment setting&amp;quot;);
        }
    }

    // ---------- Extension support --------------------------------------------

    /**
     * Loads additional properties into the &amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt; object.
     * &amp;lt;p&amp;gt;
     * This implementation does nothing and may be overwritten by extensions
     * requiring additional properties to be set.
     * &amp;lt;p&amp;gt;
     * This method is called when the servlet is initialized to prepare the
     * configuration for &amp;lt;code&amp;gt;Felix&amp;lt;/code&amp;gt;. Implementations may add
     * properties from implementation specific sources. Properties added here
     * overwrite properties loaded from the default properties file and may be
     * overwritten by parameters set in the web application.
     * &amp;lt;p&amp;gt;
     * The &amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt; object has not undergone variable
     * substition and properties added by this method may also contain values
     * refererring to other properties.
     * &amp;lt;p&amp;gt;
     * The properties added in this method will not be persisted in the
     * &amp;lt;code&amp;gt;sling.properties&amp;lt;/code&amp;gt; file in the &amp;lt;code&amp;gt;sling.home&amp;lt;/code&amp;gt;
     * directory.
     *
     * @param properties The &amp;lt;code&amp;gt;Properties&amp;lt;/code&amp;gt; object to which custom
     *            properties may be added.
     */
    protected void loadPropertiesOverride(Map&amp;lt;String, String&amp;gt; properties) {
    }

    /**
     * Returns the &amp;lt;code&amp;gt;BundleContext&amp;lt;/code&amp;gt; of the system bundle of the OSGi
     * framework launched by this servlet. This method only returns a non-&amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;
     * object after the system bundle of the framework has been started and
     * before it is being stopped.
     */
    protected final BundleContext getBundleContext() {
        return this.bundleContext;
    }

    /**
     * Executes additional startup tasks and is called by the
     * {@link #start(BundleContext)} method.
     * &amp;lt;p&amp;gt;
     * This implementation does nothing and may be overwritten by extensions
     * requiring additional startup tasks.
     *
     * @throws Exception May be thrown in case of problems.
     */
    protected void doStartBundle() throws Exception {
    }

    /**
     * Executes additional shutdown tasks and is called by the
     * {@link #stop(BundleContext)} method.
     * &amp;lt;p&amp;gt;
     * This implementation does nothing and may be overwritten by extensions
     * requiring additional shutdown tasks.
     * &amp;lt;p&amp;gt;
     * When overwriting this method, it must be made sure, that no exception may
     * be thrown, otherwise unexpected behaviour may result.
     */
    protected void doStopBundle() {
    }

    // ---------- Property file support ----------------------------------------

    /**
     * Looks for &amp;lt;code&amp;gt;sling.include&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;sling.include.*&amp;lt;/code&amp;gt;
     * properties in the &amp;lt;code&amp;gt;props&amp;lt;/code&amp;gt; and loads properties form the
     * respective locations.
     * &amp;lt;p&amp;gt;
     * Each &amp;lt;code&amp;gt;sling.include&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;sling.include.*&amp;lt;/code&amp;gt;)
     * property may contain a comma-separated list of resource and/or file names
     * to be loaded from. The includes are loaded in alphabetical order of the
     * property names.
     * &amp;lt;p&amp;gt;
     * Each reasource path is first tried to be loaded through the
     * {@link #resourceProvider}. If that fails, the resource path is tested as
     * a file. If relative &amp;lt;code&amp;gt;slingHome&amp;lt;/code&amp;gt; is used as the parent if not
     * &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;, otherwise the current working directory is used as
     * the parent.
     * &amp;lt;p&amp;gt;
     * Any non-existing resource is silently ignored.
     * &amp;lt;p&amp;gt;
     * When the method returns, the &amp;lt;code&amp;gt;sling.include&amp;lt;/code&amp;gt; and
     * &amp;lt;code&amp;gt;sling.include.*&amp;lt;/code&amp;gt; properties are not contained in the
     * &amp;lt;code&amp;gt;props&amp;lt;/code&amp;gt; any more.
     *
     * @param props The &amp;lt;code&amp;gt;Properties&amp;lt;/code&amp;gt; containing the
     *            &amp;lt;code&amp;gt;sling.include&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;sling.include.*&amp;lt;/code&amp;gt;
     *            properties. This is also the destination for the new
     *            properties loaded.
     * @param slingHome The parent directory used to resolve relative path names
     *            if loading from a file. This may be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; in
     *            which case the current working directory is used as the
     *            parent.
     */
    private void loadIncludes(Map&amp;lt;String, String&amp;gt; props, String slingHome) {
        // Build the sort map of include properties first
        // and remove include elements from the properties
        SortedMap&amp;lt;String, String&amp;gt; includes = new TreeMap&amp;lt;String, String&amp;gt;();
        for (Iterator&amp;lt;Entry&amp;lt;String, String&amp;gt;&amp;gt; pi = props.entrySet().iterator(); pi.hasNext();) {
            Entry&amp;lt;String, String&amp;gt; entry = pi.next();
            if (entry.getKey().startsWith(&amp;quot;sling.include.&amp;quot;)
                || entry.getKey().equals(&amp;quot;sling.include&amp;quot;)) {
                includes.put(entry.getKey(), entry.getValue());
                pi.remove();
            }
        }

        for (Iterator&amp;lt;Entry&amp;lt;String, String&amp;gt;&amp;gt; ii = includes.entrySet().iterator(); ii.hasNext();) {
            Map.Entry&amp;lt;String, String&amp;gt; entry = ii.next();
            String key = entry.getKey();
            String include = entry.getValue();

            // ensure variable resolution on this property
            include = substVars(include, key, null, props);

            StringTokenizer tokener = new StringTokenizer(include, &amp;quot;,&amp;quot;);
            while (tokener.hasMoreTokens()) {
                String file = tokener.nextToken().trim();
                InputStream is = this.resourceProvider.getResourceAsStream(file);
                try {
                    if (is == null &amp;amp;&amp;amp; slingHome != null) {
                        File resFile = new File(file);
                        if (!resFile.isAbsolute()) {
                            resFile = new File(slingHome, file);
                        }
                        if (resFile.canRead()) {
                            is = new FileInputStream(resFile);
                            file = resFile.getAbsolutePath(); // for logging
                        }
                    }

                    if (is != null) {
                        this.load(props, is);
                    }
                } catch (IOException ioe) {
                    this.logger.log(Logger.LOG_ERROR,
                        &amp;quot;Error loading config properties from &amp;quot; + file, ioe);
                }
            }
        }
    }

    /**
     * Load properties from the given resource file, which is accessed through
     * the {@link #resourceProvider}. If the resource does not exist, nothing
     * is loaded.
     *
     * @param props The &amp;lt;code&amp;gt;Properties&amp;lt;/code&amp;gt; into which the loaded
     *            properties are loaded
     * @param resource The resource from which to load the resources
     */
    private void load(Map&amp;lt;String, String&amp;gt; props, String resource) {
        InputStream is = this.resourceProvider.getResourceAsStream(resource);
        if (is != null) {
            try {
                this.load(props, is);
            } catch (IOException ioe) {
                this.logger.log(Logger.LOG_ERROR,
                    &amp;quot;Error loading config properties from &amp;quot; + resource, ioe);
            }
        }
    }

    /**
     * Load properties from the given file. If the resource cannot be read from
     * (e.g. because it does not exist), nothing is loaded.
     *
     * @param props The &amp;lt;code&amp;gt;Properties&amp;lt;/code&amp;gt; into which the loaded
     *            properties are loaded
     * @param file The &amp;lt;code&amp;gt;File&amp;lt;/code&amp;gt; to load the properties from
     */
    private void load(Map&amp;lt;String, String&amp;gt; props, File file) {
        if (file != null &amp;amp;&amp;amp; file.canRead()) {
            try {
                this.load(props, new FileInputStream(file));
            } catch (IOException ioe) {
                this.logger.log(Logger.LOG_ERROR,
                    &amp;quot;Error loading config properties from &amp;quot;
                        + file.getAbsolutePath(), ioe);
            }
        }
    }

    private void load(Map&amp;lt;String, String&amp;gt; props, InputStream ins)
            throws IOException {
        try {
            Properties tmp = new Properties();
            tmp.load(ins);

            for (Map.Entry&amp;lt;Object, Object&amp;gt; entry : tmp.entrySet()) {
                props.put((String) entry.getKey(), (String) entry.getValue());
            }
        } finally {
            try {
                ins.close();
            } catch (IOException ioe2) {
                // ignore
            }
        }
    }

    // ---------- Property file variable substition support --------------------

    /**
     * The starting delimiter of variable names (value is &amp;quot;${&amp;quot;).
     */
    private static final String DELIM_START = &amp;quot;${&amp;quot;;

    /**
     * The ending delimiter of variable names (value is &amp;quot;}&amp;quot;).
     */
    private static final String DELIM_STOP = &amp;quot;}&amp;quot;;

    /**
     * This method performs property variable substitution on the specified
     * value. If the specified value contains the syntax
     * &amp;lt;tt&amp;gt;${&amp;amp;lt;prop-name&amp;amp;gt;}&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;&amp;amp;lt;prop-name&amp;amp;gt;&amp;lt;/tt&amp;gt;
     * refers to either a configuration property or a system property, then the
     * corresponding property value is substituted for the variable placeholder.
     * Multiple variable placeholders may exist in the specified value as well
     * as nested variable placeholders, which are substituted from inner most to
     * outer most. Configuration properties override system properties.
     *
     * @param val The string on which to perform property substitution.
     * @param currentKey The key of the property being evaluated used to detect
     *            cycles.
     * @param cycleMap Map of variable references used to detect nested cycles.
     * @param configProps Set of configuration properties.
     * @return The value of the specified string after system property
     *         substitution.
     * @throws IllegalArgumentException If there was a syntax error in the
     *             property placeholder syntax or a recursive variable
     *             reference.
     */
    private static String substVars(String val, String currentKey,
            Map&amp;lt;String, String&amp;gt; cycleMap, Map&amp;lt;String, String&amp;gt; configProps)
            throws IllegalArgumentException {
        // If there is currently no cycle map, then create
        // one for detecting cycles for this invocation.
        if (cycleMap == null) {
            cycleMap = new HashMap&amp;lt;String, String&amp;gt;();
        }

        // Put the current key in the cycle map.
        cycleMap.put(currentKey, currentKey);

        // Assume we have a value that is something like:
        // &amp;quot;leading ${foo.${bar}} middle ${baz} trailing&amp;quot;

        // Find the first ending '}' variable delimiter, which
        // will correspond to the first deepest nested variable
        // placeholder.
        int stopDelim = val.indexOf(DELIM_STOP);

        // Find the matching starting &amp;quot;${&amp;quot; variable delimiter
        // by looping until we find a start delimiter that is
        // greater than the stop delimiter we have found.
        int startDelim = val.indexOf(DELIM_START);
        while (stopDelim &amp;gt;= 0) {
            int idx = val.indexOf(DELIM_START, startDelim
                + DELIM_START.length());
            if ((idx &amp;lt; 0) || (idx &amp;gt; stopDelim)) {
                break;
            } else if (idx &amp;lt; stopDelim) {
                startDelim = idx;
            }
        }

        // If we do not have a start or stop delimiter, then just
        // return the existing value.
        if ((startDelim &amp;lt; 0) &amp;amp;&amp;amp; (stopDelim &amp;lt; 0)) {
            return val;
        }
        // At this point, we found a stop delimiter without a start,
        // so throw an exception.
        else if (((startDelim &amp;lt; 0) || (startDelim &amp;gt; stopDelim))
            &amp;amp;&amp;amp; (stopDelim &amp;gt;= 0)) {
            throw new IllegalArgumentException(
                &amp;quot;stop delimiter with no start delimiter: &amp;quot; + val);
        }

        // At this point, we have found a variable placeholder so
        // we must perform a variable substitution on it.
        // Using the start and stop delimiter indices, extract
        // the first, deepest nested variable placeholder.
        String variable = val.substring(startDelim + DELIM_START.length(),
            stopDelim);

        // Verify that this is not a recursive variable reference.
        if (cycleMap.get(variable) != null) {
            throw new IllegalArgumentException(&amp;quot;recursive variable reference: &amp;quot;
                + variable);
        }

        // Get the value of the deepest nested variable placeholder.
        // Try to configuration properties first.
        String substValue = (configProps != null)
                ? configProps.get(variable)
                : null;
        if (substValue == null) {
            // Ignore unknown property values.
            substValue = System.getProperty(variable, &amp;quot;&amp;quot;);
        }

        // Remove the found variable from the cycle map, since
        // it may appear more than once in the value and we don't
        // want such situations to appear as a recursive reference.
        cycleMap.remove(variable);

        // Append the leading characters, the substituted value of
        // the variable, and the trailing characters to get the new
        // value.
        val = val.substring(0, startDelim) + substValue
            + val.substring(stopDelim + DELIM_STOP.length(), val.length());

        // Now perform substitution again, since there could still
        // be substitutions to make.
        val = substVars(val, currentKey, cycleMap, configProps);

        // Return the value.
        return val;
    }
}&lt;/pre&gt;
&lt;a name="org.apache.sling.launcher.app.BootstrapInstaller"&gt;&lt;/a&gt;

&lt;h4&gt;&lt;code&gt;org.apache.sling.launcher.app.BootstrapInstaller&lt;/code&gt;, Revision 688973&lt;/h4&gt;

&lt;pre class="java" name="code"&gt;/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * &amp;quot;License&amp;quot;); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * &amp;quot;AS IS&amp;quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.sling.launcher.app;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.felix.framework.Logger;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.startlevel.StartLevel;

/**
 * The &amp;lt;code&amp;gt;BootstrapInstaller&amp;lt;/code&amp;gt; class is installed into the OSGi
 * framework as an activator to be called when the framework is starting up.
 * Upon startup all bundles from the {@link #PATH_CORE_BUNDLES} and the
 * {@link #PATH_BUNDLES} location are checked whether they are already installed
 * or not. If they are not installed, they are installed, their start level set
 * to 1 and started. Any bundle already installed is not installed again and
 * will also not be started here.
 */
class BootstrapInstaller implements BundleActivator {

    /**
     * The Bundle location scheme (protocol) used for bundles installed by this
     * activator (value is &amp;quot;slinginstall:&amp;quot;). The path part of the Bundle
     * location of Bundles installed by this class is the name (without the
     * path) of the resource from which the Bundle was installed.
     */
    public static final String SCHEME = &amp;quot;slinginstall:&amp;quot;;

    /**
     * The location the core Bundles (value is &amp;quot;resources/corebundles&amp;quot;). These
     * bundles are installed first.
     */
    public static final String PATH_CORE_BUNDLES = &amp;quot;resources/corebundles&amp;quot;;

    /**
     * The location the additional Bundles (value is &amp;quot;resources/bundles&amp;quot;). These
     * Bundles are installed after the {@link #PATH_CORE_BUNDLES core Bundles}.
     */
    public static final String PATH_BUNDLES = &amp;quot;resources/bundles&amp;quot;;

    /**
     * The {@link Logger} use for logging messages during installation and
     * startup.
     */
    private final Logger logger;

    /**
     * The {@link ResourceProvider} used to access the Bundle jar files to
     * install.
     */
    private final ResourceProvider resourceProvider;

    /** The data file which works as a marker to detect the first startup. */
    private static final String DATA_FILE = &amp;quot;bootstrapinstaller.ser&amp;quot;;

    BootstrapInstaller(Logger logger, ResourceProvider resourceProvider) {
        this.logger = logger;
        this.resourceProvider = resourceProvider;
    }

    /**
     * Installs any Bundles missing in the current framework instance. The
     * Bundles are verified by the Bundle location string. All missing Bundles
     * are first installed and then started in the order of installation.
     * Also install all deployment packages.
     *
     * This installation stuff is only performed during the first startup!
     */
    public void start(BundleContext context) throws Exception {
        boolean alreadyInstalled = false;
        final File dataFile = context.getDataFile(DATA_FILE);
        if ( dataFile != null &amp;amp;&amp;amp; dataFile.exists() ) {
            try {
                final FileInputStream fis = new FileInputStream(dataFile);
                try {
                    final ObjectInputStream ois = new ObjectInputStream(fis);
                    try {
                        alreadyInstalled = ois.readBoolean();
                    } finally {
                        try {
                            ois.close();
                        } catch (IOException ignore) {}
                    }
                } finally {
                    try {
                        fis.close();
                    } catch (IOException ignore) {}
                }
            } catch (IOException ioe) {
                logger.log(Logger.LOG_ERROR, &amp;quot;IOException during reading of installed flag.&amp;quot;, ioe);
            }
        }

        if ( !alreadyInstalled ) {
            // register deployment package support
            final DeploymentPackageInstaller dpi =
                new DeploymentPackageInstaller(context, logger, resourceProvider);
            context.addFrameworkListener(dpi);
            context.addServiceListener(dpi, &amp;quot;(&amp;quot;
                    + Constants.OBJECTCLASS + &amp;quot;=&amp;quot; + DeploymentPackageInstaller.DEPLOYMENT_ADMIN + &amp;quot;)&amp;quot;);

            // list all existing bundles
            Bundle[] bundles = context.getBundles();
            Map&amp;lt;String, Bundle&amp;gt; byLocation = new HashMap&amp;lt;String, Bundle&amp;gt;();
            for (int i = 0; i &amp;lt; bundles.length; i++) {
                byLocation.put(bundles[i].getLocation(), bundles[i]);
            }

            // install bundles
            List&amp;lt;Bundle&amp;gt; installed = new LinkedList&amp;lt;Bundle&amp;gt;();
            installBundles(context, byLocation, PATH_CORE_BUNDLES, installed);
            installBundles(context, byLocation, PATH_BUNDLES, installed);

            try {
                final FileOutputStream fos = new FileOutputStream(dataFile);
                try {
                    final ObjectOutputStream oos = new ObjectOutputStream(fos);
                    try {
                        oos.writeBoolean(true);
                    } finally {
                        try {
                            oos.close();
                        } catch (IOException ignore) {}
                    }
                } finally {
                    try {
                        fos.close();
                    } catch (IOException ignore) {}
                }
            } catch (IOException ioe) {
                logger.log(Logger.LOG_ERROR, &amp;quot;IOException during writing of installed flag.&amp;quot;, ioe);
            }

            // set start levels on the bundles and start them
            startBundles(context, installed);
        }
    }

    /** Nothing to be done on stop */
    public void stop(BundleContext context) {
    }

    /**
     * Install the Bundles from JAR files found in the given &amp;lt;code&amp;gt;parent&amp;lt;/code&amp;gt;
     * path.
     *
     * @param context The &amp;lt;code&amp;gt;BundleContext&amp;lt;/code&amp;gt; used to install the new
     *            Bundles.
     * @param currentBundles The currently installed Bundles indexed by their
     *            Bundle location.
     * @param parent The path to the location in which to look for JAR files to
     *            install. Only resources whose name ends with &amp;lt;em&amp;gt;.jar&amp;lt;/em&amp;gt;
     *            are considered for installation.
     * @param installed The list of Bundles installed by this method. Each
     *            Bundle successfully installed is added to this list.
     */
    private void installBundles(BundleContext context,
            Map&amp;lt;String, Bundle&amp;gt; currentBundles, String parent,
            List&amp;lt;Bundle&amp;gt; installed) {

        Iterator&amp;lt;String&amp;gt; res = resourceProvider.getChildren(parent);
        while (res.hasNext()) {

            String path = res.next();

            if (path.endsWith(&amp;quot;.jar&amp;quot;)) {

                // check for an already installed Bundle with the given location
                String location = SCHEME
                    + path.substring(path.lastIndexOf('/') + 1);
                if (currentBundles.containsKey(location)) {
                    continue;
                }

                // try to access the JAR file, ignore if not possible
                InputStream ins = resourceProvider.getResourceAsStream(path);
                if (ins == null) {
                    continue;
                }

                // install the JAR file as a bundle
                Bundle newBundle;
                try {
                    newBundle = context.installBundle(location, ins);
                    logger.log(Logger.LOG_INFO, &amp;quot;Bundle &amp;quot;
                        + newBundle.getSymbolicName() + &amp;quot; installed from &amp;quot;
                        + location);
                } catch (BundleException be) {
                    logger.log(Logger.LOG_ERROR, &amp;quot;Bundle installation from &amp;quot;
                        + location + &amp;quot; failed&amp;quot;, be);
                    continue;
                }

                // finally add the bundle to the list for later start
                installed.add(newBundle);
            }
        }
    }

    /**
     * Starts the Bundles in the &amp;lt;code&amp;gt;bundles&amp;lt;/code&amp;gt; list. If the framework
     * provides an active &amp;lt;code&amp;gt;StartLevel&amp;lt;/code&amp;gt; service, the start levels of
     * the Bundles is first set to &amp;lt;em&amp;gt;1&amp;lt;/em&amp;gt;.
     */
    private void startBundles(BundleContext context, List&amp;lt;Bundle&amp;gt; bundles) {

        // the start level service to set the initial start level
        ServiceReference ref = context.getServiceReference(StartLevel.class.getName());
        StartLevel startLevel = (ref != null)
                ? (StartLevel) context.getService(ref)
                : null;

        // start all bundles
        for (Bundle bundle : bundles) {

            if (startLevel != null) {
                startLevel.setBundleStartLevel(bundle, 1);
            }

            try {
                bundle.start();
            } catch (BundleException be) {
                logger.log(Logger.LOG_ERROR, &amp;quot;Bundle &amp;quot;
                    + bundle.getSymbolicName() + &amp;quot; could not be started&amp;quot;, be);
            }
        }

        // release the start level service
        if (ref != null) {
            context.ungetService(ref);
        }
    }

}&lt;/pre&gt;
&lt;a name="org.apache.sling.launcher.app.main.Main"&gt;&lt;/a&gt;

&lt;h4&gt;&lt;code&gt;org.apache.sling.launcher.app.main.Main&lt;/code&gt;, Revision 667440&lt;/h4&gt;

&lt;pre class="java" name="code"&gt;/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the &amp;quot;License&amp;quot;); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sling.launcher.app.main;

import static org.apache.felix.framework.util.FelixConstants.LOG_LEVEL_PROP;

import java.util.HashMap;
import java.util.Map;

import org.apache.felix.framework.Logger;
import org.apache.sling.commons.log.LogManager;
import org.apache.sling.launcher.app.ClassLoaderResourceProvider;
import org.apache.sling.launcher.app.ResourceProvider;
import org.apache.sling.launcher.app.Sling;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;

/**
 * The &amp;lt;code&amp;gt;Main&amp;lt;/code&amp;gt; class is a simple Java Application which interprests
 * the command line and creates the {@link Sling} launcher class and thus starts
 * the OSGi framework. In addition a shutdown thread is registered to ensure
 * proper shutdown on VM termination.
 * &amp;lt;p&amp;gt;
 * The supported command line options are:
 * &amp;lt;dl&amp;gt;
 * &amp;lt;dt&amp;gt;-l loglevel&amp;lt;/dt&amp;gt;
 * &amp;lt;dd&amp;gt;Sets the initial loglevel as an integer in the range 0 to 4 or as one of
 * the well known level strings FATAL, ERROR, WARN, INFO or DEBUG. This option
 * overwrites the &amp;lt;code&amp;gt;org.apache.sling.osg.log.level&amp;lt;/code&amp;gt; setting the
 * &amp;lt;code&amp;gt;sling.properties&amp;lt;/code&amp;gt; file.&amp;lt;/dd&amp;gt;
 * &amp;lt;dt&amp;gt;-f logfile&amp;lt;/dt&amp;gt;
 * &amp;lt;dd&amp;gt;The log file, \&amp;quot;-\&amp;quot; for stdout (default logs/error.log). This option
 * overwrites the &amp;lt;code&amp;gt;org.apache.sling.osg.log.file&amp;lt;/code&amp;gt; setting the
 * &amp;lt;code&amp;gt;sling.properties&amp;lt;/code&amp;gt; file.&amp;lt;/dd&amp;gt;
 * &amp;lt;dt&amp;gt;-c slinghome&amp;lt;/dt&amp;gt;
 * &amp;lt;dd&amp;gt;The directory in which Sling locates its initial configuration file
 * &amp;lt;code&amp;gt;sling.properties&amp;lt;/code&amp;gt; and where files of Sling itself such as the
 * Apache Felix bundle archive or the JCR repository files are stored (default
 * sling).&amp;lt;/dd&amp;gt;
 * &amp;lt;dt&amp;gt;-a address&amp;lt;/dt&amp;gt;
 * &amp;lt;dd&amp;gt;The interfact to bind to (use 0.0.0.0 for any). This option is not
 * implemented yet.&amp;lt;/dd&amp;gt;
 * &amp;lt;dt&amp;gt;-p port&amp;lt;/dt&amp;gt;
 * &amp;lt;dd&amp;gt;The port to listen (default 8080) to handle HTTP requests. This option
 * overwrites the &amp;lt;code&amp;gt;org.osgi.service.http.port&amp;lt;/code&amp;gt; setting the
 * &amp;lt;code&amp;gt;sling.properties&amp;lt;/code&amp;gt; file.&amp;lt;/dd&amp;gt;
 * &amp;lt;dt&amp;gt;-h&amp;lt;/dt&amp;gt;
 * &amp;lt;dd&amp;gt;Prints a simple usage message listing all available command line
 * options.&amp;lt;/dd&amp;gt;
 * &amp;lt;/dl&amp;gt;
 */
public class Main {

    /** Mapping between log level numbers and names */
    private static final String[] logLevels = { &amp;quot;FATAL&amp;quot;, &amp;quot;ERROR&amp;quot;, &amp;quot;WARN&amp;quot;,
        &amp;quot;INFO&amp;quot;, &amp;quot;DEBUG&amp;quot; };

    /** The Sling configuration property name setting the initial log level */
    private static final String PROP_LOG_LEVEL = LogManager.LOG_LEVEL;

    /** The Sling configuration property name setting the initial log file */
    private static final String PROP_LOG_FILE = LogManager.LOG_FILE;

    /** Default log level setting if no set on command line (value is &amp;quot;INFO&amp;quot;). */
    private static final int DEFAULT_LOG_LEVEL = Logger.LOG_INFO;

    /**
     * The configuration property setting the port on which the HTTP service
     * listens
     */
    private static final String PROP_PORT = &amp;quot;org.osgi.service.http.port&amp;quot;;

    /** The default port on which the HTTP service listens. */
    private static final String DEFAULT_PORT = &amp;quot;8080&amp;quot;;

    /**
     * The property value to export the Servlet API 2.5 from the system
     * bundle.
     */
    private static final String SERVLET_API_EXPORT =
        &amp;quot;javax.servlet;javax.servlet.http;javax.servlet.resources; version=2.5&amp;quot;;

    /** The parsed command line mapping (Sling) option name to option value */
    private static Map&amp;lt;String, String&amp;gt; commandLine;

    public static void main(String[] args) throws Exception {
        // creating the instance launches the framework and we are done here ..
        Map&amp;lt;String, String&amp;gt; props = new HashMap&amp;lt;String, String&amp;gt;();

        // parse the command line (exit in case of failure)
        commandLine = new HashMap&amp;lt;String, String&amp;gt;();
        commandLine.put(PROP_PORT, DEFAULT_PORT);
        parseCommandLine(args, commandLine);

        // if sling.home was set on the command line, set it in the properties
        if (commandLine.containsKey(Sling.SLING_HOME)) {
            props.put(Sling.SLING_HOME, commandLine.get(Sling.SLING_HOME));
        }

        // overwrite the loadPropertiesOverride method to inject the command
        // line arguments unconditionally. These will not be persisted in any
        // properties file, though

        // set up and configure Felix Logger
        int logLevel;
        if (!commandLine.containsKey(PROP_LOG_LEVEL)) {
            logLevel = DEFAULT_LOG_LEVEL;
        } else {
            logLevel = toLogLevelInt(commandLine.get(PROP_LOG_LEVEL),
                DEFAULT_LOG_LEVEL);
            commandLine.put(LOG_LEVEL_PROP, String.valueOf(logLevel));
        }
        Logger logger = new Logger();

        // prevent tons of needless WARN from the framework
        // logger.setLogLevel(logLevel);
        logger.setLogLevel(Logger.LOG_ERROR);

        // prevent tons of needless WARN messages from the framework
        // logger.setLogLevel(logLevel);
        logger.setLogLevel(Logger.LOG_ERROR);

        try {
            ResourceProvider resProvider = new ClassLoaderResourceProvider(
                Main.class.getClassLoader());
            Sling sling = new Sling(logger, resProvider, props) {
                protected void loadPropertiesOverride(
                        Map&amp;lt;String, String&amp;gt; properties) {
                    if (commandLine != null) {
                        properties.putAll(commandLine);
                    }

                    // add Servlet API to the system bundle exports
                    String sysExport = properties.get(Constants.FRAMEWORK_SYSTEMPACKAGES);
                    if (sysExport == null) {
                        sysExport = SERVLET_API_EXPORT;
                    } else {
                        sysExport += &amp;quot;,&amp;quot; + SERVLET_API_EXPORT;
                    }
                    properties.put(Constants.FRAMEWORK_SYSTEMPACKAGES,
                        sysExport);
                }
            };

            Runtime.getRuntime().addShutdownHook(new TerminateSling(sling));
        } catch (BundleException be) {
            log(&amp;quot;Failed to Start OSGi framework&amp;quot;);
            be.printStackTrace(System.err);
            System.exit(2);
        }
    }

    private static class TerminateSling extends Thread {
        private final Sling sling;

        TerminateSling(Sling sling) {
            super(&amp;quot;Sling Terminator&amp;quot;);
            this.sling = sling;
        }

        public void run() {
            if (this.sling != null) {
                this.sling.destroy();
            }
        }
    }

    /**
     * Parses the command line in &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; and sets appropriate Sling
     * configuration options in the &amp;lt;code&amp;gt;props&amp;lt;/code&amp;gt; map.
     */
    private static void parseCommandLine(String[] args,
            Map&amp;lt;String, String&amp;gt; props) {
        for (int argc = 0; argc &amp;lt; args.length; argc++) {
            String arg = args[argc];
            if (arg.startsWith(&amp;quot;-&amp;quot;)) {

                // require at least another character naming the option
                if (arg.length() != 2) {
                    usage(&amp;quot;Missing option name&amp;quot;, 1);
                }

                // option argument is following the current option
                argc++;
                String value = argc &amp;lt; args.length ? args[argc] : null;

                switch (arg.charAt(1)) {
                    case 'l':
                        if (value == null) {
                            usage(&amp;quot;Missing log level value&amp;quot;, 1);
                            continue;
                        }
                        try {
                            int logLevel = Integer.parseInt(value);
                            value = toLogLevel(logLevel);
                        } catch (NumberFormatException nfe) {
                            // might be a log level string
                            value = checkLogLevel(value);
                        }
                        if (value != null) {
                            props.put(PROP_LOG_LEVEL, value);
                        }
                        break;

                    case 'f':
                        if (value == null) {
                            usage(&amp;quot;Missing log file value&amp;quot;, 1);
                            continue;
                        } else if (&amp;quot;-&amp;quot;.equals(value)) {
                            value = &amp;quot;&amp;quot;;
                        }
                        props.put(PROP_LOG_FILE, value);
                        break;

                    case 'c':
                        if (value == null) {
                            usage(&amp;quot;Missing directory value&amp;quot;, 1);
                            continue;
                        }
                        props.put(Sling.SLING_HOME, value);
                        break;

                    case 'p':
                        if (value == null) {
                            usage(&amp;quot;Missing port value&amp;quot;, 1);
                            continue;
                        }
                        try {
                            // just to verify it is a number
                            Integer.parseInt(value);
                            props.put(PROP_PORT, value);
                        } catch (RuntimeException e) {
                            usage(&amp;quot;Bad port: &amp;quot; + value, 1);
                        }
                        break;

                    case 'a':
                        if (value == null) {
                            usage(&amp;quot;Missing address value&amp;quot;, 1);
                            continue;
                        }
                        log(&amp;quot;Setting the address to bind to is not supported, binding to 0.0.0.0&amp;quot;);
                        break;

                    case 'h':
                        usage(null, 0);

                    default:
                        usage(&amp;quot;Unrecognized option &amp;quot; + arg, 1);
                        break;
                }
            }
        }
    }

    /** prints a simple usage plus optional error message and exists with code */
    private static void usage(String message, int code) {
        if (message != null) {
            log(message);
            log(&amp;quot;&amp;quot;);
        }

        log(&amp;quot;usage: &amp;quot;
            + Main.class.getName()
            + &amp;quot; [ -l loglevel ] [ -f logfile ] [ -c slinghome ] [ -a address ] [ -p port ] [ -h ]&amp;quot;);

        log(&amp;quot;    -l loglevel   the initial loglevel (0..4, FATAL, ERROR, WARN, INFO, DEBUG)&amp;quot;);
        log(&amp;quot;    -f logfile    the log file, \&amp;quot;-\&amp;quot; for stdout (default logs/error.log)&amp;quot;);
        log(&amp;quot;    -c slinghome  the sling context directory (default sling)&amp;quot;);
        log(&amp;quot;    -a address    the interfact to bind to (use 0.0.0.0 for any) (not supported yet)&amp;quot;);
        log(&amp;quot;    -p port       the port to listen to (default 8080)&amp;quot;);
        log(&amp;quot;    -h            prints this usage message&amp;quot;);

        // exiting now
        System.exit(code);
    }

    /** Writes the message to stderr output */
    private static void log(String message) {
        System.err.println(message);
    }

    /** Converts the loglevel code to a loglevel string name */
    private static String toLogLevel(int level) {
        if (level &amp;gt;= 0 &amp;amp;&amp;amp; level &amp;lt; logLevels.length) {
            return logLevels[level];
        }

        usage(&amp;quot;Bad log level: &amp;quot; + level, 1);
        return null;
    }

    /** Verifies the log level is one of the known values, returns null otherwise */
    private static String checkLogLevel(String level) {
        for (int i = 0; i &amp;lt; logLevels.length; i++) {
            if (logLevels[i].equalsIgnoreCase(level)) {
                return logLevels[i];
            }
        }

        usage(&amp;quot;Bad log level: &amp;quot; + level, 1);
        return null;
    }

    /** Return the log level code for the string */
    private static int toLogLevelInt(String level, int defaultLevel) {
        for (int i = 0; i &amp;lt; logLevels.length; i++) {
            if (logLevels[i].equalsIgnoreCase(level)) {
                return i;
            }
        }

        return defaultLevel;
    }
}&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5750351649256467689-7496544646489672769?l=in-the-sling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/7496544646489672769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5750351649256467689&amp;postID=7496544646489672769' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/7496544646489672769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/7496544646489672769'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/2008/09/inside-sling-how-sling-boots.html' title='Inside Sling: How Sling boots'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/moritz.havelock/SNenJUN2ANI/AAAAAAAAACM/hnQeFx8FFZM/s72-c/launchpad%20classes_thumb%5B7%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5750351649256467689.post-2228836231618815339</id><published>2008-09-09T10:22:00.001+02:00</published><updated>2008-09-09T10:22:38.119+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sling'/><category scheme='http://www.blogger.com/atom/ns#' term='crx'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><title type='text'>Sling OSGi Track pt 7: configuring services at runtime</title><content type='html'>&lt;p&gt;This is the continuation of&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html"&gt;Sling OSGi Track pt 1: hand-rolled service bundle&lt;/a&gt; and &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-2-using-felix.html"&gt;Sling OSGi Track pt 2: using Felix' bundle plugin for manifest entries&lt;/a&gt; and &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-3-replacing.html"&gt;Sling OSGi Track pt 3: replacing the Activator with DS&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-4-installing-to.html"&gt;Sling OSGi Track pt 4: installing to Sling using Maven&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/09/how-to-use-json-query-servlet.html"&gt;Sling OSGi Track pt 5: Bundling initial content&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/09/sling-osgi-track-pt-6-sling-servlets-i.html"&gt;Sling OSGI Track pt 6: Sling Servlets I&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In this part, I will explain how to use the OSGi configuration management to configure services at runtime.&lt;/p&gt;  &lt;p&gt;Suppose I want a service that can do more than just say &amp;quot;hello&amp;quot;. I want the phrase the service returns from the &lt;code&gt;sayHello()&lt;/code&gt; method to be configurable at runtime. This is easily done through OSGi configuration management.&lt;/p&gt;  &lt;h4&gt;Aims:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Show how to introduce a configurable property into an OSGi bundle &lt;/li&gt;    &lt;li&gt;Show how to change the configuration through the OSGi configuration manager &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Ingredients:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://dev.day.com/microsling/content/blogs/cup/downloads.c.html"&gt;CRX quickstart&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html"&gt;Bundle Plugin for Maven&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-scr-plugin.html"&gt;SCR Plugin for Maven&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://incubator.apache.org/sling/site/sling.html"&gt;Maven Sling Plugin&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-configuration-admin-service.html"&gt;Felix' Configuration Admin Service implementation&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Files:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a title="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.7.jar" href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.7.jar"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.7.jar&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a title="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.7-sources.jar" href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.7-sources.jar"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.7-sources.jar&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Outline:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Project Structure &lt;/li&gt;    &lt;li&gt;Changes to the implementation &lt;/li&gt;    &lt;li&gt;The pom &lt;/li&gt;    &lt;li&gt;The results &lt;/li&gt;    &lt;li&gt;Testing &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Execution&lt;/h4&gt;  &lt;h5&gt;Project Structure&lt;/h5&gt;  &lt;p&gt;From here on, I am no longer bundling the sample client script, as we've done our own client servlet in part 6 of this track. So we're back to just the pom, the interface and the implementation.&lt;/p&gt;  &lt;pre class="plain" name="code"&gt;.
|-- pom.xml
`-- src
    `-- main
        `-- java
            `-- mh
                `-- osgitest
                    |-- SampleService.java
                    `-- SampleServiceImpl.java&lt;/pre&gt;

&lt;h5&gt;Changes to the implementation&lt;/h5&gt;

&lt;p&gt;The only semantic change is in lines 18 and 21: a property &lt;code&gt;helloPhrase&lt;/code&gt; is introduced and the value that is returned from the &amp;quot;sayHello()&amp;quot; method is read from that property.&lt;/p&gt;

&lt;p&gt;Lines 11-14 introduce a constant, &lt;code&gt;PROP_HELLO_PHRASE&lt;/code&gt;. The value of that constant will be used as a key to store the actual value. Line 12 points to the &lt;code&gt;DEFAULT_HELLO_PHRASE&lt;/code&gt; constant for the default value. The following would have been equivalent, but it's better practice to use constants, so that the default value can be reffered to from Java code.&lt;/p&gt;

&lt;pre class="java:firstline[11]" name="code"&gt;	/**
	 * @scr.property value=&amp;quot;hello&amp;quot;
	 */
	public static final String PROP_HELLO_PHRASE = &amp;quot;mh.osgitest.helloPhrase&amp;quot;;&lt;/pre&gt;

&lt;p&gt;the &lt;code&gt;activate()&lt;/code&gt; method is called when the component is activated. At that point, we can obtain configuration values from the properties that are part of the &lt;code&gt;ComponentContext&lt;/code&gt; that is passed as the method's argument.&lt;/p&gt;

&lt;pre class="java" name="code"&gt;package mh.osgitest;

import org.osgi.service.component.ComponentContext;

/**
 * @scr.component immediate=&amp;quot;true&amp;quot;
 * @scr.service interface=&amp;quot;SampleService&amp;quot;
 */
public class SampleServiceImpl implements SampleService {

	/**
	 * @scr.property valueRef=&amp;quot;DEFAULT_HELLO_PHRASE&amp;quot;
	 */
	public static final String PROP_HELLO_PHRASE = &amp;quot;mh.osgitest.helloPhrase&amp;quot;;

	public static final String DEFAULT_HELLO_PHRASE = &amp;quot;hello&amp;quot;;

	private String helloPhrase;

	public String sayHello() {
		return helloPhrase;
	}

	protected void activate(ComponentContext context) {
		Object helloPhrase = context.getProperties().get(PROP_HELLO_PHRASE);
		if (helloPhrase != null)
			this.helloPhrase = helloPhrase.toString();
	}
}&lt;/pre&gt;

&lt;h5&gt;The pom&lt;/h5&gt;

&lt;p&gt;The pom is very straight forward. Nothing special here.&lt;/p&gt;

&lt;pre class="xml" name="code"&gt;&amp;lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
	xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&amp;gt;
	&amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
	&amp;lt;groupId&amp;gt;mh.studies&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;mh.studies.sling.osgitest&amp;lt;/artifactId&amp;gt;
	&amp;lt;name&amp;gt;OSGI Test Bundle&amp;lt;/name&amp;gt;
	&amp;lt;version&amp;gt;0.0.7&amp;lt;/version&amp;gt;
	&amp;lt;packaging&amp;gt;bundle&amp;lt;/packaging&amp;gt;
	&amp;lt;description /&amp;gt;
	&amp;lt;build&amp;gt;
		&amp;lt;plugins&amp;gt;
			&amp;lt;plugin&amp;gt;
				&amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
				&amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
				&amp;lt;configuration&amp;gt;
					&amp;lt;source&amp;gt;1.5&amp;lt;/source&amp;gt;
					&amp;lt;target&amp;gt;1.5&amp;lt;/target&amp;gt;
				&amp;lt;/configuration&amp;gt;
			&amp;lt;/plugin&amp;gt;
			&amp;lt;plugin&amp;gt;
				&amp;lt;groupId&amp;gt;org.apache.sling&amp;lt;/groupId&amp;gt;
				&amp;lt;artifactId&amp;gt;maven-sling-plugin&amp;lt;/artifactId&amp;gt;
				&amp;lt;version&amp;gt;2.0.2-incubator&amp;lt;/version&amp;gt;
				&amp;lt;executions&amp;gt;
					&amp;lt;execution&amp;gt;
						&amp;lt;id&amp;gt;install-bundle&amp;lt;/id&amp;gt;
						&amp;lt;goals&amp;gt;
							&amp;lt;goal&amp;gt;install&amp;lt;/goal&amp;gt;
						&amp;lt;/goals&amp;gt;
						&amp;lt;configuration&amp;gt;
							&amp;lt;slingUrl&amp;gt; http://localhost:7402/system/console/install&amp;lt;/slingUrl&amp;gt;
							&amp;lt;user&amp;gt;admin&amp;lt;/user&amp;gt;
							&amp;lt;password&amp;gt;admin&amp;lt;/password&amp;gt;
						&amp;lt;/configuration&amp;gt;
					&amp;lt;/execution&amp;gt;
				&amp;lt;/executions&amp;gt;
			&amp;lt;/plugin&amp;gt;
			&amp;lt;plugin&amp;gt;
			    &amp;lt;groupId&amp;gt;org.apache.felix&amp;lt;/groupId&amp;gt;
			    &amp;lt;artifactId&amp;gt;maven-scr-plugin&amp;lt;/artifactId&amp;gt;
			    &amp;lt;version&amp;gt;1.0.7&amp;lt;/version&amp;gt;
			    &amp;lt;executions&amp;gt;
			        &amp;lt;execution&amp;gt;
			            &amp;lt;id&amp;gt;generate-scr-scrdescriptor&amp;lt;/id&amp;gt;
			            &amp;lt;goals&amp;gt;
			                &amp;lt;goal&amp;gt;scr&amp;lt;/goal&amp;gt;
			            &amp;lt;/goals&amp;gt;
			        &amp;lt;/execution&amp;gt;
			    &amp;lt;/executions&amp;gt;
			&amp;lt;/plugin&amp;gt;			
			&amp;lt;plugin&amp;gt;
				&amp;lt;groupId&amp;gt;org.apache.felix&amp;lt;/groupId&amp;gt;
				&amp;lt;artifactId&amp;gt;maven-bundle-plugin&amp;lt;/artifactId&amp;gt;
				&amp;lt;version&amp;gt;1.4.3&amp;lt;/version&amp;gt;
				&amp;lt;extensions&amp;gt;true&amp;lt;/extensions&amp;gt;
				&amp;lt;configuration&amp;gt;
					&amp;lt;instructions&amp;gt;
						&amp;lt;Export-Package&amp;gt;mh.osgitest&amp;lt;/Export-Package&amp;gt;
						&amp;lt;Import-Package&amp;gt;
                            org.osgi.framework;version=&amp;quot;1.3.0&amp;quot;,
                            org.osgi.service.component
                        &amp;lt;/Import-Package&amp;gt;
						&amp;lt;Bundle-SymbolicName&amp;gt;${pom.artifactId}&amp;lt;/Bundle-SymbolicName&amp;gt;
						&amp;lt;Bundle-Name&amp;gt;${pom.name}&amp;lt;/Bundle-Name&amp;gt;
						&amp;lt;Bundle-Vendor&amp;gt;Moritz Havelock&amp;lt;/Bundle-Vendor&amp;gt;
					&amp;lt;/instructions&amp;gt;
				&amp;lt;/configuration&amp;gt;
			&amp;lt;/plugin&amp;gt;
		&amp;lt;/plugins&amp;gt;
	&amp;lt;/build&amp;gt;
	&amp;lt;repositories&amp;gt;
		&amp;lt;repository&amp;gt;
			&amp;lt;id&amp;gt;apache.incubating&amp;lt;/id&amp;gt;
			&amp;lt;name&amp;gt;Apache Incubating Repository&amp;lt;/name&amp;gt;
			&amp;lt;url&amp;gt;http://people.apache.org/repo/m2-incubating-repository&amp;lt;/url&amp;gt;
		&amp;lt;/repository&amp;gt;
	&amp;lt;/repositories&amp;gt;
	&amp;lt;pluginRepositories&amp;gt;
		&amp;lt;pluginRepository&amp;gt;
			&amp;lt;id&amp;gt;apache.incubating.plugins&amp;lt;/id&amp;gt;
			&amp;lt;name&amp;gt;Apache Incubating Plugin Repository&amp;lt;/name&amp;gt;
			&amp;lt;url&amp;gt;http://people.apache.org/repo/m2-incubating-repository
			&amp;lt;/url&amp;gt;
		&amp;lt;/pluginRepository&amp;gt;
	&amp;lt;/pluginRepositories&amp;gt;
	&amp;lt;dependencies&amp;gt;
		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.apache.felix&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;org.osgi.core&amp;lt;/artifactId&amp;gt;
			&amp;lt;version&amp;gt;1.0.1&amp;lt;/version&amp;gt;
		&amp;lt;/dependency&amp;gt;
            &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.apache.felix&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;org.osgi.compendium&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.0.1&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
	&amp;lt;/dependencies&amp;gt;
&amp;lt;/project&amp;gt;&lt;/pre&gt;

&lt;h5&gt;The results&lt;/h5&gt;

&lt;p&gt;After deploying the Bundle, I do a quick test and call &lt;a href="http://localhost:7402/system/osgitest/info"&gt;http://localhost:7402/system/osgitest/info&lt;/a&gt;. That requires that the Servlet from the last part is still installed. If you have not followed along, grab it from here: &lt;a title="http://in-the-sling.blogspot.com/2008/09/sling-osgi-track-pt-6-sling-servlets-i.html" href="http://in-the-sling.blogspot.com/2008/09/sling-osgi-track-pt-6-sling-servlets-i.html"&gt;http://in-the-sling.blogspot.com/2008/09/sling-osgi-track-pt-6-sling-servlets-i.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As expected, I get the result &amp;quot;hello&amp;quot;.&lt;/p&gt;

&lt;p&gt;Now, I hit the OSGi configuration management console at &lt;a title="http://localhost:7402/system/console/configMgr" href="http://localhost:7402/system/console/configMgr"&gt;http://localhost:7402/system/console/configMgr&lt;/a&gt; and select my bundle from the drop down:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/moritz.havelock/SMYyR2lWCFI/AAAAAAAAAB4/OmxRJpSSNS8/s1600-h/snap002200809093.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="151" alt="snap002 2008-09-09" src="http://lh3.ggpht.com/moritz.havelock/SMYySawXHwI/AAAAAAAAAB8/z_0LpuvL5tc/snap00220080909_thumb1.png?imgmax=800" width="581" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Don't be confused by the naming of the entries. They can easily be replaced, but I will keep focused on the important stuff for a while and leave these out of consideration.&lt;/p&gt;

&lt;p&gt;I get the following screen, which allows me to configure the component's properties. In our case, that is the &amp;quot;helloPhrase&amp;quot; property, which I can change by entering a new value into the text box and hitting &amp;quot;save&amp;quot;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/moritz.havelock/SMYyS7g28vI/AAAAAAAAACA/xO8f-4pCGlM/s1600-h/snap003200809093.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="223" alt="snap003 2008-09-09" src="http://lh6.ggpht.com/moritz.havelock/SMYyTbRmlQI/AAAAAAAAACE/O2jEgowxw04/snap00320080909_thumb1.png?imgmax=800" width="563" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h5&gt;Testing&lt;/h5&gt;

&lt;p&gt;The final test is to again hit &lt;a title="http://localhost:7402/system/osgitest/info" href="http://localhost:7402/system/osgitest/info"&gt;http://localhost:7402/system/osgitest/info&lt;/a&gt;, which should now return the new value of the &amp;quot;helloPhrase&amp;quot; property.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7b13d622-921d-46d3-ab68-3b07c129e5b2" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/CRX" rel="tag"&gt;CRX&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Sling" rel="tag"&gt;Sling&lt;/a&gt;,&lt;a href="http://technorati.com/tags/OSGi" rel="tag"&gt;OSGi&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5750351649256467689-2228836231618815339?l=in-the-sling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/2228836231618815339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5750351649256467689&amp;postID=2228836231618815339' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/2228836231618815339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/2228836231618815339'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/2008/09/sling-osgi-track-pt-7-configuring.html' title='Sling OSGi Track pt 7: configuring services at runtime'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/moritz.havelock/SMYySawXHwI/AAAAAAAAAB8/z_0LpuvL5tc/s72-c/snap00220080909_thumb1.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5750351649256467689.post-2769142173443389001</id><published>2008-09-03T23:44:00.001+02:00</published><updated>2008-09-04T08:52:34.316+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sling'/><category scheme='http://www.blogger.com/atom/ns#' term='crx'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><title type='text'>Sling OSGI Track pt 6: Sling Servlets I</title><content type='html'>&lt;p&gt;This is the continuation of&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html"&gt;Sling OSGi Track pt 1: hand-rolled service bundle&lt;/a&gt; and &lt;/li&gt;   &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-2-using-felix.html"&gt;Sling OSGi Track pt 2: using Felix' bundle plugin for manifest entries&lt;/a&gt; and &lt;/li&gt;   &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-3-replacing.html"&gt;Sling OSGi Track pt 3: replacing the Activator with DS&lt;/a&gt; &lt;/li&gt;   &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-4-installing-to.html"&gt;Sling OSGi Track pt 4: installing to Sling using Maven&lt;/a&gt; &lt;/li&gt;   &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/09/how-to-use-json-query-servlet.html"&gt;Sling OSGi Track pt 5: Bundling initial content&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In this part, I will show how to create your own Sling Servlet and deploy it as an OSGi Bundle.&lt;/p&gt;  &lt;p&gt;As you may have seen from the sling documentation, there is a pretty straightforward way to create scripts on the search paths (/apps, /libs) that will be executed depending on properties of the requested resource (most notably sling:resourceType.&lt;/p&gt; &lt;p&gt;You can do the same using servlets, if you prefer.    &lt;br /&gt;Using servlets, you can also do a lot more than with scripts, and we'll have a first look at what can be done right now.   &lt;br /&gt;As a first easy example, I will show how to create a servlet that uses the service created in the previous parts and makes the output available at /system/osgitest/info .&lt;/p&gt; &lt;h4&gt;Aims:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Show how to create a Sling Servlet and register it to respond to a preset path.&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Ingredients:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://dev.day.com/microsling/content/blogs/cup/downloads.c.html"&gt;CRX quickstart&lt;/a&gt; &lt;/li&gt;   &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html"&gt;Bundle Plugin for Maven&lt;/a&gt; &lt;/li&gt;   &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-scr-plugin.html"&gt;SCR Plugin for Maven&lt;/a&gt; &lt;/li&gt;   &lt;li&gt;&lt;a href="http://incubator.apache.org/sling/site/sling.html"&gt;Maven Sling Plugin&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Files:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest.client-0.0.1-sources.jar"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest.client-0.0.1-sources.jar&lt;/a&gt;&lt;/li&gt;     &lt;li&gt;&lt;a href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest.client-0.0.1.jar"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest.client-0.0.1.jar&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Outline:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Project structure&lt;/li&gt;   &lt;li&gt;The servlet implementation&lt;/li&gt;   &lt;li&gt;The pom: nothing special&lt;/li&gt;   &lt;li&gt;Maven dependencies: oops&lt;/li&gt;   &lt;li&gt;Build, Deploy, Test&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Execution:&lt;/h4&gt; &lt;h5&gt;Project structure&lt;/h5&gt; &lt;p&gt;The project structure is simpler than anything we had so far. We actually need no more than the servlet implementation and the pom. Let's have a look:&lt;/p&gt; &lt;pre name="code" class="plain"&gt;
.
|-- pom.xml
`-- src
    `-- main
        `-- java
            `-- mh
                `-- osgitest
                    `-- client
                        `-- OsgiTestClientServlet.java
&lt;/pre&gt;						

&lt;h5&gt;The servlet implementation&lt;/h5&gt;

&lt;p&gt;Let's have a look at the servlet implementation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The servlet extends SlingSafeMethodsServlet (l. 25).&lt;br /&gt;This is a sling-provided class that can be extended to implement servlets that do not have side-effects, i.e. do not modify data. See
&lt;a href="http://svn.apache.org/viewvc/incubator/sling/trunk/api/src/main/java/org/apache/sling/api/servlets/SlingSafeMethodsServlet.java?view=markup"&gt;http://svn.apache.org/viewvc/incubator/sling/trunk/api/src/main/java/org/apache/sling/api/servlets/SlingSafeMethodsServlet.java?view=markup&lt;/a&gt; for the details.&lt;/li&gt;

&lt;li&gt;The servlet overrides the doGet method (l. 31ff).
&lt;br /&gt;In this method, it checks whether it's "service" variable is set (which is of the type 'SampleService' from our previous parts of this track), and if so calls sayHello() on the object to write the result to the output stream.
&lt;/li&gt;

&lt;li&gt;OK, so how can the service variable ever be anything but null? That happens through the src.reference directive in line 27. This will create an OSGi service descriptor, and the OSGi container will inject the reference to a SampleService instance, if available.&lt;/li&gt;

&lt;li&gt;In line 22, the &lt;code&gt;sling.servlet.paths&lt;/code&gt; property is set to &lt;code&gt;/system/osgitest/info&lt;/code&gt;. This creates the mapping to the URL &lt;code&gt;/system/osgitest/info&lt;/code&gt;, which the servlet will respond to.
&lt;br /&gt;There are many other options of creating mappings depending on the resource that is being accessed, depending on method, etc. Part of this is explained in &lt;a href="http://incubator.apache.org/sling/site/servlet-resolution.html"&gt;http://incubator.apache.org/sling/site/servlet-resolution.html&lt;/a&gt;, but that description is outdated. I'll look into the other options in further posts.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre name="code" class="java"&gt;
package mh.osgitest.client;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import mh.osgitest.SampleService;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;

/**
 * A Servlet that uses the service provided in the mh.osgitest to retrieve the
 * phrase &amp;quot;hello&amp;quot;.
 * 
 * @scr.component immediate=&amp;quot;true&amp;quot; metatype=&amp;quot;no&amp;quot;
 * @scr.service interface=&amp;quot;javax.servlet.Servlet&amp;quot;
 * @scr.property name=&amp;quot;service.description&amp;quot; value=&amp;quot;Sample OSGi Client Servlet&amp;quot;
 * @scr.property name=&amp;quot;service.vendor&amp;quot; value=&amp;quot;Moritz Havelock&amp;quot;
 * @scr.property name=&amp;quot;sling.servlet.paths&amp;quot; value=&amp;quot;/system/osgitest/info&amp;quot;
 */
@SuppressWarnings(&amp;quot;serial&amp;quot;)
public class OsgiTestClientServlet extends SlingSafeMethodsServlet {
	
	/** @scr.reference */
	private final SampleService service = null;

	@Override
	protected void doGet(SlingHttpServletRequest request,
			SlingHttpServletResponse response) throws ServletException,
			IOException {
		if (service == null) {
			response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
					&amp;quot;no reference to service available&amp;quot;);
		} else {
			response.setContentType(&amp;quot;text/plain&amp;quot;);
			response.getOutputStream().print(service.sayHello());
		}
	}
}
&lt;/pre&gt;

&lt;h5&gt;The pom: nothing special&lt;/h5&gt;
&lt;p&gt;The pom looks quite familiar. What's different this time?
&lt;br /&gt;On lines 93-97, we have a dependency on the &lt;code&gt;org.apache.sling.api&lt;/code&gt; artifact. That is because we are using sling specific types in the servlet implementation. I have here used the version &lt;code&gt;2.0.0.incubator-SNAPSHOT&lt;/code&gt;, which is what comes with CRX Cup edition.
&lt;br /&gt;On lines 98-102, we depend on the &lt;code&gt;mh.studies.sling.osgitest&lt;/code&gt; artifact. This should be in your m2 repository from the previous tracks.
&lt;/p&gt;
&lt;pre name="code" class="xml"&gt;
&amp;lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
   xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&amp;gt;
   &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
   &amp;lt;groupId&amp;gt;mh.studies&amp;lt;/groupId&amp;gt;
   &amp;lt;artifactId&amp;gt;mh.studies.sling.osgitest.client&amp;lt;/artifactId&amp;gt;
   &amp;lt;packaging&amp;gt;bundle&amp;lt;/packaging&amp;gt;
   &amp;lt;name&amp;gt;A Servlet Client for the OSGi Test Bundle&amp;lt;/name&amp;gt;
   &amp;lt;version&amp;gt;0.0.1&amp;lt;/version&amp;gt;
   &amp;lt;description /&amp;gt;
   &amp;lt;build&amp;gt;
      &amp;lt;plugins&amp;gt;
         &amp;lt;plugin&amp;gt;
            &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;configuration&amp;gt;
               &amp;lt;source&amp;gt;1.5&amp;lt;/source&amp;gt;
               &amp;lt;target&amp;gt;1.5&amp;lt;/target&amp;gt;
            &amp;lt;/configuration&amp;gt;
         &amp;lt;/plugin&amp;gt;
         &amp;lt;plugin&amp;gt;
            &amp;lt;groupId&amp;gt;org.apache.sling&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;maven-sling-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;2.0.2-incubator&amp;lt;/version&amp;gt;
            &amp;lt;executions&amp;gt;
               &amp;lt;execution&amp;gt;
                  &amp;lt;id&amp;gt;install-bundle&amp;lt;/id&amp;gt;
                  &amp;lt;goals&amp;gt;
                     &amp;lt;goal&amp;gt;install&amp;lt;/goal&amp;gt;
                  &amp;lt;/goals&amp;gt;
                  &amp;lt;configuration&amp;gt;
                     &amp;lt;slingUrl&amp;gt;http://localhost:7402/system/console/install&amp;lt;/slingUrl&amp;gt;
                     &amp;lt;user&amp;gt;admin&amp;lt;/user&amp;gt;
                     &amp;lt;password&amp;gt;admin&amp;lt;/password&amp;gt;
                  &amp;lt;/configuration&amp;gt;
               &amp;lt;/execution&amp;gt;
            &amp;lt;/executions&amp;gt;
         &amp;lt;/plugin&amp;gt;
         &amp;lt;plugin&amp;gt;
            &amp;lt;groupId&amp;gt;org.apache.felix&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;maven-scr-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.0.7&amp;lt;/version&amp;gt;
            &amp;lt;executions&amp;gt;
               &amp;lt;execution&amp;gt;
                  &amp;lt;id&amp;gt;generate-scr-scrdescriptor&amp;lt;/id&amp;gt;
                  &amp;lt;goals&amp;gt;
                     &amp;lt;goal&amp;gt;scr&amp;lt;/goal&amp;gt;
                  &amp;lt;/goals&amp;gt;
               &amp;lt;/execution&amp;gt;
            &amp;lt;/executions&amp;gt;
         &amp;lt;/plugin&amp;gt;
         &amp;lt;plugin&amp;gt;
            &amp;lt;groupId&amp;gt;org.apache.felix&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;maven-bundle-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.4.3&amp;lt;/version&amp;gt;
            &amp;lt;extensions&amp;gt;true&amp;lt;/extensions&amp;gt;
            &amp;lt;configuration&amp;gt;
               &amp;lt;instructions&amp;gt;
                  &amp;lt;Export-Package&amp;gt;&amp;lt;/Export-Package&amp;gt;
                  &amp;lt;Private-Package&amp;gt;mh.osgitest.client&amp;lt;/Private-Package&amp;gt;
                  &amp;lt;Bundle-SymbolicName&amp;gt;${pom.artifactId}&amp;lt;/Bundle-SymbolicName&amp;gt;
                  &amp;lt;Bundle-Name&amp;gt;${pom.name}&amp;lt;/Bundle-Name&amp;gt;
               &amp;lt;/instructions&amp;gt;
            &amp;lt;/configuration&amp;gt;
         &amp;lt;/plugin&amp;gt;
      &amp;lt;/plugins&amp;gt;
   &amp;lt;/build&amp;gt;
   &amp;lt;repositories&amp;gt;
      &amp;lt;repository&amp;gt;
         &amp;lt;id&amp;gt;apache.incubating&amp;lt;/id&amp;gt;
         &amp;lt;name&amp;gt;Apache Incubating Repository&amp;lt;/name&amp;gt;
         &amp;lt;url&amp;gt;http://people.apache.org/repo/m2-incubating-repository&amp;lt;/url&amp;gt;
      &amp;lt;/repository&amp;gt;
   &amp;lt;/repositories&amp;gt;
   &amp;lt;pluginRepositories&amp;gt;
      &amp;lt;pluginRepository&amp;gt;
         &amp;lt;id&amp;gt;apache.incubating.plugins&amp;lt;/id&amp;gt;
         &amp;lt;name&amp;gt;Apache Incubating Plugin Repository&amp;lt;/name&amp;gt;
         &amp;lt;url&amp;gt;http://people.apache.org/repo/m2-incubating-repository 
         &amp;lt;/url&amp;gt;
      &amp;lt;/pluginRepository&amp;gt;
   &amp;lt;/pluginRepositories&amp;gt;
   &amp;lt;dependencies&amp;gt;
      &amp;lt;dependency&amp;gt;
         &amp;lt;groupId&amp;gt;javax.servlet&amp;lt;/groupId&amp;gt;
         &amp;lt;artifactId&amp;gt;servlet-api&amp;lt;/artifactId&amp;gt;
         &amp;lt;version&amp;gt;2.4&amp;lt;/version&amp;gt;
      &amp;lt;/dependency&amp;gt;
      &amp;lt;dependency&amp;gt;
         &amp;lt;groupId&amp;gt;org.apache.felix&amp;lt;/groupId&amp;gt;
         &amp;lt;artifactId&amp;gt;org.osgi.core&amp;lt;/artifactId&amp;gt;
         &amp;lt;version&amp;gt;1.0.0&amp;lt;/version&amp;gt;
      &amp;lt;/dependency&amp;gt;
      &amp;lt;dependency&amp;gt;
         &amp;lt;groupId&amp;gt;org.apache.sling&amp;lt;/groupId&amp;gt;
         &amp;lt;artifactId&amp;gt;org.apache.sling.api&amp;lt;/artifactId&amp;gt;
         &amp;lt;version&amp;gt;2.0.0.incubator-SNAPSHOT&amp;lt;/version&amp;gt;
      &amp;lt;/dependency&amp;gt;
      &amp;lt;dependency&amp;gt;
         &amp;lt;groupId&amp;gt;mh.studies&amp;lt;/groupId&amp;gt;
         &amp;lt;artifactId&amp;gt;mh.studies.sling.osgitest&amp;lt;/artifactId&amp;gt;
         &amp;lt;version&amp;gt;0.0.5&amp;lt;/version&amp;gt;
      &amp;lt;/dependency&amp;gt;
   &amp;lt;/dependencies&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;

&lt;h5&gt;Maven dependencies: oops&lt;/h5&gt;
&lt;p&gt;Everything looks easy so far, but there's one catch: no public m2 repository can satisfy the dependency on org.apache.sling.api-2.0.0.incubator-SNAPSHOT, so that when you now run &lt;code&gt;mvn  package&lt;/code&gt;, you will end up with the following:&lt;/p&gt;

&lt;pre name="code" class="plain"&gt;
D:\projekte\workspace-sling\mh.studies.sling.osgitest.client&amp;gt;mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building A Servlet Client for the OSGi Test Bundle
[INFO]    task-segment: [package]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] snapshot org.apache.sling:org.apache.sling.api:2.0.0.incubator-SNAPSHOT: checking for updates from apache.incubating
Downloading: http://people.apache.org/repo/m2-incubating-repository/org/apache/sling/org.apache.sling.api/2.0.0.incubator-SNAPSHOT/org.apache.sling.api-2.0.0.incubator-SNAPSHOT.pom

Downloading: http://people.apache.org/repo/m2-incubating-repository/org/apache/sling/org.apache.sling.api/2.0.0.incubator-SNAPSHOT/org.apache.sling.api-2.0.0.incubator-SNAPSHOT.jar

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) org.apache.sling:org.apache.sling.api:jar:2.0.0.incubator-SNAPSHOT

  Try downloading the file manually from the project website.

  Then, install it using the command:
      mvn install:install-file -DgroupId=org.apache.sling -DartifactId=org.apache.sling.api -Dversion=2.0.0.incubator-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file

  Alternatively, if you host your own repository you can deploy the file there:
      mvn deploy:deploy-file -DgroupId=org.apache.sling -DartifactId=org.apache.sling.api -Dversion=2.0.0.incubator-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]

  Path to dependency:
        1) mh.studies:mh.studies.sling.osgitest.client:bundle:0.0.1
        2) org.apache.sling:org.apache.sling.api:jar:2.0.0.incubator-SNAPSHOT

----------
1 required artifact is missing.

for artifact:
  mh.studies:mh.studies.sling.osgitest.client:bundle:0.0.1

from the specified remote repositories:
  central (http://repo1.maven.org/maven2),
  apache.incubating (http://people.apache.org/repo/m2-incubating-repository)


[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Wed Sep 03 16:56:39 CEST 2008
[INFO] Final Memory: 5M/9M
[INFO] ------------------------------------------------------------------------
&lt;/pre&gt;

&lt;p&gt;Don't let it bring you down -- the problem is easily solved, even if it takes a few steps. Note the lines 21 - 26 above. They already show that there is a solution at hand. Now all we need is the jar file. Don't look on the sling website, it's already on your machine. Go to the place you started CRX Quickstart from, and you'll find it here: &lt;code&gt;./crx-quickstart/server/runtime/0/_/WEB-INF/resources/bundles/org.apache.sling.api-2.0.0-incubator-SNAPSHOT.jar&lt;/code&gt;. Now, you only need to execute the following:&lt;/p&gt;

&lt;pre name="code" class="plain"&gt;mvn install:install-file -DgroupId=org.apache.sling -DartifactId=org.apache.sling.api -Dversion=2.0.0.incubator-SNAPSHOT -Dpackaging=jar \
  -Dfile=&amp;lt;crx quickstart dir&amp;gt;/crx-quickstart/server/runtime/0/_/WEB-INF/resources/bundles/org.apache.sling.api-2.0.0-incubator-SNAPSHOT.jar&lt;/pre&gt;

&lt;h5&gt;Build, Deploy, Test&lt;/h5&gt;
&lt;p&gt;All that remains is &lt;code&gt;mvn clean install&lt;/code&gt;, and go to &lt;a href="http://localhost:7402/system/osgitest/info"&gt;http://localhost:7402/system/osgitest/info&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5750351649256467689-2769142173443389001?l=in-the-sling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/2769142173443389001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5750351649256467689&amp;postID=2769142173443389001' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/2769142173443389001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/2769142173443389001'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/2008/09/sling-osgi-track-pt-6-sling-servlets-i.html' title='Sling OSGI Track pt 6: Sling Servlets I'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5750351649256467689.post-1006526840722378543</id><published>2008-09-02T22:24:00.001+02:00</published><updated>2008-09-04T10:47:27.416+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sling'/><category scheme='http://www.blogger.com/atom/ns#' term='jcr'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><title type='text'>HOW-TO use the JSON Query Servlet</title><content type='html'>&lt;p&gt;Sling provides a standard JSON Query Servlet in the package org.apache.sling.servlets.get that allows you to perform a search on the contents of the underlying repository.&lt;/p&gt;  &lt;p&gt;The source of the servlet is available here:    &lt;br /&gt;&lt;a title="http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/RedirectServlet.java?view=markup" href="http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/RedirectServlet.java?view=markup"&gt;http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/RedirectServlet.java?view=markup&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I am here discussing revision 660460. The source of that revision is at the very bottom of this post.&lt;/p&gt;  &lt;p&gt;The servlet registers with the selector &amp;quot;query&amp;quot; and the extension &amp;quot;json&amp;quot; in lines 59 and 58.    &lt;br /&gt;That means that we can trigger it by accessing any node in the repository and append &amp;quot;.query&amp;quot; to it's name and &amp;quot;.json&amp;quot; as the extension.     &lt;br /&gt;The node we call is irrelevant. The servlet will always query the whole repository. The only thing we need is a resource that does exist, or the star resource.     &lt;br /&gt;So let's start off with a simple example that will work on any sling installation, whatever has been done to it, and return each and every node as a search result:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*"&gt;http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This reveals the two required parameters for the servlet: queryType and statement. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;u&gt;queryType&lt;/u&gt; can be &amp;quot;xpath&amp;quot; or &amp;quot;sql&amp;quot; &lt;/li&gt;    &lt;li&gt;&lt;u&gt;statement&lt;/u&gt; is the search statement in the language specified through the queryType parameter. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The more intuitive language (at least to me and when dealing with structured content) is xpath, so let's see another example. This one will return all nodes of the primary type &amp;quot;nt:unstructured&amp;quot;.    &lt;br /&gt;&lt;a title="http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[@jcr:primaryType=&amp;#39;nt:unstructured&amp;#39;]" href="http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[@jcr:primaryType='nt:unstructured']"&gt;http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[@jcr:primaryType='nt:unstructured']&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The same result will be returned with the following SQL query:    &lt;br /&gt;&lt;a href="http://localhost:8080/content.query.json?queryType=sql&amp;amp;statement=select * from nt:base where jcr:primaryType='nt:unstructured'"&gt;http://localhost:8080/content.query.json?queryType=sql&amp;amp;statement=select * from nt:base where jcr:primaryType='nt:unstructured'&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This will (on my instance) give the following result. As you can see, for each result we get&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;the name of the node &lt;/li&gt;    &lt;li&gt;the path &lt;/li&gt;    &lt;li&gt;the score of the result entry &lt;/li&gt;    &lt;li&gt;the primaryType &lt;/li&gt; &lt;/ul&gt;  &lt;pre name="code" class="js"&gt;
 [
    {
       "name":"org.apache.sling.launchpad.content",
       "jcr:path":"/var/sling/bundle-content/org.apache.sling.launchpad.content",
       "jcr:score":"1000",
       "jcr:primaryType":"nt:unstructured"
    },
    {
       "name":"mh.studies.sling.osgitest",
       "jcr:path":"/var/sling/bundle-content/mh.studies.sling.osgitest",
       "jcr:score":"1000",
       "jcr:primaryType":"nt:unstructured"
    },
    {
       "name":"test",
       "jcr:path":"/content/osgitest/test",
       "jcr:score":"1000",
       "jcr:primaryType":"nt:unstructured"
    }
 ]&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;But you can also use the full power of the jcr-specific xpath functions, e.g. 
  &lt;br /&gt;&lt;a title="http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(.,&amp;#39;sling&amp;#39;)]" href="http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(.,'sling')]"&gt;http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(.,'sling')]&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This searches for all nodes that contain the word &amp;quot;sling&amp;quot;.&lt;/p&gt;

&lt;p&gt;The &lt;u&gt;offset&lt;/u&gt; parameter will skip as many rows in the result as given (lines 110-116).&lt;/p&gt;

&lt;p&gt;The &lt;u&gt;rows&lt;/u&gt; parameter states the maximum number of rows that will be returned.&lt;/p&gt;

&lt;p&gt;The &lt;u&gt;property&lt;/u&gt; parameter can be used to extract additional properties from the node. 

  &lt;br /&gt;It can be used multiple times. 

  &lt;br /&gt;&lt;a title="http://localhost:8080/content.query.json?statement=//*[@jcr:primaryType=&amp;#39;nt:file&amp;#39;]&amp;amp;property=jcr:content/jcr:mimeType" href="http://localhost:8080/content.query.json?statement=//*[@jcr:primaryType='nt:file']&amp;amp;property=jcr:content/jcr:mimeType"&gt;http://localhost:8080/content.query.json?statement=//*[@jcr:primaryType='nt:file']&amp;amp;property=jcr:content/jcr:mimeType&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;will return:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  1: [
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  3:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;index.html&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/index.html&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  5:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;1000&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;nt:file&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  7:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:content/jcr:mimeType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;text/html&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8:    },
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  9:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;sling-logo.png&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 11:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/sling-logo.png&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;1000&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 13:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;nt:file&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:content/jcr:mimeType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;image/png&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 15:    },
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 16:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 17:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;assert.js&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 18:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/sling-test/sling/assert.js&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 19:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;1000&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 20:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;nt:file&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 21:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:content/jcr:mimeType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;application/x-javascript&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 22:    },
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 23:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 24:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;sling-test.html&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 25:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/sling-test/sling/sling-test.html&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 26:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;1000&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 27:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;nt:file&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 28:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:content/jcr:mimeType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;text/html&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 29:    },
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 30:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 31:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;sling.css&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 32:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/sling.css&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 33:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;1000&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 34:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;nt:file&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 35:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:content/jcr:mimeType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;text/css&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 36:    },
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 37:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 38:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;GET.esp&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 39:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/apps/samples/osgitest/GET.esp&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 40:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;1000&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 41:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;nt:file&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 42:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:content/jcr:mimeType&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;text/plain&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 43:    }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 44: ]&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;u&gt;excerptPath&lt;/u&gt; parameter specifies the argument to the rep:excerpt() function. 

  &lt;br /&gt;You might want to have a look here: &lt;a title="http://wiki.apache.org/jackrabbit/ExcerptProvider" href="http://wiki.apache.org/jackrabbit/ExcerptProvider"&gt;http://wiki.apache.org/jackrabbit/ExcerptProvider&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what is the rep:excerpt() function? The rep:excerpt() function returns an excerpt of the node that was found and highlights search terms. The excerpt is an XML fragment, and is included in the JSON code as a &amp;quot;rep:excerpt&amp;quot; key in the returned array.&lt;/p&gt;

&lt;p&gt;Let's have an example:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(.,'sling')]/(rep:excerpt(.))&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This will return the following JSON that includes&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the name &lt;/li&gt;

  &lt;li&gt;the path &lt;/li&gt;

  &lt;li&gt;the excerpt &lt;/li&gt;

  &lt;li&gt;the score &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for each entry (note it no longer returns the primaryType).&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  1: [
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  3:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  5:       &amp;quot;&lt;span style="color: #8b0000"&gt;rep:excerpt()&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;div&amp;gt;&amp;lt;span&amp;gt;&amp;lt;strong&amp;gt;sling&amp;lt;\/strong&amp;gt;:redirect /index.html&amp;lt;\/span&amp;gt;&amp;lt;\/div&amp;gt;&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;1000&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  7:    },
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  9:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;jcr:content&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/index.html/jcr:content&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 11:       &amp;quot;&lt;span style="color: #8b0000"&gt;rep:excerpt()&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;div&amp;gt;&amp;lt;span&amp;gt; Welcome to the &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; Launchpad Welcome to the &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; Launchpad Apache &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; currently in incubation is a web framework that uses a Java Content&amp;lt;\/span&amp;gt;&amp;lt;span&amp;gt;... content bundles can be loaded unloaded and reconfigured at runtime The &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; Launchpad is a ready to run &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; configuration providing an embedded JCR content repository and web server&amp;lt;\/span&amp;gt;&amp;lt;span&amp;gt;... root URL as the WebDAV server URL Use our mailing lists to contact the &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; developers team The &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; OSGi management console is available at system console The Sling client ...&amp;lt;\/span&amp;gt;&amp;lt;\/div&amp;gt;&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;500&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 13:    },
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 15:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;jcr:content&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 16:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/sling-test/sling/sling-test.html/jcr:content&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 17:       &amp;quot;&lt;span style="color: #8b0000"&gt;rep:excerpt()&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;div&amp;gt;&amp;lt;span&amp;gt;... px background color red color white padding em font weight bold Automated &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; client library tests TODO for now running these tests requires setting&amp;lt;\/span&amp;gt;&amp;lt;span&amp;gt;... undefined typeof data dummy function testGetSessionInfo var session &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; getSessionInfo assertNotNull &amp;lt;strong&amp;gt;Sling&amp;lt;\/strong&amp;gt; getSessionInfo session assertEquals session userID is a string string&amp;lt;\/span&amp;gt;&amp;lt;span&amp;gt;... indexOf default function testRemoveContent var deletePath baseTestPath &amp;lt;strong&amp;gt;sling&amp;lt;\/strong&amp;gt; test testhtml nodes delete now var c slingPost deletePath title hello ...&amp;lt;\/span&amp;gt;&amp;lt;\/div&amp;gt;&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 18:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;313&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 19:    }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 20: ]&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This is quite unsatisfactory. What we really want is not the jcr:content nodes, right? We want their parent nodes, but still have the excerpt from the content.&lt;/p&gt;

&lt;p&gt;So, let's refine in a first step and get the parents as the search result: 
  &lt;br /&gt;&lt;a title="http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(jcr:content,&amp;#39;sling&amp;#39;)]/(rep:excerpt(.))" href="http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(jcr:content,'sling')]/(rep:excerpt(.))"&gt;http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(jcr:content,'sling')]/(rep:excerpt(.))&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives us the following. This is OK in terms of nodes returned -- it gives us the nodes of which the content contains &amp;quot;sling&amp;quot;. 
  &lt;br /&gt;But now the excerpts are ruined, as the node itself does not contain the word &amp;quot;sling&amp;quot;, but the excerpt is drawn from the node.&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  1: [
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  3:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;index.html&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/index.html&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  5:       &amp;quot;&lt;span style="color: #8b0000"&gt;rep:excerpt()&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;excerpt&amp;gt;&amp;lt;fragment&amp;gt;&amp;lt;\/fragment&amp;gt;&amp;lt;\/excerpt&amp;gt;&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;1000&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  7:    },
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8:    {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  9:       &amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;sling-test.html&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;/sling-test/sling/sling-test.html&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 11:       &amp;quot;&lt;span style="color: #8b0000"&gt;rep:excerpt()&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;excerpt&amp;gt;&amp;lt;fragment&amp;gt;&amp;lt;\/fragment&amp;gt;&amp;lt;\/excerpt&amp;gt;&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12:       &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:score&lt;/span&gt;&amp;quot;:&amp;quot;&lt;span style="color: #8b0000"&gt;903&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 13:    }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14: ]&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;*STOPPER* 
  &lt;br /&gt;After struggling through JPDA sessions for a whole while, I must confess that I am a bit lost about excerptPath. 

  &lt;br /&gt;Looking at lines 155ff, it would seem that it is impossible for a result row to contain REP_EXCERPT = &amp;quot;rep:excerpt()&amp;quot; and &amp;quot;rep:excerpt(&amp;quot; + exerptPath + &amp;quot;)&amp;quot; at the same time, if exerptPath is anything else but &amp;quot;&amp;quot;.&lt;/p&gt;

&lt;p&gt;But this may be because I am not too well acquainted with the jcr functions of xpath. 
  &lt;br /&gt;If ever I get a handle on this, I will update this post. Or maybe someone can provide a meaningful example?&lt;/p&gt;

&lt;p&gt;My idea was that I can modify above query to the following, so that the parent node of the respective node is returned, and the excerpt of the jcr:content path. 
  &lt;br /&gt;&lt;a title="http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(jcr:content,&amp;#39;sling&amp;#39;)]/(rep:excerpt(jcr:content))&amp;amp;excerptPath=jcr:content" href="http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(jcr:content,'sling')]/(rep:excerpt(jcr:content))&amp;amp;excerptPath=jcr:content"&gt;http://localhost:8080/content.query.json?queryType=xpath&amp;amp;statement=//*[jcr:contains(jcr:content,'sling')]/(rep:excerpt(jcr:content))&amp;amp;excerptPath=jcr:content&lt;/a&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #008000"&gt;/*
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2:  * Licensed to the Apache Software Foundation (ASF) under one
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  3:  * or more contributor license agreements.  See the NOTICE file
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4:  * distributed with this work for additional information
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  5:  * regarding copyright ownership.  The ASF licenses this file
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6:  * to you under the Apache License, Version 2.0 (the
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  7:  * &amp;quot;License&amp;quot;); you may not use this file except in compliance
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8:  * with the License.  You may obtain a copy of the License at
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  9:  *
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10:  *   http://www.apache.org/licenses/LICENSE-2.0
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 11:  *
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12:  * Unless required by applicable law or agreed to in writing,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 13:  * software distributed under the License is distributed on an
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14:  * &amp;quot;AS IS&amp;quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 15:  * KIND, either express or implied.  See the License for the
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 16:  * specific language governing permissions and limitations
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 17:  * under the License.
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 18:  */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 19: &lt;span style="color: #0000ff"&gt;package&lt;/span&gt; org.apache.sling.servlets.get;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 20: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 21: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; java.io.IOException;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 22: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; java.io.InputStream;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 23: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; java.util.ArrayList;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 24: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; java.util.Iterator;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 25: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; java.util.List;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 26: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; java.util.Map;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 27: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 28: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; javax.jcr.RepositoryException;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 29: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; javax.jcr.Value;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 30: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; javax.jcr.query.Query;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 31: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 32: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.api.SlingException;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 33: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.api.SlingHttpServletRequest;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 34: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.api.SlingHttpServletResponse;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 35: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.api.resource.Resource;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 36: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.api.resource.ResourceResolver;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 37: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.api.resource.ResourceUtil;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 38: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.api.servlets.SlingSafeMethodsServlet;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 39: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.commons.json.JSONException;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 40: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.commons.json.io.JSONWriter;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 41: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.jcr.resource.JcrResourceUtil;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 42: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.apache.sling.servlets.get.helpers.JsonRendererServlet;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 43: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.slf4j.Logger;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 44: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.slf4j.LoggerFactory;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 45: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 46: &lt;span style="color: #008000"&gt;/**
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 47:  * A SlingSafeMethodsServlet that renders the search results as JSON data
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 48:  *
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 49:  * @scr.component immediate=&amp;quot;true&amp;quot; metatype=&amp;quot;no&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 50:  * @scr.service interface=&amp;quot;javax.servlet.Servlet&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 51:  * 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 52:  * @scr.property name=&amp;quot;service.description&amp;quot; value=&amp;quot;Default Query Servlet&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 53:  * @scr.property name=&amp;quot;service.vendor&amp;quot; value=&amp;quot;The Apache Software Foundation&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 54:  * 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 55:  * Use this as the default query servlet for json get requests for Sling
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 56:  * @scr.property name=&amp;quot;sling.servlet.resourceTypes&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 57:  *               value=&amp;quot;sling/servlet/default&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 58:  * @scr.property name=&amp;quot;sling.servlet.extensions&amp;quot; value=&amp;quot;json&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 59:  * @scr.property name=&amp;quot;sling.servlet.selectors&amp;quot; value=&amp;quot;query&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 60:  */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 61: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; JsonQueryServlet &lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; SlingSafeMethodsServlet {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 62:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; Logger log = LoggerFactory.getLogger(JsonQueryServlet.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 63: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 64:     &lt;span style="color: #008000"&gt;/** Search clause */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 65:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String STATEMENT = &amp;quot;&lt;span style="color: #8b0000"&gt;statement&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 66: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 67:     &lt;span style="color: #008000"&gt;/** Query type */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 68:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String QUERY_TYPE = &amp;quot;&lt;span style="color: #8b0000"&gt;queryType&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 69: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 70:     &lt;span style="color: #008000"&gt;/** Result set offset */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 71:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String OFFSET = &amp;quot;&lt;span style="color: #8b0000"&gt;offset&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 72: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 73:     &lt;span style="color: #008000"&gt;/** Number of rows requested */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 74:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String ROWS = &amp;quot;&lt;span style="color: #8b0000"&gt;rows&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 75: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 76:     &lt;span style="color: #008000"&gt;/** property to append to the result */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 77:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String PROPERTY = &amp;quot;&lt;span style="color: #8b0000"&gt;property&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 78: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 79:     &lt;span style="color: #008000"&gt;/** exerpt lookup path */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 80:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String EXCERPT_PATH = &amp;quot;&lt;span style="color: #8b0000"&gt;excerptPath&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 81: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 82:     &lt;span style="color: #008000"&gt;/** rep:exerpt */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 83:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String REP_EXCERPT = &amp;quot;&lt;span style="color: #8b0000"&gt;rep:excerpt()&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 84: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 85:     @Override
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 86:     &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; doGet(SlingHttpServletRequest req,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 87:             SlingHttpServletResponse resp) &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; IOException {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 88:         dumpResult(req, resp);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 89:     }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 90: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 91:     &lt;span style="color: #008000"&gt;/**
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 92:      * Dumps the result as JSON object.
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 93:      *
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 94:      * @param req request
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 95:      * @param resp response
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 96:      * @throws IOException in case the search will unexpectedly fail
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 97:      */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 98:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; dumpResult(SlingHttpServletRequest req,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 99:             SlingHttpServletResponse resp) &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; IOException {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;100:         &lt;span style="color: #0000ff"&gt;try&lt;/span&gt; {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;101:             ResourceResolver resolver = req.getResourceResolver();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;102: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;103:             String statement = req.getParameter(STATEMENT);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;104:             String queryType = (req.getParameter(QUERY_TYPE) != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; req.getParameter(
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;105:                 QUERY_TYPE).equals(Query.SQL)) ? Query.SQL : Query.XPATH;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;106: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;107:             Iterator&amp;lt;Map&amp;lt;String, Object&amp;gt;&amp;gt; result = resolver.queryResources(
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;108:                 statement, queryType);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;109: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;110:             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (req.getParameter(OFFSET) != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;111:                 &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; skip = Long.parseLong(req.getParameter(OFFSET));
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;112:                 &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (skip &amp;gt; 0 &amp;amp;&amp;amp; result.hasNext()) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;113:                     result.next();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;114:                     skip--;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;115:                 }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;116:             }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;117: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;118:             resp.setContentType(JsonRendererServlet.responseContentType);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;119:             resp.setCharacterEncoding(&amp;quot;&lt;span style="color: #8b0000"&gt;UTF-8&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;120: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;121:             &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; JSONWriter w = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; JSONWriter(resp.getWriter());
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;122:             w.array();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;123: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;124:             &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; count = -1;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;125:             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (req.getParameter(ROWS) != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;126:                 count = Long.parseLong(req.getParameter(ROWS));
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;127:             }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;128: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;129:             List&amp;lt;String&amp;gt; properties = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArrayList&amp;lt;String&amp;gt;();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;130:             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (req.getParameterValues(PROPERTY) != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;131:                 &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (String property : req.getParameterValues(PROPERTY)) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;132:                     properties.add(property);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;133:                 }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;134:             }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;135: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;136:             String exerptPath = &amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;137:             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (req.getParameter(EXCERPT_PATH) != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;138:                 exerptPath = req.getParameter(EXCERPT_PATH);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;139:             }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;140: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;141:             &lt;span style="color: #008000"&gt;// iterate through the result set and build the &amp;quot;json result&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;142:             &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (result.hasNext() &amp;amp;&amp;amp; count != 0) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;143:                 Map&amp;lt;String, Object&amp;gt; row = result.next();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;144: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;145:                 w.&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;146:                 String path = row.get(&amp;quot;&lt;span style="color: #8b0000"&gt;jcr:path&lt;/span&gt;&amp;quot;).toString();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;147: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;148:                 w.key(&amp;quot;&lt;span style="color: #8b0000"&gt;name&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;149:                 w.value(ResourceUtil.getName(path));
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;150: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;151:                 &lt;span style="color: #008000"&gt;// dump columns&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;152:                 &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (String colName : row.keySet()) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;153:                     w.key(colName);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;154:                     String strValue = &amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;155:                     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (colName.equals(REP_EXCERPT)) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;156:                         Object ev = row.get(&amp;quot;&lt;span style="color: #8b0000"&gt;rep:excerpt(&lt;/span&gt;&amp;quot; + exerptPath + &amp;quot;&lt;span style="color: #8b0000"&gt;)&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;157:                         strValue = (ev == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) ? &amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot; : ev.toString();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;158:                     } &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;159:                         strValue = formatValue(row.get(colName));
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;160:                     }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;161:                     w.value(strValue);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;162:                 }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;163: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;164:                 &lt;span style="color: #008000"&gt;// load properties and add it to the result set&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;165:                 &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!properties.isEmpty()) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;166:                     Resource nodeRes = resolver.getResource(path);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;167:                     dumpProperties(w, nodeRes, properties);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;168:                 }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;169: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;170:                 w.endObject();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;171:                 count--;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;172:             }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;173:             w.endArray();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;174:         } &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (JSONException je) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;175:             &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; wrapException(je);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;176:         }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;177:     }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;178: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;179:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; dumpProperties(JSONWriter w, Resource nodeRes,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;180:             List&amp;lt;String&amp;gt; properties) &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; JSONException {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;181: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;182:         &lt;span style="color: #008000"&gt;// nothing to do if there is no resource&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;183:         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (nodeRes == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;184:             &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;185:         }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;186: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;187: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;188:         ResourceResolver resolver = nodeRes.getResourceResolver();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;189:         &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (String property : properties) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;190:             Resource prop = resolver.getResource(nodeRes, property);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;191:             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (prop != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;192:                 String strValue;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;193:                 Value value = prop.adaptTo(Value.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;194:                 &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (value != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;195:                     strValue = formatValue(value);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;196:                 } &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;197:                     strValue = prop.adaptTo(String.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;198:                     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (strValue == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;199:                         strValue = &amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;200:                     }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;201:                 }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;202:                 w.key(property);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;203:                 w.value(strValue);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;204:             }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;205:         }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;206: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;207:     }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;208: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;209:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; String formatValue(Value value) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;210:         &lt;span style="color: #0000ff"&gt;try&lt;/span&gt; {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;211:             &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; formatValue(JcrResourceUtil.toJavaObject(value));
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;212:         } &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (RepositoryException re) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;213:             &lt;span style="color: #008000"&gt;// might log&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;214:         }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;215:         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;216:     }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;217: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;218:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; String formatValue(Object value) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;219:         String strValue;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;220:         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (value &lt;span style="color: #0000ff"&gt;instanceof&lt;/span&gt; InputStream) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;221:             &lt;span style="color: #008000"&gt;// binary value comes as a LazyInputStream&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;222:             strValue = &amp;quot;&lt;span style="color: #8b0000"&gt;[binary]&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;223: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;224:             &lt;span style="color: #008000"&gt;// just to be clean, close the stream&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;225:             &lt;span style="color: #0000ff"&gt;try&lt;/span&gt; {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;226:                 ((InputStream) value).close();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;227:             } &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (IOException ignore) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;228:             }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;229:         } &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (value != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;230:             strValue = value.toString();
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;231:         } &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;232:             strValue = &amp;quot;&lt;span style="color: #8b0000"&gt;&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;233:         }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;234: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;235:         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; strValue;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;236:     }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;237: 
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;238:     &lt;span style="color: #008000"&gt;/**
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;239:      * @param e
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;240:      * @throws org.apache.sling.api.SlingException wrapping the given exception
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;241:      */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;242:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; SlingException wrapException(Exception e) {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;243:         log.warn(&amp;quot;&lt;span style="color: #8b0000"&gt;Error in QueryServlet: &lt;/span&gt;&amp;quot; + e.toString(), e);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;244:         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SlingException(e.toString(), e);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;245:     }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;246: }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;247: &lt;/pre&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5750351649256467689-1006526840722378543?l=in-the-sling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/1006526840722378543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5750351649256467689&amp;postID=1006526840722378543' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/1006526840722378543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/1006526840722378543'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/2008/09/how-to-use-json-query-servlet.html' title='HOW-TO use the JSON Query Servlet'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5750351649256467689.post-6240833838584581418</id><published>2008-09-02T13:54:00.001+02:00</published><updated>2008-09-02T16:34:09.203+02:00</updated><title type='text'>Sling OSGi Track pt 5: Bundling initial content</title><content type='html'>&lt;p&gt;This is the continuation of&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html"&gt;Sling OSGi Track pt 1: hand-rolled service bundle&lt;/a&gt; and &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-2-using-felix.html"&gt;Sling OSGi Track pt 2: using Felix' bundle plugin for manifest entries&lt;/a&gt; and &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-3-replacing.html"&gt;Sling OSGi Track pt 3: replacing the Activator with DS&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-4-installing-to.html"&gt;Sling OSGi Track pt 4: installing to Sling using Maven&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In this part, I will show how to bundle initial content.&lt;/p&gt;  &lt;p&gt;I will put the test node and the test script that I used previously into the bundle, so they don't need to be created separately.&lt;/p&gt;  &lt;p&gt;Sling provides several different ways to load content provided by an OSGi bundle. These are provided in the org.apache.sling.jcr.contentloader package, and can be used to&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;create initial content from a filesystem structure contained in a ZIP or JAR file      &lt;br /&gt;This content reader will create nt:folder and nt:file resources. It basically does the same as if you created the same items through WebDAV.       &lt;br /&gt;It also has the same limitations: you cannot set different Nodetypes, and you cannot edit properties explicitly. &lt;/li&gt;    &lt;li&gt;create initial content from an XML definition      &lt;br /&gt;This allows you to provide an XML file, in which the content structure is defined. You can define nodetypes and mixins, but you cannot influence any other properties.       &lt;br /&gt;As opposed to the ZIP reader, it does not provide a way to include binary data. &lt;/li&gt;    &lt;li&gt;create initial content from a JSON definition&amp;#160; &lt;br /&gt;This is the most powerful reader, as you can set arbitrary properties (but again, no binary content can be included). &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Aims:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Show how to bundle initial sling content into the OSGi bundle &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Ingredients:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://dev.day.com/microsling/content/blogs/cup/downloads.c.html"&gt;CRX quickstart&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html"&gt;Bundle Plugin for Maven&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-scr-plugin.html"&gt;SCR Plugin for Maven&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://incubator.apache.org/sling/site/sling.html"&gt;Maven Sling Plugin&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Files:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.5.jar"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.5.jar&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-5-src.zip"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-5-src.zip&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Outline:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Project structure&lt;/li&gt;    &lt;li&gt;Create initial content structure &lt;/li&gt;    &lt;li&gt;Update the pom accordingly &lt;/li&gt;    &lt;li&gt;Build and Install &lt;/li&gt;    &lt;li&gt;Test &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Execution:&lt;/h4&gt;  &lt;h5&gt;Project structure&lt;/h5&gt;  &lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;.
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;|-- pom.xml
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;`-- src
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;    `-- main
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |-- java
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |   `-- mh
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |       `-- osgitest
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |           |-- SampleService.java
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |           `-- SampleServiceImpl.java
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        `-- resources
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;            |-- META-INF
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;            `-- SLING-INF
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;                `-- initial-content
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;                    |-- apps
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;                    |   `-- samples
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;                    |       `-- osgitest
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;                    |           `-- GET.esp
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;                    `-- content.json&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h5&gt;Create initial content structure&lt;/h5&gt;

&lt;p&gt;We'll be using the JAR content loader to create the structure apps/samples/osgitest and the file GET.esp beneath it. 
  &lt;br /&gt;For that, we create a directory src/main/resources/SLING-INF/initial-content. In that directory, we'll create the directory apps/samples/osgitest. 

  &lt;br /&gt;Into that directory, we place the file GET.esp with the following contents:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  1: &amp;lt;%
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; service =
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  3:  sling.getService(Packages.mh.osgitest.SampleService);
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: %&amp;gt;&amp;lt;%= service.sayHello() %&amp;gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;That was easy so far: all we wanted to do was create resources of type nt:folder and nt:file. 
  &lt;br /&gt;(Note that the changes to the pom are needed before sling takes notice, so don't try right now).&lt;/p&gt;

&lt;p&gt;For creating the structure in the content tree, it's not that easy. If you peek back at the first part, we need to create a resource of type &amp;quot;nt:unstructured&amp;quot; and assign it a property of &amp;quot;sling:resourceType&amp;quot; with a value of &amp;quot;samples:osgitest&amp;quot;, so that the GET.esp script at apps/samples/osgitest is picked up.&lt;/p&gt;

&lt;p&gt;Also, I now want to create the script at /content/osgitest/test, instead of /content/test, so this does not clutter up the content tree at root level.&lt;/p&gt;

&lt;p&gt;This can only be achieved through the JSON reader, which expects a JSON definition of the nodes to be created. It's actually very intuitive and need little explanation. 
  &lt;br /&gt;In the initial-content/ directory, I place a file named &amp;quot;content.json&amp;quot; with the following content:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  1: {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  2:     &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot; : &amp;quot;&lt;span style="color: #8b0000"&gt;nt:unstructured&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  3:     &amp;quot;&lt;span style="color: #8b0000"&gt;osgitest&lt;/span&gt;&amp;quot; : {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  4:         &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot; : &amp;quot;&lt;span style="color: #8b0000"&gt;nt:unstructured&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  5:         &amp;quot;&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;&amp;quot; : {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  6:             &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot; : &amp;quot;&lt;span style="color: #8b0000"&gt;nt:unstructured&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  7:             &amp;quot;&lt;span style="color: #8b0000"&gt;sling:resourceType&lt;/span&gt;&amp;quot; : &amp;quot;&lt;span style="color: #8b0000"&gt;samples:osgitest&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  8:         }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  9:     }
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 10: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This will create the following structure in the content repository&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/moritz.havelock/SL0pe4QfmDI/AAAAAAAAABw/LXAmKPPgBJo/s1600-h/snap001%202008-09-02%5B3%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="133" alt="snap001 2008-09-02" src="http://lh3.ggpht.com/moritz.havelock/SL0pfSXkzEI/AAAAAAAAAB0/TzlR8BZBVFI/snap001%202008-09-02_thumb%5B1%5D.png?imgmax=800" width="422" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h5&gt;Update the pom accordingly&lt;/h5&gt;

&lt;p&gt;The contentloader service inspects the Manifest for the &amp;quot;Sling-Initial-Content&amp;quot; header. 
  &lt;br /&gt;To create this header, we add line 13 below to the pom.&lt;/p&gt;

&lt;p&gt;The header can contain multiple entries, separated by commas, and can contain directives whether content should be overwritten, whether it should be deleted when the bundle is uninstalled, and what path other then the root node the content should go to. All this is described at &lt;a title="http://incubator.apache.org/sling/site/content-loading.html" href="http://incubator.apache.org/sling/site/content-loading.html"&gt;http://incubator.apache.org/sling/site/content-loading.html&lt;/a&gt;, and in even more detail at 

  &lt;br /&gt;&lt;a title="http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java?view=markup" href="http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java?view=markup"&gt;http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java?view=markup&lt;/a&gt; and 

  &lt;br /&gt;&lt;a title="http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java?view=markup" href="http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java?view=markup"&gt;http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java?view=markup&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &amp;quot;overwrite&amp;quot; part is dangerous: it will first delete the whole path and then add your contents, so in our case above, the folders &amp;quot;content&amp;quot; and &amp;quot;apps&amp;quot; would be empty except&amp;#160; for the content we just filled in. Ouch.
  &lt;br /&gt;This can be avoided by simultaneously restricting the deployment to a path. But note that this does not work in CRX (not the cup edition, at least).&lt;/p&gt;

&lt;p&gt;But take care you understand that by default, existing content is NOT overwritten, so if you re-deploy your package and want to see the effect of your changes, you'll need to delete everything that must be replaced before deployment -- it won't be overwritten.&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.apache.felix&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  3: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;maven-bundle-plugin&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1.4.3&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  5: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;extensions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;true&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;extensions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  7: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;instructions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Export&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Package&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;mh.osgitest&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Export&lt;/span&gt;-Package&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  9: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Import&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Package&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.osgi.framework;version=&amp;quot;1.3.0&amp;quot;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Import&lt;/span&gt;-Package&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;SymbolicName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;${pom.artifactId}&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-SymbolicName&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 11: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;${pom.name}&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-Name&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Vendor&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Moritz Havelock&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-Vendor&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 13: 			&lt;strong&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Sling&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Initial&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;SLING-INF/initial-content&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Sling&lt;/span&gt;-Initial-Content&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/strong&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14: 		&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;instructions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt; 15: 	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 16: &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Build and Install&lt;/h5&gt;

&lt;p&gt;Before we build and install, remove the old test artifacts from the repository (the apps/samples/osgitest folder and the /content/test script).&lt;/p&gt;

&lt;p&gt;Then, as before, just do &amp;quot;mvn clean install&amp;quot;.&lt;/p&gt;

&lt;h5&gt;Test&lt;/h5&gt;

&lt;p&gt;We've moved the test script a bit, so now go to &lt;a href="http://localhost:7402/osgitest/test"&gt;http://localhost:7402/osgitest/test&lt;/a&gt; to see our service say &amp;quot;hello&amp;quot;.&lt;/p&gt;

&lt;h5&gt;&lt;/h5&gt;

&lt;p&gt;Properly done&lt;/p&gt;

&lt;p&gt;Above I mentioned that a combination of path specifications, overwrite and uninstall values is possible to enable the behaviour that is probably what someone would intuitively expect as the default behaviour.
  &lt;br /&gt;So, I want to&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;deploy content from the package&lt;/li&gt;

  &lt;li&gt;if resources are already existing where I want to deploy a resource, overwrite it&lt;/li&gt;

  &lt;li&gt;leave other resources alone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For that, I need to attach content-definitions to specific paths. For that, I need to re-structure my initial-content directory a bit:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;src/main/resources/SLING-INF/
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;`-- initial-content
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;    |-- apps
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;    |   `-- samples
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;    |       `-- osgitest
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;    |           `-- GET.esp
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;    `-- content
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        `-- osgitest
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;            `-- test.json&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Then, I change my Sling-Initial-Content tag in the pom to look like this:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Sling&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Initial&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;						
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2:   SLING-INF/initial-content/content/osgitest;path:=/content/osgitest;overwrite:=true;uninstall:=false,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  3:   SLING-INF/initial-content/apps/samples/osgitest;path:=/apps/samples/osgitest;overwrite:=true;uninstall:=true
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Sling&lt;/span&gt;-Initial-Content&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And the file test.json looks like this:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  1: {
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2:     &amp;quot;&lt;span style="color: #8b0000"&gt;jcr:primaryType&lt;/span&gt;&amp;quot; : &amp;quot;&lt;span style="color: #8b0000"&gt;nt:unstructured&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;  3:     &amp;quot;&lt;span style="color: #8b0000"&gt;sling:resourceType&lt;/span&gt;&amp;quot; : &amp;quot;&lt;span style="color: #8b0000"&gt;samples:osgitest&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 11px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;What does all that do?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In the first line in the Sling-Initial-Content tag in the pom, I state that I want to have content created at /content/osgitest. This restricts the whole operation to that path and makes sure that no other resources are touched (i.e. deleted in the overwrite). But that also means that my content definition in the JSON file must no longer contain the parent nodes of the &amp;quot;test&amp;quot; node. That is why the file now has a new name and contains only the properties of the single node it defines.
    &lt;br /&gt;By saying that uninstall is false, I make sure that when the package is uninstalled, the content still remains. You might want this for your package or no.

    &lt;br /&gt;&lt;strong&gt;Do note that even in this scenario, the whole subtree of /content/osgitest will be deleted before the content is re-deployed.&lt;/strong&gt; It's just everything outside of that path that is unaffected.&lt;/li&gt;

  &lt;li&gt;The second line does basically the same, but points deeper into the path through the path directive. Contents will be uninstalled when the bundle is uninstalled. 
    &lt;br /&gt;I could have omitted the uninstall directive here, as it defaults to the value of the overwrite directive.&lt;/li&gt;
&lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5750351649256467689-6240833838584581418?l=in-the-sling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/6240833838584581418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5750351649256467689&amp;postID=6240833838584581418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/6240833838584581418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/6240833838584581418'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/2008/09/sling-osgi-track-pt-5-bundling-initial.html' title='Sling OSGi Track pt 5: Bundling initial content'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/moritz.havelock/SL0pfSXkzEI/AAAAAAAAAB0/TzlR8BZBVFI/s72-c/snap001%202008-09-02_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5750351649256467689.post-9005792218747150049</id><published>2008-08-29T15:17:00.001+02:00</published><updated>2008-08-29T15:17:40.504+02:00</updated><title type='text'>Sling OSGi Track pt 4: installing to Sling using Maven</title><content type='html'>&lt;p&gt;This is the continuation of&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html"&gt;Sling OSGi Track pt 1: hand-rolled service bundle&lt;/a&gt; and &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-2-using-felix.html"&gt;Sling OSGi Track pt 2: using Felix' bundle plugin for manifest entries&lt;/a&gt; and &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-3-replacing.html"&gt;Sling OSGi Track pt 3: replacing the Activator with DS&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In this part, I will show how to install a maven-built bundle to sling directly from maven&lt;/p&gt;  &lt;h4&gt;Aims:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Show how to install a maven-built bundle to sling &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Ingredients:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://dev.day.com/microsling/content/blogs/cup/downloads.c.html"&gt;CRX quickstart&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html"&gt;Bundle Plugin for Maven&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-scr-plugin.html"&gt;SCR Plugin for Maven&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://incubator.apache.org/sling/site/sling.html"&gt;Maven Sling Plugin&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Files:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.4.jar"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.4.jar&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-4-src.zip"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-4-src.zip&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Outline:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Add the sling plugin to the pom &lt;/li&gt;    &lt;li&gt;Add the ASF incubating repository&lt;/li&gt;    &lt;li&gt;Build and Install &lt;/li&gt;    &lt;li&gt;Test &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Execution:&lt;/h4&gt;  &lt;h5&gt;Add the sling plugin to the pom&lt;/h5&gt;  &lt;p&gt;Add the following snippet to the build plugins.&lt;/p&gt;  &lt;p&gt;(8-10) bind the execution of the plugin's install-bundle goal to install phase goal   &lt;br /&gt;(11-15) configure the sling URL to use, the username and the password.&lt;/p&gt;  &lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.apache.sling&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;maven-sling-plugin&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;2.0.2-incubator&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;executions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;execution&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  7: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;install-bundle&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;goals&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  9: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;goal&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;install&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;goal&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10: 			&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;goals&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 11: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;slingUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;http://localhost:7402/system/console/install&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;slingUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 13: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;user&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;admin&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;user&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;password&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;admin&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;password&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 15: 			&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 16: 		&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;execution&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 17: 	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;executions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 18: &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Add the ASF incubating repository&lt;/h5&gt;

&lt;p&gt;The sling plugin (to date) lives in the Apache Software Foundation's incubating repository (as sling is still in the incubator).
  &lt;br /&gt;So for maven to be able to resolve the plugin, we must add the repository to the pom.

  &lt;br /&gt;While we're at it, we will also add it both as a plugin and as a regular artifact repository, as we'll be using other parts of sling later on.&lt;/p&gt;

&lt;p&gt;Add the following right before the &amp;lt;dependencies&amp;gt; section:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;repositories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;repository&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;apache.incubating&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Apache Incubating Repository&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;url&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;http://people.apache.org/repo/m2-incubating-repository&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;url&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6: 	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;repository&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  7: &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;repositories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8: &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;pluginRepositories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  9: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;pluginRepository&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;apache.incubating.plugins&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 11: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Apache Incubating Plugin Repository&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;url&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;http://people.apache.org/repo/m2-incubating-repository
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 13: 		&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;url&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14: 	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;pluginRepository&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 15: &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;pluginRepositories&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Build and Install &lt;/p&gt;

&lt;p&gt;Now, execute maven so:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;mvn clean &lt;strong&gt;install&lt;/strong&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;To verify that the new package is deployed, go to the sling console at &lt;a href="http://localhost:7402/system/console/list"&gt;http://localhost:7402/system/console/list&lt;/a&gt; and click on the &amp;quot;OSGI Test Bundle&amp;quot; to see the details

  &lt;br /&gt;(this only works in Firefox, not on IE, about others I do not know).&lt;/p&gt;

&lt;p&gt;I bumped the version by 0.0.1 for each part of this series, so we're now at 0.0.4.
  &lt;br /&gt;The version is taken from the pom's &amp;lt;version&amp;gt; element.

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/moritz.havelock/SLf28taFS5I/AAAAAAAAABo/gsfC9RDXuOM/snap001%202008-08-29%5B3%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="73" alt="snap001 2008-08-29" src="http://lh4.ggpht.com/moritz.havelock/SLf28-MBW0I/AAAAAAAAABs/iMaUs3e_ViA/snap001%202008-08-29_thumb%5B1%5D.png" width="341" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h5&gt;Test &lt;/h5&gt;

&lt;p&gt;As usual, go to &lt;a href="http://localhost:7402/test"&gt;http://localhost:7402/test&lt;/a&gt; to see the service say &amp;quot;hello&amp;quot;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5750351649256467689-9005792218747150049?l=in-the-sling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/9005792218747150049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5750351649256467689&amp;postID=9005792218747150049' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/9005792218747150049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/9005792218747150049'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-4-installing-to.html' title='Sling OSGi Track pt 4: installing to Sling using Maven'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/moritz.havelock/SLf28-MBW0I/AAAAAAAAABs/iMaUs3e_ViA/s72-c/snap001%202008-08-29_thumb%5B1%5D.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5750351649256467689.post-2858186864162281008</id><published>2008-08-29T12:25:00.003+02:00</published><updated>2008-08-29T14:02:55.893+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sling'/><category scheme='http://www.blogger.com/atom/ns#' term='crx'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><title type='text'>Sling OSGi Track pt 3: replacing the Activator with DS</title><content type='html'>&lt;p&gt;This is the continuation of&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html"&gt;Sling OSGi Track pt 1: hand-rolled service bundle&lt;/a&gt; and &lt;/li&gt;    &lt;li&gt;&lt;a href="http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-2-using-felix.html"&gt;Sling OSGi Track pt 2: using Felix' bundle plugin for manifest entries&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In this part, I will show how to declare the SampleService instead of registering it explicitly by an activator&lt;/p&gt;  &lt;h4&gt;Aims:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Show how to declare a service component &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Ingredients:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://dev.day.com/microsling/content/blogs/cup/downloads.c.html"&gt;CRX quickstart&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html"&gt;Bundle Plugin for Maven&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-scr-plugin.html"&gt;SCR Plugin for Maven&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Files:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a title="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.3.jar" href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.3.jar"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.3.jar&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-3-src.zip" href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-3-src.zip"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-3-src.zip&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Outline:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Add the scr plugin to the pom &lt;/li&gt;    &lt;li&gt;Remove the activator &lt;/li&gt;    &lt;li&gt;Add scr tags &lt;/li&gt;    &lt;li&gt;Build, Install, Test &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Execution:&lt;/h4&gt;  &lt;h5&gt;Add the scr plugin to the pom&lt;/h5&gt;  &lt;p&gt;Add the following snippet to the build plugins:&lt;/p&gt;  &lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; overflow: auto; min-height: 40px; width: 650px; background-color: rgb(251, 251, 251);"&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt;  1:  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;plugin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(255, 255, 255);font-family:monospace;font-size:12px;"&gt;  2:      &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;groupId&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;org.apache.felix&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;groupId&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt;  3:      &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;artifactId&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;maven-scr-plugin&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;artifactId&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(255, 255, 255);font-family:monospace;font-size:12px;"&gt;  4:      &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;version&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;1.0.7&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;version&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt;  5:      &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;executions&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(255, 255, 255);font-family:monospace;font-size:12px;"&gt;  6:          &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;execution&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt;  7:              &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;generate-scr-scrdescriptor&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(255, 255, 255);font-family:monospace;font-size:12px;"&gt;  8:              &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;goals&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt;  9:                  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;goal&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;scr&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;goal&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(255, 255, 255);font-family:monospace;font-size:12px;"&gt; 10:              &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;goals&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt; 11:          &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;execution&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(255, 255, 255);font-family:monospace;font-size:12px;"&gt; 12:      &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;executions&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt; 13:  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;plugin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Remove the activator&lt;/h5&gt;

&lt;p&gt;As we no longer will use explicit activation, we remove the Activator from the sources and remove the following line from the pom:&lt;/p&gt;

&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; overflow: auto; min-height: 40px; width: 650px; background-color: rgb(251, 251, 251);"&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Bundle&lt;/span&gt;-&lt;span style="color: rgb(255, 0, 0);"&gt;Activator&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;mh.osgitest.Activator&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Bundle&lt;/span&gt;-Activator&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Add scr tags&lt;/h5&gt;

&lt;p&gt;Now, we add the scr tags to the implementing class.&lt;/p&gt;

&lt;p&gt;Line (4) declares the class as a component. This will provide a wrapped ManagedService Component in the OSGi container

(I'll come to ManageServices later)&lt;/p&gt;

&lt;p&gt;Line (5) declares the service we are offering. Actually, the interface attribute is superflous, as by default, all implemented Interfaces are used.&lt;/p&gt;

&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; overflow: auto; min-height: 40px; width: 650px; background-color: rgb(251, 251, 251);"&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt;  1: &lt;span style="color: rgb(0, 0, 255);"&gt;package&lt;/span&gt; mh.osgitest;
&lt;/pre&gt;&lt;pre face="monospace" size="12px" style="margin: 0em; width: 100%; background-color: rgb(255, 255, 255);"&gt;  2:
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt;  3: &lt;span style="color: rgb(0, 128, 0);"&gt;/**
&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0em; font-size: 12px; width: 100%; font-family: monospace; background-color: rgb(255, 255, 255);"&gt;  4:  * @scr.component
&lt;/pre&gt;&lt;pre   style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);font-family:monospace;font-size:12px;"&gt;  5:  * @scr.service interface="SampleService"
&lt;/pre&gt;&lt;pre style="margin: 0em; font-size: 12px; width: 100%; font-family: monospace; background-color: rgb(255, 255, 255);"&gt;  6:  */
&lt;/pre&gt;&lt;pre face="monospace" size="12px" style="margin: 0em; width: 100%; background-color: rgb(250, 250, 250);"&gt;  7: &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; SampleServiceImpl &lt;span style="color: rgb(0, 0, 255);"&gt;implements&lt;/span&gt; SampleService {
&lt;/pre&gt;&lt;pre style="margin: 0em; font-size: 12px; width: 100%; font-family: monospace; background-color: rgb(255, 255, 255);"&gt;  8:  &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; String sayHello() {
&lt;/pre&gt;&lt;pre style="margin: 0em; font-size: 12px; width: 100%; font-family: monospace; background-color: rgb(250, 250, 250);"&gt;  9:   &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; "&lt;span style="color: rgb(139, 0, 0);"&gt;hello&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="margin: 0em; font-size: 12px; width: 100%; font-family: monospace; background-color: rgb(255, 255, 255);"&gt; 10:  }
&lt;/pre&gt;&lt;pre style="margin: 0em; font-size: 12px; width: 100%; font-family: monospace; background-color: rgb(250, 250, 250);"&gt; 11: }&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Build, Install, Test&lt;/h5&gt;

&lt;p&gt;First, mvn clean package&lt;/p&gt;

&lt;p&gt;To install the bundle, go to the system console at &lt;a href="http://localhost:7402/system/console/list"&gt;http://localhost:7402/system/console/list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then, call the URL &lt;a title="http://localhost:7402/test" href="http://localhost:7402/test"&gt;http://localhost:7402/test&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;For the detail of these two steps, have a look at the first post in this series: &lt;a title="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html" href="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html"&gt;/2008/08/basic-osgi-service-for-sling.html&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5750351649256467689-2858186864162281008?l=in-the-sling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/2858186864162281008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5750351649256467689&amp;postID=2858186864162281008' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/2858186864162281008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/2858186864162281008'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-3-replacing.html' title='Sling OSGi Track pt 3: replacing the Activator with DS'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5750351649256467689.post-5774840224576558411</id><published>2008-08-28T21:44:00.001+02:00</published><updated>2008-08-28T21:44:34.550+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sling'/><category scheme='http://www.blogger.com/atom/ns#' term='crx'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><title type='text'>Sling OSGi Track pt 2: using Felix' bundle plugin for manifest entries</title><content type='html'>&lt;p&gt;This is the continuation of&amp;#160; &lt;a href="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html"&gt;Sling OSGi Track pt 1: hand-rolled service bundle&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;In this part, I will remove the manually created MANIFEST.MF, and have it created by the Maven2 felix-bundle-plugin.&lt;/p&gt;  &lt;h4&gt;Aims:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;define OSGi-specific manifest entries in pom.xml and let Maven create the manifest &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Ingredients:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://dev.day.com/microsling/content/blogs/cup/downloads.c.html"&gt;CRX quickstart&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html"&gt;Bundle Plugin for Maven&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Files: &lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a title="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.2.jar" href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.2.jar"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.2.jar&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a title="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-2-src.zip" href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-2-src.zip"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-2-src.zip&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Outline:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;enable and configure the plugin in pom.xml &lt;/li&gt;    &lt;li&gt;change the packaging style in pom.xml &lt;/li&gt;    &lt;li&gt;stop merging our own manifest into the created jar and remove manifest file &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Execution:&lt;/h4&gt;  &lt;h5&gt;enable and configure the plugin in pom.xml&lt;/h5&gt;  &lt;p&gt;The plugin configuration is done in lines 20-35.    &lt;br /&gt;(27): Export-Package creates and Export-Package manifest entry with the same content     &lt;br /&gt;(28): same for Import-Package     &lt;br /&gt;(29): the symbolic name is taken from the pom's articactId     &lt;br /&gt;(30): the bundle name is taken from the pom's project name     &lt;br /&gt;(32): Bundle-Activator -- the main class&lt;/p&gt;  &lt;h5&gt;change the packaging style in pom.xml&lt;/h5&gt;  &lt;p&gt;We need to change the packaging style to &amp;quot;bundle&amp;quot; (defaults to &amp;quot;jar&amp;quot;) for the plugin to do its work.    &lt;br /&gt;This is done in line 8.&lt;/p&gt;  &lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;project&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;xsi&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: 	&lt;span style="color: #ff0000"&gt;xsi&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;schemaLocation&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;modelVersion&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;4.0.0&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;modelVersion&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;mh.studies&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;mh.studies.sling.osgitest&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;OSGI Test Bundle&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  7: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;0.0.2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;packaging&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;bundle&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;packaging&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  9: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;description&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;build&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 11: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plugins&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 13: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;maven-compiler-plugin&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 15: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 16: 					&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;source&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1.5&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;source&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 17: 					&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1.5&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 18: 				&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 19: 			&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 20: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 21: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.apache.felix&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 22: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;maven-bundle-plugin&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 23: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1.4.3&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 24: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;extensions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;true&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;extensions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 25: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 26: 					&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;instructions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 27: 						&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Export&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Package&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;mh.osgitest&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Export&lt;/span&gt;-Package&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 28: 						&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Import&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Package&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.osgi.framework;version=&amp;quot;1.3.0&amp;quot;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Import&lt;/span&gt;-Package&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 29: 						&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;SymbolicName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;${pom.artifactId}&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-SymbolicName&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 30: 						&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;${pom.name}&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-Name&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 31: 						&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Vendor&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Moritz Havelock&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-Vendor&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 32: 						&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;Activator&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;mh.osgitest.Activator&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Bundle&lt;/span&gt;-Activator&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 33: 						&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Built&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;By&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Moritz Havelock&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Built&lt;/span&gt;-By&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 34: 					&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;instructions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 35: 				&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 36: 			&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 37: 		&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plugins&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 38: 	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;build&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 39: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;dependencies&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 40: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;dependency&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 41: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.apache.felix&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 42: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.osgi.core&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 43: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1.0.1&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 44: 		&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;dependency&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 45: 	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;dependencies&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 46: &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;project&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;stop merging our own manifest into the created jar and remove manifest file&lt;/p&gt;

&lt;p&gt;We can now remove the file src/main/resources/META-INF/MANIFEST.MF, as this will be auto-generated. 
  &lt;br /&gt;Also, we can remove the following section from the pom.&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;maven-jar-plugin&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;2.2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;					&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;archive&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;						&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;manifestFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;src/main/resources/META-INF/MANIFEST.MF&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;manifestFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;					&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;archive&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;				&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;			&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;&amp;#160;&lt;/h5&gt;

&lt;h5&gt;Build&lt;/h5&gt;

&lt;p&gt;Do an &amp;quot;mvn clean package&amp;quot;.&lt;/p&gt;

&lt;p&gt;Now, open the created jar file ( target/mh.studies.sling.osgitest-0.0.2.jar ), and have a look at the created META-INF/MANIFEST.MF: 
  &lt;br /&gt;as you can see, all the lines we previously created manually are there, looking much the same. 

  &lt;br /&gt;There are slight differences in (7) -- the used packages are declared, and (3), (2), (11) and (15) are new.&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: Manifest-Version: 1.0
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: Built-By: Moritz Havelock
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3: Created-By: Apache Maven Bundle Plugin
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: Bundle-Activator: mh.osgitest.Activator
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: Import-Package: org.osgi.framework;version=&amp;quot;1.3.0&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6: Bnd-LastModified: 1219937878156
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  7: Export-Package: mh.osgitest;uses:=&amp;quot;org.osgi.framework&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8: Bundle-Version: 0.0.2
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  9: Bundle-Name: OSGI Test Bundle
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10: Bundle-ClassPath: .
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 11: Build-Jdk: 1.5.0_16
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12: Bundle-ManifestVersion: 2
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 13: Bundle-Vendor: Moritz Havelock
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14: Bundle-SymbolicName: mh.studies.sling.osgitest
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 15: Tool: Bnd-0.0.255&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h5&gt;Install / Test Client&lt;/h5&gt;

&lt;p&gt;To install the bundle, go to the system console at &lt;a href="http://localhost:7402/system/console/list"&gt;http://localhost:7402/system/console/list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then, call the URL &lt;a title="http://localhost:7402/test" href="http://localhost:7402/test"&gt;http://localhost:7402/test&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;For the detail of these two steps, have a look at the previous post: &lt;a title="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html" href="http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html"&gt;/2008/08/basic-osgi-service-for-sling.html&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5750351649256467689-5774840224576558411?l=in-the-sling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/5774840224576558411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5750351649256467689&amp;postID=5774840224576558411' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/5774840224576558411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/5774840224576558411'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/2008/08/sling-osgi-track-pt-2-using-felix.html' title='Sling OSGi Track pt 2: using Felix&amp;#39; bundle plugin for manifest entries'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5750351649256467689.post-1330234916639853339</id><published>2008-08-28T11:49:00.001+02:00</published><updated>2008-08-28T17:03:34.220+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sling'/><category scheme='http://www.blogger.com/atom/ns#' term='crx'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><title type='text'>Sling OSGi Track pt 1: hand-rolled service bundle</title><content type='html'>&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:6a303722-cd59-48ed-8965-b28b4259ae5d" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/sling" rel="tag"&gt;sling&lt;/a&gt;,&lt;a href="http://technorati.com/tags/osgi" rel="tag"&gt;osgi&lt;/a&gt;,&lt;a href="http://technorati.com/tags/crx" rel="tag"&gt;crx&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;This is the first in a series that tries to show how to create OSGi bundles for sling.&lt;/p&gt;  &lt;p&gt;I'll create a very simple service that answers with &amp;quot;hello&amp;quot; when asked to say hello.    &lt;br /&gt;This is little functionality, but demonstrates how to get the tools ready for creating CRX bundles.&lt;/p&gt;  &lt;h4&gt;Aims:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;create a service that returns the String &amp;quot;hello&amp;quot; when called with sayHello() &lt;/li&gt;    &lt;li&gt;use maven for building &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Ingredients:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;CRX-quickstart &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Files:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a title="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-1-src.zip" href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-1-src.zip"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0-0-1-src.zip&lt;/a&gt; (sources used)&lt;/li&gt;    &lt;li&gt;&lt;a title="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.1.jar" href="https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.1.jar"&gt;https://mhavelock-blog.s3.amazonaws.com/mh.studies.sling.osgitest-0.0.1.jar&lt;/a&gt; (completed OSGi bundle)&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Outline:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Project structure &lt;/li&gt;    &lt;li&gt;Define the service interface &lt;/li&gt;    &lt;li&gt;Create an implementation of that interface &lt;/li&gt;    &lt;li&gt;Create an Activator that registers the service &lt;/li&gt;    &lt;li&gt;Create the Manifest &lt;/li&gt;    &lt;li&gt;Create the Maven pom &lt;/li&gt;    &lt;li&gt;Build &lt;/li&gt;    &lt;li&gt;Install &lt;/li&gt;    &lt;li&gt;Create a test client &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Execution:&lt;/h4&gt;  &lt;h5&gt;Project structure&lt;/h5&gt;  &lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;.
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;|-- pom.xml
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;`-- src
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;    `-- main
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |-- java
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |   `-- mh
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |       `-- osgitest
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |           |-- Activator.java
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |           |-- SampleService.java
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        |           `-- SampleServiceImpl.java
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;        `-- resources
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;            `-- META-INF
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fbfbfb"&gt;                `-- MANIFEST.MF&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Define the service interface&lt;/h5&gt;

&lt;p&gt;The service interface is straightforward: it contains a single public method.&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: package mh.osgitest;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3: public interface SampleService {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: 	public String sayHello();
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: }&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Create an implementation of that interface&lt;/h5&gt;

&lt;p&gt;This is just as easy and pojo:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: &lt;span style="color: #0000ff"&gt;package&lt;/span&gt; mh.osgitest;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SampleServiceImpl &lt;span style="color: #0000ff"&gt;implements&lt;/span&gt; SampleService {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: 	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; String sayHello() {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: 		&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &amp;quot;&lt;span style="color: #8b0000"&gt;hello&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6: 	}
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  7: }
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8: &lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Create an activator that registers the service &lt;/h5&gt;

&lt;p&gt;Every OSGi bundle must have an activator that implements the BundleActivator interface. 
  &lt;br /&gt;(simplification. declarative services do not need an activator).&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://www.osgi.org/javadoc/r4/org/osgi/framework/BundleActivator.html"&gt;BundleActivator&lt;/a&gt; gives us start and stop methods that will be called when the bundles is started / stopped by the container. 

  &lt;br /&gt;In the start method, the service instance is created (11), and then registered. The registerService method of the &lt;a href="http://www.osgi.org/javadoc/r4/org/osgi/framework/BundleContext.html"&gt;BundleContext&lt;/a&gt; receives the class name under which the service is registered and by which it can be located (14), the service instance (15) and an empty configuration table.&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: &lt;span style="color: #0000ff"&gt;package&lt;/span&gt; mh.osgitest;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; java.util.Hashtable;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.osgi.framework.BundleActivator;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: &lt;span style="color: #0000ff"&gt;import&lt;/span&gt; org.osgi.framework.BundleContext;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6: 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  7: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Activator &lt;span style="color: #0000ff"&gt;implements&lt;/span&gt; BundleActivator {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8: 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  9: 	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; start(BundleContext context) &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; Exception {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10: 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 11: 		SampleService sample = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SampleServiceImpl();
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12: 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 13: 		context.registerService(
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14: 				SampleService.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;.getName(), 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 15: 				sample,
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 16: 				&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Hashtable&amp;lt;Object, Object&amp;gt;());
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 17: 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 18: 		System.err.println(&amp;quot;&lt;span style="color: #8b0000"&gt;SampleService Started&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 19: 	}
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 20: 
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 21: 	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; stop(BundleContext context) &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; Exception {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 22: 		System.err.println(&amp;quot;&lt;span style="color: #8b0000"&gt;SampleService Stopped&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 23: 	}
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 24: }&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Create the Manifest &lt;/h5&gt;

&lt;p&gt;The manifest file needs some OSGi specific entries:&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: Manifest-Version: 1.0
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: Bundle-ManifestVersion: 2
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3: Bundle-Name: Simple OSGITest
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: Bundle-SymbolicName: mh.osgitest
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: Bundle-Version: 1.0.0
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6: Bundle-Activator: mh.osgitest.Activator
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  7: Bundle-Vendor: Moritz Havelock
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8: Import-Package: org.osgi.framework;version=&amp;quot;&lt;span style="color: #8b0000"&gt;1.3.0&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  9: Export-Package: mh.osgitest;version=0.0.1
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10: Bundle-ClassPath: .&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;(3) Name of the Bundle. Choose freely 

  &lt;br /&gt;(4) The symbolic name by which the bundle is referred to. 

  &lt;br /&gt;(6) the activator is the name of the class that implements BundleActivator 

  &lt;br /&gt;(8) Import-Package declares the packages that this bundle expects to be provided by other packages. 

  &lt;br /&gt;(9) Export-Package declares the package that is exposed and available to other bundles. 

  &lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Create the Maven pom &lt;/h5&gt;

&lt;p&gt;The only things needed (except for dependencies) are &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;configuring our own manifest file to be blended in when bundling the jar file and &lt;/li&gt;

  &lt;li&gt;setting source style to Java 5 &lt;/li&gt;
&lt;/ul&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;project&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;xsi&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: 	&lt;span style="color: #ff0000"&gt;xsi&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;schemaLocation&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;modelVersion&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;4.0.0&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;modelVersion&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;mh.studies&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;mh.studies.sling.osgitest&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  6: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;OSGI Test Bundle&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  7: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;0.0.1&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  8: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;description&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  9: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;build&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 10: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plugins&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 11: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 12: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 13: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;maven-jar-plugin&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 14: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;2.2&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 15: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 16: 					&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;archive&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 17: 						&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;manifestFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;src/main/resources/META-INF/MANIFEST.MF&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;manifestFile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 18: 					&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;archive&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 19: 				&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 20: 			&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 21: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 22: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 23: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;maven-compiler-plugin&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 24: 				&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 25: 					&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;source&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1.5&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;source&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 26: 					&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1.5&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 27: 				&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 28: 			&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plugin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 29: 		&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plugins&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 30: 	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;build&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 31: 	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;dependencies&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 32: 		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;dependency&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 33: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.apache.felix&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;groupId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 34: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;org.osgi.core&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;artifactId&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 35: 			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;1.0.1&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 36: 		&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;dependency&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt; 37: 	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;dependencies&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt; 38: &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;project&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Build &lt;/h5&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;mvn clean package&lt;/pre&gt;&lt;/pre&gt;

&lt;h5&gt;Install &lt;/h5&gt;

&lt;p&gt;To install the bundle, go to the system console at &lt;a title="http://localhost:7402/system/console/list" href="http://localhost:7402/system/console/list"&gt;http://localhost:7402/system/console/list&lt;/a&gt;. 

  &lt;br /&gt;(note that the system console does not fully work in Internet Explorer) 

  &lt;br /&gt;

  &lt;br /&gt;Hit the &amp;quot;Browse&amp;quot; button and select the jar file from the target/ directory created by maven.&lt;/p&gt;

&lt;p&gt;Check the &amp;quot;Start&amp;quot; box, level the level at 20 and hit &amp;quot;Install or Update&amp;quot;.&lt;/p&gt;

&lt;p&gt;Then, hit &amp;quot;Refresh Package&amp;quot;. You will then see an entry &amp;quot;Simple OSGITest&amp;quot; in the list of bundles. Click it to see an expanded view. 
  &lt;br /&gt;You will see the Bundle properties, plus the registered service of type mh.osgitest.SampleService.&lt;/p&gt;

&lt;p&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="235" alt="SimpleOSGI-expanded" src="http://lh3.ggpht.com/moritz.havelock/SLZ0xQprPcI/AAAAAAAAABg/Vt8B9dn9YII/SimpleOSGI-expanded%5B6%5D.png" width="542" border="0" /&gt; &lt;/p&gt;

&lt;h5&gt;Create a test client &lt;/h5&gt;

&lt;p&gt;In the CRX browser, create a node /content/test of type nt:unstructured, and give it a property &amp;quot;sling:resourceType&amp;quot; with a value of &amp;quot;samples:osgitest&amp;quot;. 
  &lt;br /&gt;Create the structure /apps/samples/osgitest, and there create the file GET.esp with the following contents.&lt;/p&gt;

&lt;p&gt;In line 3, the service is obtained from the sling helper object.&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  1: &amp;lt;%
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  2: &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; service =
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  3:   sling.getService(Packages.mh.osgitest.SampleService);
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;  4:   
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;  5: %&amp;gt;&amp;lt;%= service.sayHello() %&amp;gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now, you can use a browser or curl to call that URL with an impressing result ;-)&lt;/p&gt;

&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #fafafa"&gt;D:\projekte\workspace-sling\mh.studies.sling.osgitest&amp;gt;curl http://localhost:7402/test
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: monospace; background-color: #ffffff"&gt;hello&lt;/pre&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5750351649256467689-1330234916639853339?l=in-the-sling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-the-sling.blogspot.com/feeds/1330234916639853339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5750351649256467689&amp;postID=1330234916639853339' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/1330234916639853339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5750351649256467689/posts/default/1330234916639853339'/><link rel='alternate' type='text/html' href='http://in-the-sling.blogspot.com/2008/08/basic-osgi-service-for-sling.html' title='Sling OSGi Track pt 1: hand-rolled service bundle'/><author><name>Moritz Havelock</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/moritz.havelock/SLZ0xQprPcI/AAAAAAAAABg/Vt8B9dn9YII/s72-c/SimpleOSGI-expanded%5B6%5D.png' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
