On 7/1/12 9:38, Dan Gravell wrote:
Thanks Richard...

On Sun, Jul 1, 2012 at 2:15 PM, Richard S. Hall <[email protected]>wrote:

I have to imagine the simple solution for your scenario is to deploy your
client and your server (with OBR or not), then to perform a refresh
afterwards.

... but this is what I'm doing isn't it? Here's my actual code to deploy:

final Resource bundleResource =
FelixObrUtils.getLatestBundleResource(repoAdminSupplier);
Resolver resolver = repoAdminSupplier.get().resolver();
resolver.add(bundleResource);
if (resolver.resolve()) {
listener.installBundleStart();
resolver.deploy(Resolver.START);
  // null to resolve all unresolved bundles
context.getBundle(0).adapt(FrameworkWiring.class).resolveBundles(null);
listener.installBundleComplete();
} else {
  // handling code...
}

FelixObrUtils.getLatestBundleResource looks inside the RepositoryAdmin and
returns the highest versioned Resource with the symbolic name
"com.elsten.bliss.bundle". This is resolved (which should bring in the new
dependencies) and then deployed.

This code is itself running inside com.elsten.bliss.bundle.

Thanks for the info about refreshing and the BundleContext. I always
guessed that approach was a bit suspect. What is the correct way of
retrieving the FrameworkWiring without the BundleContext?

For the above to work, the "context" must be from a bundle that hasn't been updated. So, if you have three bundles: updater, client, and server. And updater is doing the above code to update server and client, then it should work.

-> richard


Dan


If we release a modified version of OBR that automatically refreshes, then
you shouldn't need to manually perform the refresh afterwards.

-> richard

  I'm using OBR, and the Client is marked as
requiring a package on Server that was updated. Therefore I expected
Server
to be updated before Client (although this assumption might be wrong). In
OBR API terms I am *only* calling deploy() on the Client BundleResource.

The other, separate, package named 'server' within the Server bundle that
contains type A was not updated and the requirement was not updated.

When one package is updated but the other isn't within a bundle I assumed
the classloader would be refreshed for the entire bundle, so affecting
both
packages, by virtue of the bundle being updated.

So I ran an experiment. In bundle "Server", I updated the exported version
of package "server". I then updated bundle "Server"'s version to ensure it
would be updated. In "Client"'s manifest I changed the version requirement
to reflect the new version of "server". I also updated "Client"'s version
(although that uses the .qualifier PDE build approach, so a regeneration
of
the build script was all that was required).

This time I get a different error message:

