felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dan Gravell <elstensoftw...@googlemail.com>
Subject Re: Help me understand ClassCastException after update
Date Sun, 01 Jul 2012 12:17:25 GMT
One further question on this. You said "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". 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 <heavy@ungoverned.org>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.**apache.org<users-unsubscribe@felix.apache.org>
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message