You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Stuart McCulloch <mc...@gmail.com> on 2009/06/14 18:15:56 UTC

Re: Bundle-ClassPath without "." while using maven-bundle-plugin and maven-war-plugin together

2009/6/13 Sahoo <Sa...@sun.com>

> I am using a war type project, so the packaging is governed by
> maven-war-plugin. For the OSGi meta data in the war, I am using manifest
> goal of maven-bundle-plugin in process-classes phase. Yes, I have already
> looked at the excellent examples on this use case at [1]. However, my use
> case has one difference. I don't want "." in Bundle-ClassPath. Why? Because,
> it should never be. Files at the root level of .war file is never used
> directly by class loaders in web container; WEB-INF/classes and
> WEB-INF/lib/*.jar are used instead. As soon as I remove the "." from
> Bundle-ClassPath settings, bundle plugin is confused. I don't know why  "."
> is necessary for bundle plugin to generate meta data? My guess is without
> it, it does not find any classes in the target dir?


if you want to use the bundleplugin to build the WAR file then you need
to use Embed-Dependency (or the raw Bnd Include-Resouce instruction)
so that the classes end up in the right location(s) inside the WAR bundle
- then when Bnd analyzes the Bundle-ClassPath it will find the classes

if you want to use the bundleplugin to generate the manifest, and you
want a Bundle-ClassPath without '.' then I suspect you'll need to have
the WAR file laid out under "target/classes" (or somewhere else that
you could add to the Bnd classpath by using its -classpath setting)

otherwise I suspect the reason you're getting unexpected results is
because Bnd is looking for the given structure, but the classpath it's
been given is just the basic compilation path.

also the key difference between the bundle and manifest goals is that
the manifest goal doesn't actually generate the bundle, so there may
still be some inconsistencies due to this (and some may be impossible
to solve without actually generating the bundle - in which case you'd
might as well use the bundle goal and then extract the manifest...)

feel free to attach your testcase to a JIRA issue (make sure it can be
built without missing dependencies, etc.) ... unfortunately I can't say
for sure when I'll be able to get round to actively look at it

So, as a work around, I am having to specify Bundle-ClassPath using
> maven-war-plugin. Here is how plugin section of my pom.xml finally looks
> like:
>
>       <plugins>
>           <plugin>
>               <artifactId>maven-war-plugin</artifactId>
>               <groupId>org.apache.maven.plugins</groupId>
>               <version>2.0</version>
>               <configuration>
>                   <archive>
>                       <!-- add the generated manifest to the war -->
>
> <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
>                       <!-- For some reason, adding Bundle-ClassPath in
> maven-bundle-plugin
>                       without "." confuses that plugin and it generates
> wrong Import-Package, etc.
>                       Need to investigate further.
>                       -->
>                       <manifestEntries>
>
> <Bundle-ClassPath>WEB-INF/classes/</Bundle-ClassPath>
>                       </manifestEntries>
>                   </archive>
>               </configuration>
>           </plugin>
>           <plugin>
>               <groupId>org.apache.felix</groupId>
>               <artifactId>maven-bundle-plugin</artifactId>
>               <version>2.0.0</version>
>               <configuration>
>                   <supportedProjectTypes>
>                       <supportedProjectType>jar</supportedProjectType>
>                       <supportedProjectType>bundle</supportedProjectType>
>                       <supportedProjectType>war</supportedProjectType>
>                   </supportedProjectTypes>
>                   <instructions>
>
> <Bundle-Activator>sahoo.hybridapp.example1.impl.Activator</Bundle-Activator>
>
> <Export-Package>sahoo.hybridapp.example1</Export-Package>
>                       <Web-ContextPath>/hybrid1</Web-ContextPath>
>                       <!-- Specifying Bundle-ClassPath without "." confuses
> bundle plugin,
>                              as there are no classes in
> target/WEB-INF/classes/ and hence it
>                              can't do any processing. So, leave it
> unspecified and generate it
>                              during war packaging.
>                       <Bundle-ClassPath>WEB-INF/classes/</Bundle-ClassPath>
>                       -->
>                   </instructions>
>               </configuration>
>               <executions>
>                   <execution>
>                       <id>bundle-manifest</id>
>                       <phase>process-classes</phase>
>                       <goals>
>                           <goal>manifest</goal>
>                       </goals>
>                   </execution>
>               </executions>
>           </plugin>
>       </plugins>
>
> Is there any better way to handle this? Right now it is OK as I have only
> WEB-INF/classes as classpath entry, but when I have jars in WEB-INF/lib, it
> becomes a maintenance issue.
>
> Thanks,
> Sahoo
>
> [1]
> http://wiki.ops4j.org/display/ops4j/Getting+the+benefits+of+maven-bundle-plugin+in+other+project+types
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>


-- 
Cheers, Stuart

Re: Bundle-ClassPath without "." while using maven-bundle-plugin and maven-war-plugin together

Posted by Sahoo <Sa...@Sun.COM>.
Stuart McCulloch wrote:
> feel free to attach your testcase to a JIRA issue (make sure it can be
> built without missing dependencies, etc.) ... unfortunately I can't say
> for sure when I'll be able to get round to actively look at it
>   
Filed https://issues.apache.org/jira/browse/FELIX-1571.

Thanks,
Sahoo

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: Bundle-ClassPath without "." while using maven-bundle-plugin and maven-war-plugin together

Posted by Sahoo <Sa...@Sun.COM>.
Stuart McCulloch wrote:
> 2009/6/13 Sahoo <Sa...@sun.com>
>
>   
>> I am using a war type project, so the packaging is governed by
>> maven-war-plugin. For the OSGi meta data in the war, I am using manifest
>> goal of maven-bundle-plugin in process-classes phase. Yes, I have already
>> looked at the excellent examples on this use case at [1]. However, my use
>> case has one difference. I don't want "." in Bundle-ClassPath. Why? Because,
>> it should never be. Files at the root level of .war file is never used
>> directly by class loaders in web container; WEB-INF/classes and
>> WEB-INF/lib/*.jar are used instead. As soon as I remove the "." from
>> Bundle-ClassPath settings, bundle plugin is confused. I don't know why  "."
>> is necessary for bundle plugin to generate meta data? My guess is without
>> it, it does not find any classes in the target dir?
>>     
>
>
> if you want to use the bundleplugin to build the WAR file then you need
> to use Embed-Dependency (or the raw Bnd Include-Resouce instruction)
> so that the classes end up in the right location(s) inside the WAR bundle
> - then when Bnd analyzes the Bundle-ClassPath it will find the classes
>   
I will explore this option, but let's focus on using war plugin to do 
the packaging and bundle plugin to generate the manifest.
> if you want to use the bundleplugin to generate the manifest, and you
> want a Bundle-ClassPath without '.' then I suspect you'll need to have
> the WAR file laid out under "target/classes" (or somewhere else that
> you could add to the Bnd classpath by using its -classpath setting)
>   
In fact, war plugin already creates an exploded directory called 
target/${finalName}/ with the war content in it. I suspect it is created 
after bundle is run, so bundle plugin can't see the contents even if I 
appropriate set <_classpath/>.

Thanks,
Sahoo

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: What is the correct service import behavior?

Posted by Todor Boev <t....@prosyst.bg>.
> nope - peaberry doesn't hold any locks during the actual service call, it
> only
> has a small amount of synchronization to properly manage internal records
> when setting up and tearing down a service call
> 
> 

Yup. I figured that would be the case after Richard's replay. Now the lock 
holding mode does not make much sense to me either :)

Todor

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: What is the correct service import behavior?

Posted by Stuart McCulloch <mc...@gmail.com>.
2009/6/15 Todor Boev <t....@prosyst.bg>

> Hello,
> Seems I have been chewing on the service dynamics issue forever. Just as I
> though I got a workable concept about tracking and releasing services I
> stumble
> on a contradicting concept. The problem is this:
>
> According to my understanding it is not acceptable importer behavior to
> ever
> call service objects that are unregistered. Achieving this requires the
> service
> to be tracked and every piece of code that calls the service be
> synchronized
> with the tracking code. I'll name this the "dedicated lock approach":
>
> private Object lock;
> private Hello service;
>
> void set(Hello service) {
>  synchronized (lock) {
>    this.service = service;
>  }
> }
>
> Hello get() {
>  synchronized (lock) {
>    if (service == null) {
>      throw new ServiceUnavailableException();
>    }
>    return service;
>  }
> }
>
> void usefulMethod() {
>  synchronized (lock) {
>    get().greet("World");
>  }
> }
>
> Some say we should never call out from the bundle while holding a lock but
> I
> think we are safe if we use a dedicated private lock for every tracked
> service.
>  In any case I can't think of any other way to be safe at all times. Lately
> however I have been encountering the "local-cache" approach, which seems to
> state we don't need to be that paranoid. E.g.
>
> void usefulMethod() {
>  Hello service = get();
>
>  /* At this spot right here the service can go down! */
>
>  service.greet("World");
> }
>
> Here we risk calling a service in an undetermined state. Do we expect every
> exporter to invalidate his objects to keep us safe? E.g. the exporter must
> keep
> a "closed" flag around, mark the service as invalid in a thread-safe
> manner, and
> start tossing exceptions at callers from that point on.
>
> iPojo follows the local cache approach - right Richard?
> Peaberry follows the dedicated lock approach - right Stuart?
>

