incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling Website > Embedding Sling
Date Mon, 19 Sep 2011 09:59:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=SLINGxSITE&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Embedding+Sling">Embedding
Sling</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~fmeschbe">Felix
Meschberger</a>
    </h4>
        <br/>
                         <h4>Changes (3)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">h3<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">
</span>.</span> Standalone Java Application <br></td></tr>
            <tr><td class="diff-unchanged" > <br>The standalone Java Application
makes use of three classes: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >At the moment these classes are not
directly suitable to be embedded in an existing application (or custom application launcher
framework) unless that embedding prepares command line arguments in a {{String[]}} and calls
the {{Main.main}} method. To allow for custom embeddings or extensions, the work distriubtions
between the three classes should be refactored. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3.
Embedding the Standalone Java Application <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{info}
<br>This work is being done as part of [SLING-2225|https://issues.apache.org/jira/browse/SLING-2225]
and will be officially available with the Sling Launchpad Base release 2.4.0. If you want
to use the embedding before the release, you have to checkout the source from [SVN|http://svn.apache.org/repos/asf/sling/trunk/launchpad/base]
and build yourself. <br>{info} <br> <br>To embedd the Sling Launcher in
an application, the {{Main}} class is extended from. To manage the launcher, the following
API is available: <br> <br>|| Method || Description || <br>| {{Main(Map&lt;String,
String&gt; properties)}} | Instantiates the Main class with the given configuration properties.
These are properties which are used directly as overwrites to the configurations in the {{sling.properties}}
file. There is no more conversion applied. | <br>| {{doControlCommand()}} | Before starting
the application for the first time, this method can be called to handle any control command
action. | <br>| {{doStart()}} | Starts the Sling Application using the provided configuration
properties as overwrites. Also these properties (or the {{sling.home}} system property or
the {{SLING_HOME}} environment variable are analyzed to get the value for the {{sling.home}}
setting. | <br>| {{doStop()}} | Stops the application started by the {{doStart()}} method.
| <br> <br> <br>h4. External Control of the Sling Application <br>
<br>By using control actions, the Sling Launcher may open or connect to a control port
to communicate. The {{doControlAction()}} method together with the {{sling.control.action}}
and {{sling.control.socket}} properties is able to setup this communication. <br> <br>The
{{sling.control.socket}} is either a normal port number, in which case the connection is opened
on the {{localhost}} interface (usually 127.0.0.1). Otheriwse, it may also be a value of the
form _host:port_ where _host_ is the name or IP address of the interface to connect to and
port is the port number. For security reasons it is suggested to not use an interface which
is available remotely. So the default of {{localhost}} is usually the best choice. <br>
<br>The {{sling.control.action}} takes either of three values: <br> <br>|
{{start}} | Starts a server socket as specified by the {{sling.control.socket}} property.
If the socket cannot be bound to (because the port is in use) an error message is printed.
| <br> <br> <br> <br>h4. Conversion of Commandline Arguments to Properties
<br> <br>When calling the Main class through the JVM startup the {{Main.main(String[]
args)}} methods is called which reads the command line arguments and converts them into a
{{Map&lt;String, String&gt;}} suitable for the constructore as follows: <br>
<br>|| Command Line Argument || Properties Entry || <br>| start | sling.control.action
= &quot;start&quot; | <br>| status | sling.control.action = &quot;status&quot;
| <br>| stop | sling.control.action = &quot;stop&quot; | <br>| -c slinghome
| sling.home = slinghome | <br>| -l loglevel | org.apache.sling.commons.log.level =
loglevel | <br>| -f logfile | org.apache.sling.commons.log.file = logfile | <br>|
-a address | This command line argument is not supported yet and thus ignored | <br>|
-p port | org.osgi.service.http.port = port | <br>| -j [ host &quot;:&quot;
] port | sling.control.socket = [ host &quot;:&quot; ] port | <br>| -h | This
command line option is handled directly and not converted into the map | <br> <br>
<br></td></tr>
            <tr><td class="diff-unchanged" >h3. Web Application <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h1><a name="EmbeddingSling-EmbeddingSling"></a>Embedding Sling</h1>

<p>The Sling Launchpad Launcher can be used to embed the OSGi Framework startup in your
own Java application. This functionality is implemented in the <a href="http://svn.apache.org/repos/asf/sling/trunk/launchpad/base"
class="external-link" rel="nofollow">Sling Launchpad Base project</a>. This project
has the following features:</p>

<ul>
	<li>Builds three artifacts:
	<ul>
		<li>A standalone Java Application with the artifact qualifier <em>app</em>;
e.g. <tt>org.apache.sling.launchpad.base-2.3.1-SNAPSHOT-app.jar</tt></li>
		<li>A Web Application with the artifact qualifier <em>webapp</em>; e.g
<tt>org.apache.sling.launchpad.base-2.3.1-SNAPSHOT-wepabb.war</tt></li>
		<li>The primary artifact without an artifact qualifier; e.g. <tt>org.apache.sling.launchpad.base-2.3.1-SNAPSHOT.jar</tt></li>
	</ul>
	</li>
	<li>Embeds the OSGi Framework (Apache Felix) in the primary artifact</li>
	<li>Encapsulates the OSGi Framework in its own <tt>URLClassLoader</tt></li>
	<li>Supports Framework restart</li>
	<li>Allows propagation of core setup functionality depending on the environment</li>
</ul>


<p>This page is about the internal details of the Sling Launchpad Base module. To get
an outside overview of the Sling Launchpad you might want to refer to <a href="/confluence/display/SLINGxSITE/The+Sling+Launchpad"
title="The Sling Launchpad">The Sling Launchpad</a> page.</p>

<h1><a name="EmbeddingSling-Structure"></a>Structure</h1>

<p>The Launcher is based on three parts:</p>
<ol>
	<li>The external part which is for example the standalone Java application's main class
or the servlet deployed into the servlet container</li>
	<li>The internal part which is the OSGi framework plus helper classes to control the
framework and run initial installations</li>
	<li>The bridging part, which contains API common to the external and internal part.</li>
</ol>


<p>The external part uses the bridging part to create the class loader into which the
internal part is loaded. The bidirectional communication between the external and internal
part is implement based on two interfaces:</p>

<ul>
	<li>The <tt>Launcher</tt> interface is implemented by a class in the internal
part which is loaded through the bridge class loader. This interface allows setting, starting
and stopping of the framework.</li>
	<li>The <tt>Notifiable</tt> interface is implemented by a class in the
external part which instance is handed to the <tt>Launcher</tt> instance. This
interface allows the internal part to communicate back to the external part, most notably
to indicate that the framework has been stopped from within or that the framework has been
updated and must be restarted.</li>
</ul>



<h1><a name="EmbeddingSling-TheBridgingPart"></a>The Bridging Part</h1>

<p>The bridging part is provided in the <tt>org.apache.sling.launchpad.base.shared</tt>
package:</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> Class </td>
<td class='confluenceTd'> Description </td>
</tr>
<tr>
<td class='confluenceTd'> Launcher </td>
<td class='confluenceTd'> The interface implemented by the internal class matching the
external class being called to start/stop the framework. </td>
</tr>
<tr>
<td class='confluenceTd'> LauncherClassLoader </td>
<td class='confluenceTd'> <tt>URLClassLoader</tt> implementing the class
loader to load the internal part (along with the OSGi framework). This class loader only delegates
to the parent class loader any packages not contained in the launchpad library (primary artifact
of the Launchpad Base project). </td>
</tr>
<tr>
<td class='confluenceTd'> Loader </td>
<td class='confluenceTd'> Helper class to find the launchpad library and to create the
<tt>LauncherClassLoader</tt> with that library. This class is also used to actually
load the <tt>Launcher</tt> implementation to be called from the external launcher
class. </td>
</tr>
<tr>
<td class='confluenceTd'> Notifiable </td>
<td class='confluenceTd'> The interface implemented in the external part and handed
over to the internal part. </td>
</tr>
<tr>
<td class='confluenceTd'> SharedConstants </td>
<td class='confluenceTd'> Constants naming various properties and classes. </td>
</tr>
</tbody></table>
</div>



<h1><a name="EmbeddingSling-TheInternalPart"></a>The Internal Part</h1>

<p>The main class from the internal class directly used is <a href="http://svn.apache.org/repos/asf/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/Sling.java"
class="external-link" rel="nofollow"><tt>Sling</tt></a> which instantiated
to start the OSGi Framework. This class is responsible for setting up the environment to finally
start the OSGi Framework:</p>

<ul>
	<li>Read the <tt>sling.properties</tt> file</li>
	<li>Ensure the presence of the JMX MBeanServer service</li>
	<li>Execute the bootstrap installations, updates and uninstallations</li>
</ul>


<p>The <a href="http://svn.apache.org/repos/asf/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/SlingFelix.java"
class="external-link" rel="nofollow"><tt>SlingFelix</tt></a> class extends
the Apache Felix <tt>Felix</tt> class which is the actual OSGi framework implementation.
We extend the class to be able to notify the <tt>Notifiable</tt> implementation
and update the OSGi framework from within the OSGi framework by updating the system bundle.</p>


<h2><a name="EmbeddingSling-TheExternalPart"></a>The External Part</h2>

<p>The external part is comprised of a main class started from the environment &#8211;
main class of the Java applicaction or the servlet deployed in the servlet container &#8211;
and a corresponding delegate class located inside of the launchpad base library. This delegate
class is instantiated by the <tt>Loader</tt> loading from the <tt>LauncherClassLoader</tt>.</p>


<h3><a name="EmbeddingSling-StandaloneJavaApplication"></a>Standalone Java
Application</h3>

<p>The standalone Java Application makes use of three classes:</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> Class </td>
<td class='confluenceTd'> Description </td>
</tr>
<tr>
<td class='confluenceTd'> Main </td>
<td class='confluenceTd'> This is the main class whose <tt>main</tt> method
is called by the Java VM. This class is itself the <tt>Notifiable</tt> and finds
the <tt>sling.home</tt> location from the environment (command line parameter,
system property, or environment variable). </td>
</tr>
<tr>
<td class='confluenceTd'> MainDelegate </td>
<td class='confluenceTd'> This class is loaded by the <tt>Loader</tt> from
the <tt>LauncherClassLoader</tt> to actually complete the initial setup before
creating the <tt>Sling</tt> class to start the framework. </td>
</tr>
<tr>
<td class='confluenceTd'> ControlListener </td>
<td class='confluenceTd'> This class is used by the <tt>Main</tt> class
to open a server socket to be able to start and stop Sling as a server. This class allows
for starting (opening the server socket), status check (connecting to the socket asking for
status), and shutdown (connecting to the socket asking for shutdown). </td>
</tr>
</tbody></table>
</div>


<p>At the moment these classes are not directly suitable to be embedded in an existing
application (or custom application launcher framework) unless that embedding prepares command
line arguments in a <tt>String[]</tt> and calls the <tt>Main.main</tt>
method. To allow for custom embeddings or extensions, the work distriubtions between the three
classes should be refactored.</p>

<h3><a name="EmbeddingSling-EmbeddingtheStandaloneJavaApplication"></a>Embedding
the Standalone Java Application</h3>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td>This work is being
done as part of <a href="https://issues.apache.org/jira/browse/SLING-2225" class="external-link"
rel="nofollow">SLING-2225</a> and will be officially available with the Sling Launchpad
Base release 2.4.0. If you want to use the embedding before the release, you have to checkout
the source from <a href="http://svn.apache.org/repos/asf/sling/trunk/launchpad/base" class="external-link"
rel="nofollow">SVN</a> and build yourself.</td></tr></table></div>

<p>To embedd the Sling Launcher in an application, the <tt>Main</tt> class
is extended from. To manage the launcher, the following API is available:</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Method </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>Main(Map&lt;String, String&gt; properties)</tt>
</td>
<td class='confluenceTd'> Instantiates the Main class with the given configuration properties.
These are properties which are used directly as overwrites to the configurations in the <tt>sling.properties</tt>
file. There is no more conversion applied. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>doControlCommand()</tt> </td>
<td class='confluenceTd'> Before starting the application for the first time, this method
can be called to handle any control command action. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>doStart()</tt> </td>
<td class='confluenceTd'> Starts the Sling Application using the provided configuration
properties as overwrites. Also these properties (or the <tt>sling.home</tt> system
property or the <tt>SLING_HOME</tt> environment variable are analyzed to get the
value for the <tt>sling.home</tt> setting. </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>doStop()</tt> </td>
<td class='confluenceTd'> Stops the application started by the <tt>doStart()</tt>
method. </td>
</tr>
</tbody></table>
</div>



<h4><a name="EmbeddingSling-ExternalControloftheSlingApplication"></a>External
Control of the Sling Application</h4>

<p>By using control actions, the Sling Launcher may open or connect to a control port
to communicate. The <tt>doControlAction()</tt> method together with the <tt>sling.control.action</tt>
and <tt>sling.control.socket</tt> properties is able to setup this communication.</p>

<p>The <tt>sling.control.socket</tt> is either a normal port number, in
which case the connection is opened on the <tt>localhost</tt> interface (usually
127.0.0.1). Otheriwse, it may also be a value of the form <em>host:port</em> where
<em>host</em> is the name or IP address of the interface to connect to and port
is the port number. For security reasons it is suggested to not use an interface which is
available remotely. So the default of <tt>localhost</tt> is usually the best choice.</p>

<p>The <tt>sling.control.action</tt> takes either of three values:</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> <tt>start</tt> </td>
<td class='confluenceTd'> Starts a server socket as specified by the <tt>sling.control.socket</tt>
property. If the socket cannot be bound to (because the port is in use) an error message is
printed. </td>
</tr>
</tbody></table>
</div>




<h4><a name="EmbeddingSling-ConversionofCommandlineArgumentstoProperties"></a>Conversion
of Commandline Arguments to Properties</h4>

<p>When calling the Main class through the JVM startup the <tt>Main.main(String[]
args)</tt> methods is called which reads the command line arguments and converts them
into a <tt>Map&lt;String, String&gt;</tt> suitable for the constructore
as follows:</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Command Line Argument </th>
<th class='confluenceTh'> Properties Entry </th>
</tr>
<tr>
<td class='confluenceTd'> start </td>
<td class='confluenceTd'> sling.control.action = "start" </td>
</tr>
<tr>
<td class='confluenceTd'> status </td>
<td class='confluenceTd'> sling.control.action = "status" </td>
</tr>
<tr>
<td class='confluenceTd'> stop </td>
<td class='confluenceTd'> sling.control.action = "stop" </td>
</tr>
<tr>
<td class='confluenceTd'> -c slinghome </td>
<td class='confluenceTd'> sling.home = slinghome </td>
</tr>
<tr>
<td class='confluenceTd'> -l loglevel </td>
<td class='confluenceTd'> org.apache.sling.commons.log.level = loglevel </td>
</tr>
<tr>
<td class='confluenceTd'> -f logfile </td>
<td class='confluenceTd'> org.apache.sling.commons.log.file = logfile </td>
</tr>
<tr>
<td class='confluenceTd'> -a address </td>
<td class='confluenceTd'> This command line argument is not supported yet and thus ignored
</td>
</tr>
<tr>
<td class='confluenceTd'> -p port </td>
<td class='confluenceTd'> org.osgi.service.http.port = port </td>
</tr>
<tr>
<td class='confluenceTd'> -j [ host ":" ] port </td>
<td class='confluenceTd'> sling.control.socket = [ host ":" ] port </td>
</tr>
<tr>
<td class='confluenceTd'> -h </td>
<td class='confluenceTd'> This command line option is handled directly and not converted
into the map </td>
</tr>
</tbody></table>
</div>



<h3><a name="EmbeddingSling-WebApplication"></a>Web Application</h3>

<p>The web application makes use of 5 classes:</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> Class </td>
<td class='confluenceTd'> Description </td>
</tr>
<tr>
<td class='confluenceTd'> SlingServlet </td>
<td class='confluenceTd'> This is the servlet registered in the <tt>web.xml</tt>
descriptor and loaded by the servlet container into which Sling is deplyoed. This class locates
the <tt>sling.home</tt> folder and loads the <tt>SlingServletDelagate</tt>
to actually launch the framework. </td>
</tr>
<tr>
<td class='confluenceTd'> SlingSessionListener </td>
<td class='confluenceTd'> This &#8211; somewhat inappropriately named &#8211;
class is registered as a listener by the Sling <tt>web.xml</tt> descriptor. It
is called by the servlet container and forwards events to the <tt>SlingHttpSessionListenerDelegate</tt>
which in turn forwards the events to the respective Servlet API listener services registered
in the OSGi Framework. </td>
</tr>
<tr>
<td class='confluenceTd'> SlingBridge </td>
<td class='confluenceTd'> Simple extension of the <tt>Sling</tt> class which
registers the system bundle's <tt>BundleContext</tt> as a servlet context attribute
of the Sling web application. This allows Servlet Container bridging to properly work. </td>
</tr>
<tr>
<td class='confluenceTd'> SlingHttpSessionListenerDelegate </td>
<td class='confluenceTd'> This class is loaded by the <tt>LauncherClassLoader</tt>
called from the <tt>SlingSessionListener</tt>. It is called by the <tt>SlingSessionListener</tt>
to forward servlet container events to registered Servlet API listener services. </td>
</tr>
<tr>
<td class='confluenceTd'> SlingServletDelegate </td>
<td class='confluenceTd'> This class is loaded by the <tt>Loader</tt> from
the <tt>LauncherClassLoader</tt> to actually complete the initial setup before
creating the <tt>SlingBridge</tt> class to start the framework. </td>
</tr>
</tbody></table>
</div>


<p>At the moment these classes, particularly the <tt>SlingServlet</tt> class,
are not particularly well suited to be extended by a servlet slightly modifying the launcher.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Embedding+Sling">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=27826084&revisedVersion=5&originalVersion=4">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Embedding+Sling?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message