geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Geronimo Development > OSGI conversion tips
Date Thu, 05 Nov 2009 13:41:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=GMOxDEV&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/GMOxDEV/OSGI+conversion+tips">OSGI
conversion tips</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~rickmcguire">Rick
McGuire</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <div>
<ul>
    <li><a href='#OSGIconversiontips-jarswithxmlbeanscompilation'>jars with xmlbeans
compilation</a></li>
    <li><a href='#OSGIconversiontips-Nonbundleinterference'>Non-bundle interference</a></li>
    <li><a href='#OSGIconversiontips-Assembleaservertomakesureeachsetofpluginsstarts.'>Assemble
a server to make sure each set of plugins starts.</a></li>
    <li><a href='#OSGIconversiontips-Classloadingproblems'>Classloading problems</a></li>
    <li><a href='#OSGIconversiontips-Classloadingproblems'>Classloading problems</a></li>
    <li><a href='#OSGIconversiontips-Loggingconversion'>Logging conversion</a></li>
</ul></div>

<h2><a name="OSGIconversiontips-Letscollecttipsonosgiconversionhere"></a>Lets
collect tips on osgi conversion here</h2>

<h3><a name="OSGIconversiontips-jarswithxmlbeanscompilation"></a>jars with
xmlbeans compilation</h3>
<p>To use xmlbeans generated code you need access to the SchemaTypeSystemImpl, which
is not imported by the maven-bundle-plugin.  So you need to add something like this to the
pom:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.felix&lt;/groupId&gt;
                &lt;artifactId&gt;maven-bundle-plugin&lt;/artifactId&gt;
                &lt;configuration&gt;
                    &lt;instructions&gt;
                        &lt;!--packages containing <span class="code-quote">"impl"</span>
or <span class="code-quote">"internal"</span> are excluded by <span class="code-keyword">default</span>
--&gt;
                        &lt;Import-Package&gt;org.apache.xmlbeans.impl.schema;version=<span
class="code-quote">"2.4"</span>,*&lt;/Import-Package&gt;
                        &lt;!--&lt;_versionpolicy&gt;[$(version;==;$(@)),$(version;+;$(@)))&lt;/_versionpolicy&gt;--&gt;
                    &lt;/instructions&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
</pre>
</div></div>

<p>Also, any package we may have with "impl" or "internal" needs to be explicitly listed
in the Export-Packages.</p>

<h3><a name="OSGIconversiontips-Nonbundleinterference"></a>Non-bundle interference</h3>
<p>Many problems with building plugins are caused by non-bundle dependencies getting
installed in felix rather than bundleized equivalents.  Unfortuneately it looks like felix
only says "non-framework bundles cannot be started" without telling us the location of the
non-bundle.  Running</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">mvn dependency:tree
</pre>
</div></div>
<p>helps to find the bad dependencies.  On a related note, generally you have to exclude
original jars from the dependencyManagement dependency entry of a bundleized repackaging.
 This seems like a serious defect in maven-bundle-plugin.</p>

<h3><a name="OSGIconversiontips-Assembleaservertomakesureeachsetofpluginsstarts."></a>Assemble
a server to make sure each set of plugins starts.</h3>
<p>I think it's a good idea to assemble a server for each set of plugins to make sure
they at least start.  Here's how:</p>

<ol>
	<li>run
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">mvn archetype:create \
   -DarchetypeGroupId=org.apache.geronimo.buildsupport \
   -DarchetypeArtifactId=geronimo-assembly-archetype \
   -DarchetypeVersion=3.0-SNAPSHOT \
   -DgroupId=org.apache.geronimo.plugins \
   -DartifactId=geronimo-&lt;foo&gt;-server
</pre>
</div></div> 
<p>where &lt;foo&gt; is your set of plugins</p></li>
	<li>add it to svn</li>
	<li>add the plugins you want to test as depedendencies</li>
	<li>add this to start the server when run with -Pit<br/>