nope - peaberry doesn't hold any locks during the actual service call, it
only
has a small amount of synchronization to properly manage internal records
when setting up and tearing down a service call


> I'd be grateful if you help me compare these import modes. That is if I got
> it
> right who uses what :)
>
> Cheers,
> Todor
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>


-- 
Cheers, Stuart

Re: What is the correct service import behavior?

Posted by Stuart McCulloch <mc...@gmail.com>.
2009/6/15 Todor Boev <t....@prosyst.bg>

> Todor Boev wrote:
> > Richard S. Hall wrote:
> >> Yes. iPOJO is of the philosophy that service departures will likely lead
> >> to errors, so you are better off being prepared to catch them and fail
> >> gracefully, sort of like errors in distributed computing. Even if you
> >> hold a dedicated lock, there is no guarantee that calling a method on
> >> the service object won't throw an exception. Locks don't stop the
> >> service from going away (think bluetooth device), in some cases if it
> >> goes away it is gone, period.
> >>
>
> Ah..I get it! You mean we should not bother to block the unexport of the
> service
> when the framework calls into our ServiceListener because that won't keep
> the
> service functional until our last calls to it return. Come to think of a
> service
> can throw an exception due to a missing transitive dependency anyway. Seems
> I am
> still not completely free from that "safe" mentality :P
>

