[ 
https://issues.apache.org/jira/browse/FELIX-3407?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13250530#comment-13250530
 ] 

Stuart McCulloch commented on FELIX-3407:
-----------------------------------------

There is a reference to "example.a.two" in the constant pool which I believe 
bnd should have picked up:

javap -c -verbose -private target/classes/example/c/ExampleExtendedInterfaceA
===========================================================================
Compiled from "ExampleExtendedInterfaceA.java"
public interface example.c.ExampleExtendedInterfaceA extends 
example.a.one.ExampleInterfaceA
  Signature: length = 0x2
   00 05 
  SourceFile: "ExampleExtendedInterfaceA.java"
  minor version: 0
  major version: 49
  Constant pool:
const #1 = class        #8;     //  example/c/ExampleExtendedInterfaceA
const #2 = class        #9;     //  java/lang/Object
const #3 = class        #10;    //  example/a/one/ExampleInterfaceA
const #4 = Asciz        Signature;
const #5 = Asciz        
Ljava/lang/Object;Lexample/a/one/ExampleInterfaceA<Lexample/b/two/ExampleImplementationB;>;;
const #6 = Asciz        SourceFile;
const #7 = Asciz        ExampleExtendedInterfaceA.java;
const #8 = Asciz        example/c/ExampleExtendedInterfaceA;
const #9 = Asciz        java/lang/Object;
const #10 = Asciz       example/a/one/ExampleInterfaceA;

{
}
===========================================================================

This is because generic types are not always fully erased: 
http://www.artima.com/weblogs/viewpost.jsp?thread=208860

I've logged this on the bnd issue tracker as 
https://github.com/bndtools/bnd/issues/152 since it relates to bnd's bytecode 
analysis. 

Normally ignoring the generic signature isn't a problem, since this extra 
information isn't actually required to load and use the class in Java code (due 
to type erasure rules). The issue appears to be that blueprint attempts to load 
the type parameters encoded in the constant pool when analyzing the service 
class using reflection ( ie. with 
http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments()
 ) and therefore it needs this extra information.
                
> Imports are missed for generics
> -------------------------------
>
>                 Key: FELIX-3407
>                 URL: https://issues.apache.org/jira/browse/FELIX-3407
>             Project: Felix
>          Issue Type: Bug
>          Components: Maven Bundle Plugin
>    Affects Versions: maven-bundle-plugin-2.3.7
>            Reporter: Tomas Forsman
>         Attachments: example.zip
>
>
> The bundle plugin miss to add imports to classes/interfaces that are used in 
> generic blocks due to type erasure.
> Consider the following (the code is in the attached zip):
> bundle-a:
> package example.a.one;
> public interface ExampleInterfaceA<T extends ExampleInterfaceB> {
>     String getGreeting(T example);
> }
> package example.a.two;
> public interface ExampleInterfaceB {
> }
> bundle-b:
> package example.b.two;
> import example.a.two.ExampleInterfaceB;
> public interface ExampleImplementationB extends ExampleInterfaceB {
> }
> bundle-c:
> package example.c;
> import example.a.one.ExampleInterfaceA;
> import example.b.two.ExampleImplementationB;
> public interface ExampleExtendedInterfaceA extends 
> ExampleInterfaceA<ExampleImplementationB> {
> }
> package example.c;
> public class ExampleReferenceListener {
>     public void register(final ExampleExtendedInterfaceA example) {
>     }
>     public void unregister(final ExampleExtendedInterfaceA example) {
>     }
> }
> OSGI-INF/blueprint/services.xml
> <?xml version="1.0" encoding="UTF-8"?>
> <blueprint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
>            xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
>            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 
> http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd";>
>     <reference-list id="exampleReferenceListener"
>                     interface="example.c.ExampleExtendedInterfaceA"
>                     availability="optional">
>         <reference-listener bind-method="register" unbind-method="unregister">
>             <bean class="example.c.ExampleReferenceListener"/>
>         </reference-listener>
>     </reference-list>
> </blueprint>
> bundle-d:
> package example.d;
> import example.b.two.ExampleImplementationB;
> import example.c.ExampleExtendedInterfaceA;
> public class ExampleExtendedImplementation implements 
> ExampleExtendedInterfaceA {
>     public String getGreeting(final ExampleImplementationB example) {
>         return "Hello World";
>     }
> }
> OSGI-INF/blueprint/services.xml
> <?xml version="1.0" encoding="UTF-8"?>
> <blueprint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
>            xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
>            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 
> http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd";>
>     <bean id="exampleBean" class="example.d.ExampleExtendedImplementation"/>
>     <service id="exampleService" 
> interface="example.c.ExampleExtendedInterfaceA" ref="exampleBean"/>
> </blueprint>
> Since the bundle plugin uses byte-code to find out which imports to add to 
> the manifest, the bundle-c manifest look like this:
> Manifest-Version: 1.0
> Bnd-LastModified: 1332925553008
> Build-Jdk: 1.6.0_26
> Built-By: tofo01
> Bundle-ManifestVersion: 2
> Bundle-Name: example.bundle-c
> Bundle-SymbolicName: example.bundle-c
> Bundle-Version: 1.0.0.SNAPSHOT
> Created-By: Apache Maven Bundle Plugin
> Export-Package: example.c;uses:="example.a.one";version="1.0.0.SNAPSHOT"
> Import-Package: 
> example.a.one;version="[1.0,2)",org.osgi.service.blueprint;version="[1.0.0,2.0.0)"
> Import-Service: 
> example.c.ExampleExtendedInterfaceA;multiple:=true;availability:=optional
> Tool: Bnd-1.50.0
> The "example.a.two" package import is missing since type-erasure removes the 
> generic part of ExampleInterfaceA in the bundle-c interface.
> This results in a NoClassDefFondError of example.a.two.ExampleInterfaceB from 
> bundle-c when trying to deploy bundle-d.
> "Error tracking new service reference java.lang.NoClassDefFoundError: 
> example.a.two.ExampleInterfaceB not found by example.bundle-c [159]"

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to