[
https://issues.apache.org/jira/browse/FELIX-5285?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Emmanuel J updated FELIX-5285:
------------------------------
Description:
iPojo runtime & api: 1.12.1
Felix framework: 4.2.1
This issue is similar to https://issues.apache.org/jira/browse/FELIX-2093
This interface exist in v1.0 of an api and is exported by the system bundle
(felix) A
{code}package com.data.service
public interface DataService
{
public void search(String condition);
}{code}
A bundle, B, imports com.data.service;version=1.0:
{code}@Requires(optional = true)
private DataServiceImpl dataServiceImpl;{code}
where DataServiceImpl only implements the interface
All is working well at this point.
Then, the api evolves with a new method:
{code}package com.data.service
import com.data.service.conditions.Condition;
public interface DataService
{
public void search(String condition);
public void search(Condition condition);
}{code}
still exported by system bundle A but now as version 1.1
The bundle B is not recompiled against this new version and does not import the
new package com.data.service.conditions
Now, when bundle B runs with v1.1 of the api, the requires of DataServiceImpl
is failing in Dependency.createNullableObject()
(http://felix.apache.org/ipojo/api/1.12.1/src-html/org/apache/felix/ipojo/handlers/dependency/Dependency.html
line 433) when creating the proxy: the proxy class is created w/o issue but
when an instance of this proxy class is done, there is a Class.forName() done
that fails to load the class Condition because it is not imported
Since the class Condition is already available and allows to create the proxy
class, it would make sense to use it instead of trying to load it thru the
bundle classloader
To achieve this, the methods of the specification could be browsed, for each
parameters and return types the classloader could be collected and given to the
NullableClassLoader. All classloaders could be asked to load the class. At some
point, the classloader of Condition would be queried and would return the class
I don't know if this is breaking OSGi principles but I think it can fix this
issue
NB: I also tried to export the new api with uses directive:
com.data.service;version=1.1;uses:="com.data.service.conditions"
with no result. If I understand correctly uses directive is not supposed to add
implicit package import to bundle B, but are only used by the OSGi framework to
help it on the wiring process
Here's the cause exception thrown in java.lang.IllegalStateException: Cannot
create the Nullable object, a referenced class cannot be loaded:
{code}java.lang.NoClassDefFoundError: *** Class
'com.data.service.conditions.Condition' was not found because bundle B [5] does
not import 'com.data.service.conditions' even though bundle
org.apache.felix.framework [0] does export it. Additionally, the class is also
available from the system class loader. There are two fixes: 1) Add an import
for 'com.data.service.conditions' to bundle B [5]; imports are necessary for
each class directly touched by bundle code or indirectly touched, such as super
classes if their methods are used. 2) Add package 'com.data.service.conditions'
to the 'org.osgi.framework.bootdelegation' property; a library or VM bug can
cause classes to be loaded by the wrong class loader. The first approach is
preferable for preserving modularity. ***{code}
And the stack trace of the loadClass that fails:
{code}"[iPOJO] pool-1-thread-1@4605" daemon prio=5 tid=0x21 nid=NA runnable
java.lang.Thread.State: RUNNABLE
at
org.apache.felix.ipojo.handlers.dependency.Dependency$NullableClassLoader.loadClass(Dependency.java:1072)
at java.lang.Class.forName0(Class.java:-1)
at java.lang.Class.forName(Class.java:264)
at com.sun.proxy.$Proxy154.<clinit>(Unknown Source:-1)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(NativeConstructorAccessorImpl.java:-1)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:739)
at
org.apache.felix.ipojo.handlers.dependency.Dependency.createNullableObject(Dependency.java:434)
at
org.apache.felix.ipojo.handlers.dependency.Dependency.start(Dependency.java:457)
at
org.apache.felix.ipojo.handlers.dependency.DependencyHandler.__M_start(DependencyHandler.java:496)
at
org.apache.felix.ipojo.handlers.dependency.DependencyHandler.start(DependencyHandler.java:-1)
at
org.apache.felix.ipojo.HandlerManager.start(HandlerManager.java:136)
at
org.apache.felix.ipojo.InstanceManager.start(InstanceManager.java:421)
at
org.apache.felix.ipojo.ComponentFactory.createInstance(ComponentFactory.java:179)
at
org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:319)
- locked <0x2a3b> (a org.apache.felix.ipojo.ComponentFactory)
at
org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:240)
at
org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:312)
at
org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:306)
at
org.apache.felix.ipojo.extender.internal.queue.JobInfoCallable.call(JobInfoCallable.java:114)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745){code}
was:
iPojo runtime & api: 1.12.1
Felix framework: 4.2.1
This issue is similar to https://issues.apache.org/jira/browse/FELIX-2093
This interface exist in v1.0 of an api and is exported by the system bundle
(felix) A
{code}package com.data.service
public interface DataService
{
public void search(String condition);
}{code}
A bundle, B, imports com.data.service;version=1.0:
{code}@Requires(optional = true)
private DataServiceImpl dataServiceImpl;{code}
where DataServiceImpl only implements the interface
All is working well at this point.
Then, the api evolves with a new method:
{code}package com.data.service
import com.data.service.conditions.Condition;
public interface DataService
{
public void search(String condition);
public void search(Condition condition);
}{code}
still exported by system bundle A but now as version 1.1
The bundle B is not recompiled against this new version and does not import the
new package com.data.service.conditions
Now, when bundle B runs with v1.1 of the api, the requires of DataServiceImpl
is failing in Dependency.createNullableObject()
(http://felix.apache.org/ipojo/api/1.12.1/src-html/org/apache/felix/ipojo/handlers/dependency/Dependency.html
line 433) when creating the proxy: the proxy class is created w/o issue but
when an instance of this proxy class is done, there is a Class.forName() done
that fails to load the class Condition because it is not imported
Since the class Condition is already available and allows to create the proxy
class, it would make sense to use it instead of trying to load it thru the
bundle classloader
To achieve this, the methods of the specification could be browsed, for each
parameters and return types the classloader could be collected and given to the
NullableClassLoader. All classloaders could be asked to load the class. At some
point, the classloader of Condition would be queried and would return the class
I don't know if this is breaking OSGi principles but I think it can fix this
issue
NB: I also tried to export the new api with uses directive:
com.data.service;version=1.1;uses:="com.data.service.conditions"
with no result. If I understand correctly uses directive is not supposed to add
implicit package import to bundle B, but are only used by the OSGi framework to
help it on the wiring process
Here's the cause exception thrown in java.lang.IllegalStateException: Cannot
create the Nullable object, a referenced class cannot be loaded:
{noformat}java.lang.NoClassDefFoundError: *** Class
'com.data.service.conditions.Condition' was not found because bundle B [5] does
not import 'com.data.service.conditions' even though bundle
org.apache.felix.framework [0] does export it. Additionally, the class is also
available from the system class loader. There are two fixes: 1) Add an import
for 'com.data.service.conditions' to bundle B [5]; imports are necessary for
each class directly touched by bundle code or indirectly touched, such as super
classes if their methods are used. 2) Add package 'com.data.service.conditions'
to the 'org.osgi.framework.bootdelegation' property; a library or VM bug can
cause classes to be loaded by the wrong class loader. The first approach is
preferable for preserving modularity. ***{noformat}
> iPojo does not delegate to the right classloader for Nullable Proxy
> instantiation
> ---------------------------------------------------------------------------------
>
> Key: FELIX-5285
> URL: https://issues.apache.org/jira/browse/FELIX-5285
> Project: Felix
> Issue Type: Bug
> Components: iPOJO
> Reporter: Emmanuel J
>
> iPojo runtime & api: 1.12.1
> Felix framework: 4.2.1
> This issue is similar to https://issues.apache.org/jira/browse/FELIX-2093
> This interface exist in v1.0 of an api and is exported by the system bundle
> (felix) A
> {code}package com.data.service
> public interface DataService
> {
> public void search(String condition);
> }{code}
> A bundle, B, imports com.data.service;version=1.0:
> {code}@Requires(optional = true)
> private DataServiceImpl dataServiceImpl;{code}
> where DataServiceImpl only implements the interface
> All is working well at this point.
> Then, the api evolves with a new method:
> {code}package com.data.service
> import com.data.service.conditions.Condition;
> public interface DataService
> {
> public void search(String condition);
> public void search(Condition condition);
> }{code}
> still exported by system bundle A but now as version 1.1
> The bundle B is not recompiled against this new version and does not import
> the new package com.data.service.conditions
> Now, when bundle B runs with v1.1 of the api, the requires of DataServiceImpl
> is failing in Dependency.createNullableObject()
> (http://felix.apache.org/ipojo/api/1.12.1/src-html/org/apache/felix/ipojo/handlers/dependency/Dependency.html
> line 433) when creating the proxy: the proxy class is created w/o issue but
> when an instance of this proxy class is done, there is a Class.forName() done
> that fails to load the class Condition because it is not imported
> Since the class Condition is already available and allows to create the proxy
> class, it would make sense to use it instead of trying to load it thru the
> bundle classloader
> To achieve this, the methods of the specification could be browsed, for each
> parameters and return types the classloader could be collected and given to
> the NullableClassLoader. All classloaders could be asked to load the class.
> At some point, the classloader of Condition would be queried and would return
> the class
> I don't know if this is breaking OSGi principles but I think it can fix this
> issue
> NB: I also tried to export the new api with uses directive:
> com.data.service;version=1.1;uses:="com.data.service.conditions"
> with no result. If I understand correctly uses directive is not supposed to
> add implicit package import to bundle B, but are only used by the OSGi
> framework to help it on the wiring process
> Here's the cause exception thrown in java.lang.IllegalStateException: Cannot
> create the Nullable object, a referenced class cannot be loaded:
> {code}java.lang.NoClassDefFoundError: *** Class
> 'com.data.service.conditions.Condition' was not found because bundle B [5]
> does not import 'com.data.service.conditions' even though bundle
> org.apache.felix.framework [0] does export it. Additionally, the class is
> also available from the system class loader. There are two fixes: 1) Add an
> import for 'com.data.service.conditions' to bundle B [5]; imports are
> necessary for each class directly touched by bundle code or indirectly
> touched, such as super classes if their methods are used. 2) Add package
> 'com.data.service.conditions' to the 'org.osgi.framework.bootdelegation'
> property; a library or VM bug can cause classes to be loaded by the wrong
> class loader. The first approach is preferable for preserving modularity.
> ***{code}
> And the stack trace of the loadClass that fails:
> {code}"[iPOJO] pool-1-thread-1@4605" daemon prio=5 tid=0x21 nid=NA runnable
> java.lang.Thread.State: RUNNABLE
> at
> org.apache.felix.ipojo.handlers.dependency.Dependency$NullableClassLoader.loadClass(Dependency.java:1072)
> at java.lang.Class.forName0(Class.java:-1)
> at java.lang.Class.forName(Class.java:264)
> at com.sun.proxy.$Proxy154.<clinit>(Unknown Source:-1)
> at
> sun.reflect.NativeConstructorAccessorImpl.newInstance0(NativeConstructorAccessorImpl.java:-1)
> at
> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
> at
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
> at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
> at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:739)
> at
> org.apache.felix.ipojo.handlers.dependency.Dependency.createNullableObject(Dependency.java:434)
> at
> org.apache.felix.ipojo.handlers.dependency.Dependency.start(Dependency.java:457)
> at
> org.apache.felix.ipojo.handlers.dependency.DependencyHandler.__M_start(DependencyHandler.java:496)
> at
> org.apache.felix.ipojo.handlers.dependency.DependencyHandler.start(DependencyHandler.java:-1)
> at
> org.apache.felix.ipojo.HandlerManager.start(HandlerManager.java:136)
> at
> org.apache.felix.ipojo.InstanceManager.start(InstanceManager.java:421)
> at
> org.apache.felix.ipojo.ComponentFactory.createInstance(ComponentFactory.java:179)
> at
> org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:319)
> - locked <0x2a3b> (a org.apache.felix.ipojo.ComponentFactory)
> at
> org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:240)
> at
> org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:312)
> at
> org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:306)
> at
> org.apache.felix.ipojo.extender.internal.queue.JobInfoCallable.call(JobInfoCallable.java:114)
> at java.util.concurrent.FutureTask.run(FutureTask.java:266)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
> at java.lang.Thread.run(Thread.java:745){code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)