On 4/17/10 14:31, Yair Ogen wrote:
Well, htis might be it.
CompB imports a class from CompA.
So, what you are saying there is no way for compB to always use the class
from CompA, when the flow is:
CompA --> CompB --> CompC.
Correct?
Yes, if instances from CompA flow through CompB to CompC then they must
all agree on the same version of CompA.
This issue may be because I use concrete files to test my case. In real life
the dependency will be to an interface in CompA. the difference between the
version used by CompB and CompC will be only the implementation injected
using Spring.
I hope to fine that B works with it's own "known" implementation version
even when invoked from C.
Well, technically it is possible, but it still depends. At a minimum,
CompB and CompC will have to have the interface type in common,
otherwise it still won't work.
Assume we have some interface IFoo coming from BundleZ.
Then assume we have FooImpl1 by BundleA and FooImpl2 by BundleB. Both of
these bundles import IFoo from BundleZ.
Now I can have client BundleC that imports from BundleZ. This will works
with either implementation of IFoo because they all share a common type:
IFoo.
Just keep in mind your original question above...if the types flow
through a bundle to client bundle bundles, then they must agree on the
same version of the type. If a type does not flow through a bundle, then
its clients are not constrained by the type.
-> richard
I'll check it out next week.
Please advise if my above logic has a flaw.
On Thu, Apr 15, 2010 at 7:49 PM, Richard S. Hall<he...@ungoverned.org>wrote:
On 4/15/10 12:39, Richard S. Hall wrote:
On 4/15/10 10:08, Yair Ogen wrote:
I am not following. I always want CompB to use a fixed version of CompA
regardless of the calling API code.
Is this possible? The direct dependency between CompC and CompA (newer
version) is a real situation.
Apparently, I am not explaining this in an understandable way, so maybe
someone else can jump in and give it a try.
The main issue has nothing to do with the dependencies of CompC->CompA or
CompB->CompA...in isolation, CompC and CompB can have dependencies on any
version of CompA they wish independently.
The only issue is the dependency of CompC->CompB. This requires that the
class spaces of the two bundles intersect via some common types. If those
common types come from CompA, then you have a problem since CompC and CompB
do not use a common version of CompA. If they do not include types from
CompA, then it will work.
In your case, since you are getting a "uses" constraint violation, it
likely means your CompB component exposes CompA types to its importers,
which means CompC can't use it. See the example I created before, does the
exported package from CompB accept any CompA types as parameters or return
any of those types from methods? If so, then CompC can't use it, since they
don't agree on a common set of CompA types.
To try to illustrate a working scenario, since that might be more helpful,
assume CompB exports a package containing only a class like:
public class CompB {
public String getName();
public CompB getChildComponent();
}
Since none of these types come from CompA 1.0, then CompC could import this
package, because the two versions of CompA would not conflict. Where as
something like this would not work:
public class CompB {
public String getName();
public CompA getChildComponent();
}
So, if any of the classes in the package exported by CompB (and imported by
CompC) publicly expose a type from CompA, then you have an issue since all
importers must use the same version of the type.
-> richard
-> richard
Please advise.
On Thu, Apr 15, 2010 at 4:46 PM, Richard S. Hall<he...@ungoverned.org
wrote:
On 4/15/10 9:17, Yair Ogen wrote:
Thank you very much and yes this is exactly what I wanted to achieve, I
know
regular Java does not allow this, however I thought that OSGi special
ClassLoader model resolves this issue.
I think this is a real life scenario. for example, assume based on
my previously described Component Graph that the logic behind the
scenes
is
that CompB was tested with CompA a long time ago. Comp C uses Comp B
but
also uses new version of CompA since it is a newer component.
It is a real requirement for me (I think this is common to all?) that
the
system engineers do not allow me to have B use the new CompA since this
combination was never tested. They do not want to have full regressions
tests either.
So, the route CompC --> CompA should use newer version, but the route
CompC
--> CompB --> CompA should use the older version.
So, I need to tell them this is not possible?
To be clear, if CompC somehow gets objects from CompB that are
instances
from classes from CompA, then it will not work. This is because CompC is
expecting the CompA instances to be 1.0.1, but the instances that CompB
returns are 1.0.0. A given class can only see one version of a type at a
time.
However, if CompB only uses class from CompA internally and never
exposes
them to CompC, then it is possible for both CompB and CompC to use
different
versions of that type.
There is a slight variation where CompB might expose CompA types, but
CompC
doesn't actually ever use those types from CompB. In this case, you
could
technically cheat and modify your CompB bundle metadata so it doesn't
report
the "uses" constraints. But I wouldn't recommend this since it would be
really fragile and would likely blow up in other situations where you
reuse
CompB.
-> richard
Regards,
Yair
On Thu, Apr 15, 2010 at 4:03 PM, Richard S. Hall<he...@ungoverned.org
wrote:
On 4/15/10 2:17, Yair Ogen wrote:
Right. this was another problem.
now A both verrsion and B work ok.
Problem in C:
org.osgi.framework.BundleException: The bundle could not be resolved.
Reason: Package uses conflict: Import-Package: com.something.b.main;
version="0.0.0"
Is this due to conflict between the imported dependency from to Be
and
the
one imported directly from C?
Is this situation supposed to be supported? I mean C using one
version
of
and using B that uses another version of A? How can I accomplish this
goal?
As I mentioned in my original response, it is supported assuming B
doesn't
expose A to C...it sounds like com.something.b.main exposes A v1 to C
who
is
only allowed to see A v1.0.1.
For example, assume B has a class like:
public interface com.something.b.main.Foo {
com.something.classes.Bar getBar();
}
Assuming com.something.classes.Bar comes from bundle A, then bundle C
will
not be allowed to use com.something.b.main, because it would cause it
to
see
a different version of the package than what it is allowed to see. If
this
is specifically what you are trying to achieve, then you can't do this
with
Java at all. A given class can only see one version of another class
at a
time...otherwise you get class cast exceptions.
-> richard
Any help appreciated.
Thanks,
Yair
On Wed, Apr 14, 2010 at 10:38 PM, Richard S. Hall<
he...@ungoverned.org
wrote:
On 4/14/10 14:59, Yair Ogen wrote:
Added the suggested Export-Package as well as Private-Package for
the
activator.
install fails now on:
org.codehaus.classworlds.NoSuchRealmException: plexus.core
at
org.codehaus.classworlds.ClassWorld.getRealm(ClassWorld.java:128)
at
org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:434)
at
org.codehaus.classworlds.Launcher.main(Launcher.java:375)
This sounds specific to the scenario you are trying to implement.
Not
sure,
I have no idea what Class Worlds is...
-> richard
Yair
On Wed, Apr 14, 2010 at 8:42 PM, Richard S. Hall<
he...@ungoverned.org
wrote:
To include packages without exporting them, you should use
Private-Package.
For example, you shouldn't export your activator package.
Is sounds like you want something like this:
CompA v1
Export-Package: com.something.classes; version=1.0.0
CompA v1.0.1
Export-Package: com.something.classes; version=1.0.1
CompB
Import-Package: com.something.classes; version="[1.0.0, 1.0.0]"
Export-Package: com.something.b.main
Private-Package: com.something.activator.b
CompC
Import-Package: com.something.classes; version="[1.0.1, 1.0.1]",
com.something.b.main
Private-Package: com.something.activator.c
-> richard
Regards,
Yair
On Wed, Apr 14, 2010 at 4:40 PM, Richard S. Hall<
he...@ungoverned.org
wrote:
On 4/14/10 9:19, Christopher Brind wrote:
Hi Richard,
Would you agree that a good rule of thumb (subject to specific
circumstance
of course) is that bundles should only import packages OR
export
packages,
but not both?
Well, as long as you extend that with, ..."and package API
separately
from
the implementation."
Then, yes, that'd be a good rule of thumb for the average case,
since
it
would result in the fewest issues overall at the expense of
creating
more
bundles to manage.
-> richard
Cheers,
Chris
On 14 April 2010 14:13, Richard S. Hall<he...@ungoverned.org>
wrote:
Technically, what you want to do is possible assuming that
CompB
doesn't
expose CompA v1 to CompC. From the sounds of it, you've
packaged
your
bundles incorrectly. Don't embed the Person package into your
bundles,
package them as separate bundles and them use Import-Package
in
the
client
bundles to access them. You might want to start with some
introductory
OSGi
tutorials to understand the basics.
-> richard
On 4/14/10 6:53, Yair Ogen wrote:
Hi,
I am a newbie. I've created dummy projects to test this out.
What I am trying to achieve is as follows:
CompA version 1.0.0 defines class Person that has 2
properties:
name,
lastName
CompA version 1.0.1 defines class Person that has 2
properties:
name,
myLastName
CompB version 1.0.0 calls API on person compiled with CompA
version
1.0.0.
CompC version 1.0.0 calls API on person compiled with CompA
version
1.0.1.
Additionally calls API on CompB.
So, CompA, both versions, are not dependent on anything.
CompB is dependant on CompA version *1.0.0*.
CompC is dependant on CompB version 1.0.0 and CompA version
*1.0.1*.
When I read about OSGi I thought that I should be able to see
that
the
API
used directly between C and A will activate Person from A
version
1.0.1,
but
the API called from C to B to A will activate the person from
A
version
1.0.0.
This is not the case. Pure B API activate the "right" person.
Person used from C (regardless of the origin - API in C or
API
in
B)
activates the same Person - 1.0.1.
When investigating I saw that the person class was embedded
in B
and
in
C,
so of course they can only work with one class at a time.
My question is - isn't there a non embedded approach, where
both
A
versions
jars are in the classpath and the container will pick up the
correct
dependency on the fly?
This must work for me, because this is the heart of what I
need
from
OSGi
-
Manage multiple version of the same artifacts in a single
jvm...
Regards,
Yair
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org