in plugin management:
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">                &lt;plugin&gt;
                    &lt;groupId&gt;org.apache.geronimo.buildsupport&lt;/groupId&gt;
                    &lt;artifactId&gt;geronimo-maven-plugin&lt;/artifactId&gt;
                    &lt;version&gt;${version}&lt;/version&gt;

                    &lt;configuration&gt;
                       &lt;assemblyArchive&gt;${project.build.directory}/${pom.artifactId}-${pom.version}-bin.zip&lt;/assemblyArchive&gt;
                        &lt;optionSets&gt;
                            &lt;optionSet&gt;
                                &lt;id&gt;morememory&lt;/id&gt;
                                &lt;options&gt;
                                    &lt;option&gt;-Xmx512m&lt;/option&gt;
                                    &lt;option&gt;-XX:MaxPermSize=128m&lt;/option&gt;
                                &lt;/options&gt;
                            &lt;/optionSet&gt;

                            &lt;optionSet&gt;
                                &lt;id&gt;debug&lt;/id&gt;
                                &lt;options&gt;
                                    &lt;option&gt;-Xdebug&lt;/option&gt;
                                    &lt;option&gt;-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n&lt;/option&gt;
                                &lt;/options&gt;
                            &lt;/optionSet&gt;
                        &lt;/optionSets&gt;
                    &lt;/configuration&gt;
                    &lt;executions&gt;
                         &lt;execution&gt;
                             &lt;id&gt;start&lt;/id&gt;
                             &lt;phase&gt;pre-integration-test&lt;/phase&gt;
                             &lt;goals&gt;
                                 &lt;goal&gt;start-server&lt;/goal&gt;
                             &lt;/goals&gt;
                             &lt;configuration&gt;
                                 &lt;assemblyId&gt;${it-server}&lt;/assemblyId&gt;
                                 &lt;logOutput&gt;<span class="code-keyword">true</span>&lt;/logOutput&gt;
                                 &lt;background&gt;<span class="code-keyword">true</span>&lt;/background&gt;
                                 &lt;verifyTimeout&gt;300&lt;/verifyTimeout&gt;
                                 &lt;refresh&gt;<span class="code-keyword">true</span>&lt;/refresh&gt;
                                 &lt;optionSets&gt;
                                     &lt;optionSet&gt;
                                         &lt;id&gt;<span class="code-keyword">default</span>&lt;/id&gt;
                                         &lt;options&gt;
                                            &lt;option&gt;-XX:MaxPermSize=128m&lt;/option&gt;
                                         &lt;/options&gt;
                                     &lt;/optionSet&gt;

                                     &lt;optionSet&gt;
                                          &lt;id&gt;morememory&lt;/id&gt;
                                          &lt;options&gt;
                                              &lt;option&gt;-Xmx512m&lt;/option&gt;
                                              &lt;option&gt;-XX:MaxPermSize=128m&lt;/option&gt;
                                          &lt;/options&gt;
                                      &lt;/optionSet&gt;

                                      &lt;optionSet&gt;
                                          &lt;id&gt;debug&lt;/id&gt;
                                          &lt;options&gt;
                                              &lt;option&gt;-Xdebug&lt;/option&gt;
                                              &lt;option&gt;-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n&lt;/option&gt;
                                          &lt;/options&gt;
                                      &lt;/optionSet&gt;
                                 &lt;/optionSets&gt;
                             &lt;/configuration&gt;
                         &lt;/execution&gt;
                         &lt;execution&gt;
                             &lt;id&gt;stop&lt;/id&gt;
                             &lt;phase&gt;install&lt;/phase&gt;
                             &lt;goals&gt;
                                 &lt;goal&gt;stop-server&lt;/goal&gt;
                             &lt;/goals&gt;
                         &lt;/execution&gt;
                     &lt;/executions&gt;
                &lt;/plugin&gt;
</pre>
</div></div>
<p>and a profile</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">    &lt;profiles&gt;
        &lt;profile&gt;
            &lt;id&gt;it&lt;/id&gt;
            &lt;build&gt;
                &lt;plugins&gt;
                    &lt;plugin&gt;
                        &lt;groupId&gt;org.apache.geronimo.buildsupport&lt;/groupId&gt;
                        &lt;artifactId&gt;geronimo-maven-plugin&lt;/artifactId&gt;
                    &lt;/plugin&gt;
                &lt;/plugins&gt;
            &lt;/build&gt;
        &lt;/profile&gt;
    &lt;/profiles&gt;
</pre>
</div></div></li>
</ol>


<p>Note that at the moment the -Pit doesn't actually work, you have to try to start
the server by hand</p>

<h3><a name="OSGIconversiontips-Classloadingproblems"></a>Classloading problems</h3>
<p>Frequently, you'll see build problems with attempting to load a class when starting
a configuration.  Most of the time, this is caused by a bundle resolution problem that occurs
earlier, but the information has been swallowed.  If you use the -X option on the build, the
resolution error will be given earlier in the build and you can generally figure out what's
missing from that. </p>