exactly!  there's not much point in artificially keeping a bundle from
unregistering
a service because in the case of a hardware problem if it's gone, it's
really gone.

Seems in the end we should count on the service exporter to toss exceptions
> at
> us rather than do random nastiness out of a partially destroyed service.
>

yes, at least in Java we have some added safety above C because any objects
you have strong references to will be kept, and not junked - however this is
no
guarantee that the contents are still valid, or external resources still
exist.

btw, one major design point in peaberry was accurately tracking who's using
a
service - this means that a bundle that's registered a service could
unregister it
then wait for "Bundle.getUsingBundles()" to return an empty list (probably
also
have a timeout in case a call takes to long) before freeing its resources

unregistering the service first means we shouldn't pick up any more callers,
so
we just have to wait for the currently active callers to complete then
gracefully
finish shutting down the service

of course you have to be careful that a reference to the service hasn't
escaped,
but that's a good reason (imho) why you should use a framework like peaberry
:)

Todor
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>

-- 
Cheers, Stuart

Re: What is the correct service import behavior?

Posted by Todor Boev <t....@prosyst.bg>.
Todor Boev wrote:
> Richard S. Hall wrote:
>> Yes. iPOJO is of the philosophy that service departures will likely lead
>> to errors, so you are better off being prepared to catch them and fail
>> gracefully, sort of like errors in distributed computing. Even if you
>> hold a dedicated lock, there is no guarantee that calling a method on
>> the service object won't throw an exception. Locks don't stop the
>> service from going away (think bluetooth device), in some cases if it
>> goes away it is gone, period.
>>

Ah..I get it! You mean we should not bother to block the unexport of the service
when the framework calls into our ServiceListener because that won't keep the
service functional until our last calls to it return. Come to think of a service
can throw an exception due to a missing transitive dependency anyway. Seems I am
still not completely free from that "safe" mentality :P

Seems in the end we should count on the service exporter to toss exceptions at
us rather than do random nastiness out of a partially destroyed service.

Todor

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: What is the correct service import behavior?