ERROR: Resolver: Start error - com.elsten.bliss.bundle
org.osgi.framework.**BundleException: Activator start error in
bundle com.elsten.bliss.bundle [42].
at org.apache.felix.framework.**Felix.activateBundle(Felix.**java:2027)
at org.apache.felix.framework.**Felix.startBundle(Felix.java:**1895)
at org.apache.felix.framework.**BundleImpl.start(BundleImpl.**java:944)
at org.apache.felix.framework.**BundleImpl.start(BundleImpl.**java:931)
at
org.apache.felix.**bundlerepository.impl.**ResolverImpl.deploy(**
ResolverImpl.java:630)
[...]
Caused by: java.lang.LinkageError: loader constraint violation: when
resolving method
"com.elsten.bliss.main.Main.**getLicenceStore()Lcom/elsten/**
bliss/licence/**PerFixLicenceStore;"
the class loader (instance of
org/apache/felix/framework/**BundleWiringImpl$**BundleClassLoaderJava5)
of the
current class, com/elsten/osgi/Activator, and the class loader (instance
of
org/apache/felix/framework/**BundleWiringImpl$**BundleClassLoaderJava5)
for
resolved class, com/elsten/bliss/main/Main, have different Class objects
for the type com/elsten/bliss/licence/**PerFixLicenceStore used in the
signature
at com.elsten.osgi.Activator.**start(Activator.java:40)
at
org.apache.felix.framework.**util.SecureAction.**
startActivator(SecureAction.**java:641)
at org.apache.felix.framework.**Felix.activateBundle(Felix.**java:1977)

This is a problem with a line preceeding the one that I originally had a
problem for. But again, it's for a type in a package I didn't update, but
within the bundle I did update.

Apologies for my obfuscated bundle and package naming before. I should
explain how the actual names in the output above map to what I've
described
so far:

Bundle com.elsten.bliss.bundle (nee "Client") has packages:
com.elsten.osgi [the actual name for the 'client' package. The package
containing the Activator that runs a class in com.elsten.bliss.main and
uses the result to register services]

Bundle com.elsten.bliss.platform (nee "Server") has packages:
com.elsten.bliss.main [the package containing the class that provides the
services to 'client']
com.elsten.bliss.licence [the package containing the type showing the new
problem]
com.elsten.bliss.music.policy2 [the actual name for the 'server' package]

So then I updated com.elsten.bliss.licence's version, containing bundle
version, import version, and containing bundle of the import's version. I
ran the update again. This time there were no errors! Although refresh
still failed:

java.lang.**IllegalStateException: Invalid BundleContext.
at
org.apache.felix.framework.**BundleContextImpl.**checkValidity(**
BundleContextImpl.java:514)
at
org.apache.felix.framework.**BundleContextImpl.getBundle(**
BundleContextImpl.java:173)
at com.elsten.osgi.OnlineUpdater.**updateTo(OnlineUpdater.java:**51)

This suggests the bundle did not restart. But I stopped the JVM and didn't
note whether the application was still usable, so I ran the test again,
removing felix-cache and performing the update against the same bundles.
This time I get a *different* result:

ERROR: Resolver: Start error - com.elsten.bliss.bundle
org.osgi.framework.**BundleException: Uses constraint violation. Unable
to
resolve bundle revision com.elsten.bliss.platform [11.1] because it is
exposed to package 'com.elsten.musicbrainz' from bundle revisions
com.elsten.musicbrainz [30.1] and com.elsten.musicbrainz [30.0] via two
dependency chains.

Chain 1:
    com.elsten.bliss.platform [11.1]
      import: (&(osgi.wiring.package=com.**elsten.musicbrainz)(version>=**
1.0.2))
       |
      export: osgi.wiring.package=com.**elsten.musicbrainz
    com.elsten.musicbrainz [30.1]

Chain 2:
    com.elsten.bliss.platform [11.1]
      import:
(&(osgi.wiring.package=com.**elsten.musicbrainz.model)(**version>=1.0.1))
       |
      export: osgi.wiring.package=com.**elsten.musicbrainz.model;
uses:=com.elsten.musicbrainz
      export: osgi.wiring.package=com.**elsten.musicbrainz
    com.elsten.musicbrainz [30.0]
at org.apache.felix.framework.**Felix.resolveBundleRevision(**
Felix.java:3832)
at org.apache.felix.framework.**Felix.startBundle(Felix.java:**1868)
at org.apache.felix.framework.**BundleImpl.start(BundleImpl.**java:944)
at org.apache.felix.framework.**BundleImpl.start(BundleImpl.**java:931)
at
org.apache.felix.**bundlerepository.impl.**ResolverImpl.deploy(**
ResolverImpl.java:630)

Crap. So now I am getting different errors on different invocations too.
Maybe it was a timing issue - on the re-run I probably ran the update
sooner after starting. These "Uses constraint violation"s are normally
fixed by package versioning, or so I thought, but in this case all
versions
of these bundles dictate package versions. So I don't know where to go
from
there.

I'm also beginning to think using Require-Bundle may be better for my
sanity, assuming it allows coarser grained control of versioning.

Serves me right for working on a Sunday I suppose.

Dan

On Sat, Jun 30, 2012 at 5:46 PM, Richard S. Hall <[email protected]
wrote:
  Updating the service doesn't completely get rid of its old exports, you
need to refresh it to do that. Most likely if you updated the client
first,
then it gets wired to the old export and stays that way after you update
the server. Regardless, if you want to make sure you don't have any old
"stale" versions causing you confusion, you have to do a "refresh" after
a
series of updates and uninstalls.

-> richard


On 6/30/12 12:09, Dan Gravell wrote:

  My OSGi adventure continues...
I have a bundle "Client" and bundle "Server". In Client's activator it
invokes code in Server, returning an object from Server, let's call it
server.A. A is defined in Server. Client then registers A as a service:

context.registerService(A.****class, (A) serverClass.getA(), new

Hashtable());

This works when it is first run.

If I then update Client and Server bundles, the Client Activator gets
run
again. This time I get a ClassCastException saying "server.A cannot be
cast
to server.A".

So I guess the classloaders are different for the A that is returned by
Server to the one Client sees. Given both bundles were updated at the
same
time, why is this?

I make use of package versioning, if this is important. A's package,
server, was not updated, and its version was not incremented. Was the
code
in Client using the old version of server.A?

I guess registering A as a service in Client, rather than Server, is
opposed to most sample code I see but is it the cause of the problem? If
classloaders work on a per package level then it won't help will it?

Thanks,
Dan


  ------------------------------****----------------------------**
--**---------
To unsubscribe, e-mail: 
users-unsubscribe@felix.**apac**he.org<http://apache.org>
<users-unsubscribe@**felix.apache.org<[email protected]>
For additional commands, e-mail: [email protected]




------------------------------**------------------------------**---------
To unsubscribe, e-mail: 
users-unsubscribe@felix.**apache.org<[email protected]>
For additional commands, e-mail: [email protected]





---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to