<p>Occasionally, the resolution error will be a very generic "Constraint violation"
without much information on what actually failed.  Turning on debug logging in Felix will
give some information, but I've found that building Felix with the following patch applied
helps diagnose the problem more quickly: </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Index: src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java
===================================================================
--- src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java	(revision 831350)
+++ src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java	(working copy)
@@ -332,8 +332,12 @@
                     }
                     <span class="code-keyword">else</span>
                     {
+                        <span class="code-object">System</span>.out.println(
+                            <span class="code-quote">"Constraint violation <span
class="code-keyword">for</span> "</span> + importer
+                            + <span class="code-quote">" detected; module can see "</span>
+                            + rp + <span class="code-quote">" and "</span> +
rpUses);
                         m_logger.log(
-                            Logger.LOG_DEBUG,
+                            Logger.LOG_ERROR,
                             <span class="code-quote">"Constraint violation <span
class="code-keyword">for</span> "</span> + importer
                             + <span class="code-quote">" detected; module can see "</span>
                             + rp + <span class="code-quote">" and "</span> +
rpUses);
@@ -705,7 +709,7 @@
         <span class="code-keyword">catch</span> (ResolveException ex)
         {
             m_logger.log(
-                Logger.LOG_DEBUG,
+                Logger.LOG_ERROR,
                 <span class="code-quote">"Constraint violation <span class="code-keyword">for</span>
"</span> + targetModule + <span class="code-quote">" detected."</span>,
                 ex);
             <span class="code-keyword">return</span> <span class="code-keyword">false</span>;
@@ -789,7 +793,7 @@
         <span class="code-keyword">catch</span> (ResolveException ex)
         {
             m_logger.log(
-                Logger.LOG_DEBUG,
+                Logger.LOG_ERROR,
                 <span class="code-quote">"Constraint violation <span class="code-keyword">for</span>
"</span> + targetModule + <span class="code-quote">" detected."</span>,
                 ex);
             <span class="code-keyword">return</span> <span class="code-keyword">false</span>;
@@ -824,7 +828,7 @@
         <span class="code-keyword">catch</span> (ResolveException ex)
         {
             m_logger.log(
-                Logger.LOG_DEBUG,
+                Logger.LOG_ERROR,
                 <span class="code-quote">"Constraint violation <span class="code-keyword">for</span>
"</span> + targetModule + <span class="code-quote">" detected."</span>,
                 ex);
             <span class="code-keyword">return</span> <span class="code-keyword">false</span>;
@@ -875,7 +879,7 @@
                     <span class="code-keyword">else</span>
                     {
                         m_logger.log(
-                            Logger.LOG_DEBUG,
+                            Logger.LOG_ERROR,
                             <span class="code-quote">"Constraint violation <span
class="code-keyword">for</span> "</span> + targetModule
                             + <span class="code-quote">" detected; module can see "</span>
                             + rp + <span class="code-quote">" and "</span> +
rpUses);
Index: src/main/java/org/apache/felix/framework/ModuleImpl.java
===================================================================
--- src/main/java/org/apache/felix/framework/ModuleImpl.java	(revision 831350)
+++ src/main/java/org/apache/felix/framework/ModuleImpl.java	(working copy)
@@ -1295,7 +1295,7 @@
 
     <span class="code-keyword">public</span> <span class="code-object">String</span>
toString()
     {
-        <span class="code-keyword">return</span> m_id;
+        <span class="code-keyword">return</span> getSymbolicName() + <span
class="code-quote">" ("</span> + m_id + <span class="code-quote">")"</span>;
     }
 
     <span class="code-keyword">private</span> <span class="code-keyword">synchronized</span>
ModuleClassLoader getClassLoader()
@@ -1590,12 +1590,12 @@
 
             <span class="code-keyword">try</span>
             {
-                dexFileClassLoadDex = dexFileClass.getMethod(<span class="code-quote">"loadDex"</span>,

+                dexFileClassLoadDex = dexFileClass.getMethod(<span class="code-quote">"loadDex"</span>,
                     <span class="code-keyword">new</span> <span class="code-object">Class</span>[]{<span
class="code-object">String</span>.class, <span class="code-object">String</span>.class,
<span class="code-object">Integer</span>.TYPE});
             }
             <span class="code-keyword">catch</span> (Exception ex)
             {
-                <span class="code-comment">// Nothing we need to <span class="code-keyword">do</span>

</span>+                <span class="code-comment">// Nothing we need to <span
class="code-keyword">do</span>
</span>             }
             dexFileClassConstructor = dexFileClass.getConstructor(
                 <span class="code-keyword">new</span> <span class="code-object">Class</span>[]
{ java.io.File.class });
@@ -1717,7 +1717,7 @@
 
                         <span class="code-keyword">if</span> (clazz == <span
class="code-keyword">null</span>)
                         {
-                            <span class="code-object">int</span> activationPolicy
= 
+                            <span class="code-object">int</span> activationPolicy
=
                                 ((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
                                 ? ((BundleImpl) getBundle()).getCurrentModule().getDeclaredActivationPolicy()
                                 : IModule.EAGER_ACTIVATION;
@@ -1873,8 +1873,8 @@
                 {
                     <span class="code-keyword">if</span> (m_dexFileClassLoadDex
!= <span class="code-keyword">null</span>)
                     {
-                        dexFile = m_dexFileClassLoadDex.invoke(<span class="code-keyword">null</span>,

-                            <span class="code-keyword">new</span> <span class="code-object">Object</span>[]{content.getFile().getAbsolutePath(),

+                        dexFile = m_dexFileClassLoadDex.invoke(<span class="code-keyword">null</span>,
+                            <span class="code-keyword">new</span> <span class="code-object">Object</span>[]{content.getFile().getAbsolutePath(),
                                 content.getFile().getAbsolutePath() + <span class="code-quote">".dex"</span>,
<span class="code-keyword">new</span> <span class="code-object">Integer</span>(0)});
                     }
                     <span class="code-keyword">else</span>

</pre>
</div></div>


<h3><a name="OSGIconversiontips-Classloadingproblems"></a>Classloading problems</h3>
<p>Frequently, you'll see build problems with attempting to load a class when starting
a configuration.  Most of the time, this is caused by a bundle resolution problem that occurs
earlier, but the information has been swallowed.  If you use the -X option on the build, the
resolution error will be given earlier in the build and you can generally figure out what's
missing from that. </p>

<p>Occasionally, the resolution error will be a very generic "Constraint violation"
without much information on what actually failed.  Turning on debug logging in Felix will
give some information, but I've found that building Felix with the following patch applied
helps diagnose the problem more quickly: </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Index: src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java
===================================================================
--- src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java	(revision 831350)
+++ src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java	(working copy)
@@ -332,8 +332,12 @@
                     }
                     <span class="code-keyword">else</span>
                     {
+                        <span class="code-object">System</span>.out.println(
+                            <span class="code-quote">"Constraint violation <span
class="code-keyword">for</span> "</span> + importer
+                            + <span class="code-quote">" detected; module can see "</span>
+                            + rp + <span class="code-quote">" and "</span> +
rpUses);
                         m_logger.log(
-                            Logger.LOG_DEBUG,
+                            Logger.LOG_ERROR,
                             <span class="code-quote">"Constraint violation <span
class="code-keyword">for</span> "</span> + importer
                             + <span class="code-quote">" detected; module can see "</span>
                             + rp + <span class="code-quote">" and "</span> +
rpUses);
@@ -705,7 +709,7 @@
         <span class="code-keyword">catch</span> (ResolveException ex)
         {
             m_logger.log(
-                Logger.LOG_DEBUG,
+                Logger.LOG_ERROR,
                 <span class="code-quote">"Constraint violation <span class="code-keyword">for</span>
"</span> + targetModule + <span class="code-quote">" detected."</span>,
                 ex);
             <span class="code-keyword">return</span> <span class="code-keyword">false</span>;
@@ -789,7 +793,7 @@
         <span class="code-keyword">catch</span> (ResolveException ex)
         {
             m_logger.log(
-                Logger.LOG_DEBUG,
+                Logger.LOG_ERROR,
                 <span class="code-quote">"Constraint violation <span class="code-keyword">for</span>
"</span> + targetModule + <span class="code-quote">" detected."</span>,
                 ex);
             <span class="code-keyword">return</span> <span class="code-keyword">false</span>;
@@ -824,7 +828,7 @@
         <span class="code-keyword">catch</span> (ResolveException ex)
         {
             m_logger.log(
-                Logger.LOG_DEBUG,
+                Logger.LOG_ERROR,
                 <span class="code-quote">"Constraint violation <span class="code-keyword">for</span>
"</span> + targetModule + <span class="code-quote">" detected."</span>,
                 ex);
             <span class="code-keyword">return</span> <span class="code-keyword">false</span>;
@@ -875,7 +879,7 @@
                     <span class="code-keyword">else</span>
                     {
                         m_logger.log(
-                            Logger.LOG_DEBUG,
+                            Logger.LOG_ERROR,
                             <span class="code-quote">"Constraint violation <span
class="code-keyword">for</span> "</span> + targetModule
                             + <span class="code-quote">" detected; module can see "</span>
                             + rp + <span class="code-quote">" and "</span> +
rpUses);
Index: src/main/java/org/apache/felix/framework/ModuleImpl.java
===================================================================
--- src/main/java/org/apache/felix/framework/ModuleImpl.java	(revision 831350)
+++ src/main/java/org/apache/felix/framework/ModuleImpl.java	(working copy)
@@ -1295,7 +1295,7 @@
 
     <span class="code-keyword">public</span> <span class="code-object">String</span>
toString()
     {
-        <span class="code-keyword">return</span> m_id;
+        <span class="code-keyword">return</span> getSymbolicName() + <span
class="code-quote">" ("</span> + m_id + <span class="code-quote">")"</span>;
     }
 
     <span class="code-keyword">private</span> <span class="code-keyword">synchronized</span>
ModuleClassLoader getClassLoader()
@@ -1590,12 +1590,12 @@
 
             <span class="code-keyword">try</span>
             {
-                dexFileClassLoadDex = dexFileClass.getMethod(<span class="code-quote">"loadDex"</span>,

+                dexFileClassLoadDex = dexFileClass.getMethod(<span class="code-quote">"loadDex"</span>,
                     <span class="code-keyword">new</span> <span class="code-object">Class</span>[]{<span
class="code-object">String</span>.class, <span class="code-object">String</span>.class,
<span class="code-object">Integer</span>.TYPE});
             }
             <span class="code-keyword">catch</span> (Exception ex)
             {
-                <span class="code-comment">// Nothing we need to <span class="code-keyword">do</span>

</span>+                <span class="code-comment">// Nothing we need to <span
class="code-keyword">do</span>
</span>             }
             dexFileClassConstructor = dexFileClass.getConstructor(
                 <span class="code-keyword">new</span> <span class="code-object">Class</span>[]
{ java.io.File.class });
@@ -1717,7 +1717,7 @@
 
                         <span class="code-keyword">if</span> (clazz == <span
class="code-keyword">null</span>)
                         {
-                            <span class="code-object">int</span> activationPolicy
= 
+                            <span class="code-object">int</span> activationPolicy
=
                                 ((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
                                 ? ((BundleImpl) getBundle()).getCurrentModule().getDeclaredActivationPolicy()
                                 : IModule.EAGER_ACTIVATION;
@@ -1873,8 +1873,8 @@
                 {
                     <span class="code-keyword">if</span> (m_dexFileClassLoadDex
!= <span class="code-keyword">null</span>)
                     {
-                        dexFile = m_dexFileClassLoadDex.invoke(<span class="code-keyword">null</span>,

-                            <span class="code-keyword">new</span> <span class="code-object">Object</span>[]{content.getFile().getAbsolutePath(),

+                        dexFile = m_dexFileClassLoadDex.invoke(<span class="code-keyword">null</span>,
+                            <span class="code-keyword">new</span> <span class="code-object">Object</span>[]{content.getFile().getAbsolutePath(),
                                 content.getFile().getAbsolutePath() + <span class="code-quote">".dex"</span>,
<span class="code-keyword">new</span> <span class="code-object">Integer</span>(0)});
                     }
                     <span class="code-keyword">else</span>

</pre>
</div></div>


<h3><a name="OSGIconversiontips-Loggingconversion"></a>Logging conversion</h3>

<p>When converting plugins make sure to avoid the following dependencies: <tt>log4j</tt>,
<tt>jcl-over-slf4j</tt>,<br/>
<tt>jul-to-slf4j</tt>, <tt>slf4j-api</tt>, or <tt>slf4j-log4j12</tt>.
Instead use <tt>pax-logging-api</tt>. This bundle exports all of these logging
API. </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">            &lt;dependency&gt;
                &lt;groupId&gt;org.ops4j.pax.logging&lt;/groupId&gt;
                &lt;artifactId&gt;pax-logging-api&lt;/artifactId&gt;     
        
            &lt;/dependency&gt;
</pre>
</div></div>

<p>The <tt>pax-logging-api</tt> together with <tt>pax-logging-service</tt>
provides a logging service in the OSGi environment that works with all commonly used logging
API.</p>
     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/GMOxDEV/OSGI+conversion+tips">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=5603340&revisedVersion=6&originalVersion=5">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/GMOxDEV/OSGI+conversion+tips?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message