Posted by Todor Boev <t....@prosyst.bg>.
Richard S. Hall wrote:
> 
> Yes. iPOJO is of the philosophy that service departures will likely lead
> to errors, so you are better off being prepared to catch them and fail
> gracefully, sort of like errors in distributed computing. Even if you
> hold a dedicated lock, there is no guarantee that calling a method on
> the service object won't throw an exception. Locks don't stop the
> service from going away (think bluetooth device), in some cases if it
> goes away it is gone, period.
> 

I completely agree. This is all about "crashing safely", not trying to avoid
crashes with synchronization. Crashing safely means we always get an exception
when trying to access a missing service. If we allow some final calls to an
unregistered service object we risk getting random return values and other
behavior that can corrupt the importing bundle. Here the question is if we
should count on the exporter to place extra invalidation code in his service
object so it consistently throws exceptions at late retainers? Or should we take
matters in our own hands and guarantee a ServiceUnavailableException will always
be thrown from our own internal tracking code?

Todor

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: What is the correct service import behavior?

Posted by "Richard S. Hall" <he...@ungoverned.org>.
On 6/14/09 5:08 PM, Todor Boev wrote:
> Some say we should never call out from the bundle while holding a lock but I
> think we are safe if we use a dedicated private lock for every tracked service.
>   In any case I can't think of any other way to be safe at all times. Lately
> however I have been encountering the "local-cache" approach, which seems to
> state we don't need to be that paranoid. E.g.
>
> void usefulMethod() {
>    Hello service = get();
>
>    /* At this spot right here the service can go down! */
>
>    service.greet("World");
> }
>
> Here we risk calling a service in an undetermined state. Do we expect every
> exporter to invalidate his objects to keep us safe? E.g. the exporter must keep
> a "closed" flag around, mark the service as invalid in a thread-safe manner, and
> start tossing exceptions at callers from that point on.
>
> iPojo follows the local cache approach - right Richard?
>    

Yes. iPOJO is of the philosophy that service departures will likely lead 
to errors, so you are better off being prepared to catch them and fail 
gracefully, sort of like errors in distributed computing. Even if you 
hold a dedicated lock, there is no guarantee that calling a method on 
the service object won't throw an exception. Locks don't stop the 
service from going away (think bluetooth device), in some cases if it 
goes away it is gone, period.

Given that you have to deal with this case anyway, you might as well 
just treat all services the same way rather than trying to figure which 
is which case. This will become even more complicated as people start 
using distributed services from R4.2.

But depending on your application and what control you have over 
everything, then either approach is fine.

-> richard

> Peaberry follows the dedicated lock approach - right Stuart?
>
> I'd be grateful if you help me compare these import modes. That is if I got it
> right who uses what :)
>
> Cheers,
> Todor
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>    

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


What is the correct service import behavior?

Posted by Todor Boev <t....@prosyst.bg>.
Hello,
Seems I have been chewing on the service dynamics issue forever. Just as I
though I got a workable concept about tracking and releasing services I stumble
on a contradicting concept. The problem is this:

According to my understanding it is not acceptable importer behavior to ever
call service objects that are unregistered. Achieving this requires the service
to be tracked and every piece of code that calls the service be synchronized
with the tracking code. I'll name this the "dedicated lock approach":

private Object lock;
private Hello service;

void set(Hello service) {
  synchronized (lock) {
    this.service = service;
  }
}

Hello get() {
  synchronized (lock) {
    if (service == null) {
      throw new ServiceUnavailableException();
    }
    return service;
  }
}

void usefulMethod() {
  synchronized (lock) {
    get().greet("World");
  }
}

Some say we should never call out from the bundle while holding a lock but I
think we are safe if we use a dedicated private lock for every tracked service.
 In any case I can't think of any other way to be safe at all times. Lately
however I have been encountering the "local-cache" approach, which seems to
state we don't need to be that paranoid. E.g.

void usefulMethod() {
  Hello service = get();

  /* At this spot right here the service can go down! */

  service.greet("World");
}

Here we risk calling a service in an undetermined state. Do we expect every
exporter to invalidate his objects to keep us safe? E.g. the exporter must keep
a "closed" flag around, mark the service as invalid in a thread-safe manner, and
start tossing exceptions at callers from that point on.

iPojo follows the local cache approach - right Richard?
Peaberry follows the dedicated lock approach - right Stuart?

I'd be grateful if you help me compare these import modes. That is if I got it
right who uses what :)

Cheers,
Todor

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org