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 13:38:49 GMT
Thanks Richard...

On Sun, Jul 1, 2012 at 2:15 PM, Richard S. Hall <heavy@ungoverned.org>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?

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 <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.**apac**he.org<http://apache.org>
>>> <users-unsubscribe@**felix.apache.org<users-unsubscribe@felix.apache.org>
>>> >
>>>
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>>
>
>
> ------------------------------**------------------------------**---------
> 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