Repository: netty/netty
Issue: netty-transport-native-epoll-*-linux-x86_64.jar is not OSGi bundle
Labels: defect

Hello,
basically, reopening https://github.com/netty/netty/issues/3781
I am working on OpenDaylight project and we would like use netty-transport-native-epoll due to the TCP MD5 signature support. Currently we are using Netty version 4.0.33.Final and bumping to 4.0.36.Final right now.
Unfortunately, netty-transport-native-epoll-*-linux-x86_64.jar is not a bundle and since the OpenDaylight is running in OSGi container (Apache Karaf) we are not able use it directly as a bundle (like other Netty artifacts).
It would be great for us if the jar is packed as a bundle as well.

Thanks,
Milos Fabian


Issue comments:
@MilosFabian we love PRs.. so maybe you can provide one as I don't have any good OSGI knowledge :(

Alright, I will work on it :) 

Thanks ❤️!

> Am 12.04.2016 um 09:33 schrieb MilosFabian notifications@github.com:
> 
> Alright, I will work on it :)
> 
> —
> You are receiving this because you commented.
> Reply to this email directly or view it on GitHub

I am sorry for a delay...finally I found some time take a look at it.
I managed produce bundle (include manifest in jar) for netty-transport-native-epoll-*-linux-x86_64
However, when I was trying to use the bundle in OSGi (Apache Karaf) I hit a problem when loading native library.
The Epoll.isAvailable() returns false with following unavailability cause.

java.lang.ClassNotFoundException: io.netty.channel.epoll.NativeStaticallyReferencedJniMethods
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)[:1.8.0_45]
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)[:1.8.0_45]
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1937)[:1.8.0_45]
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1822)[:1.8.0_45]
    at java.lang.Runtime.load0(Runtime.java:809)[:1.8.0_45]
    at java.lang.System.load(System.java:1086)[:1.8.0_45]
    at io.netty.util.internal.NativeLibraryLoader.load(NativeLibraryLoader.java:214)
    at io.netty.channel.epoll.Native.loadNativeLibrary(Native.java:261)
    at io.netty.channel.epoll.Native.<clinit>(Native.java:62)
    at io.netty.channel.epoll.Epoll.<clinit>(Epoll.java:33)

More investigation needed.

Fixed by https://github.com/netty/netty/pull/5326


Pull request review comments:

Patch that resolved the issue:
diff --git a/common/pom.xml b/common/pom.xml
index 6385c932854..d0b99399e5b 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -138,6 +138,27 @@
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>2.4.0</version>
+        <executions>
+          <execution>
+            <id>generate-manifest</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>manifest</goal>
+            </goals>
+            <configuration>
+              <instructions>
+                <!-- NativeLibraryLoader can be used to manually load native libraries from other bundles that this bundle does not depend on,
+                hence use DynamicImport-Package instruction to ensure the loading is successful -->
+                <DynamicImport-Package>*</DynamicImport-Package>
+              </instructions>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/transport-native-epoll/pom.xml b/transport-native-epoll/pom.xml
index a705b08ebaf..b12ba73623b 100644
--- a/transport-native-epoll/pom.xml
+++ b/transport-native-epoll/pom.xml
@@ -105,6 +105,13 @@
               <goal>jar</goal>
             </goals>
             <configuration>
+              <archive>
+                <manifest>
+                  <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                </manifest>
+                <index>true</index>
+                <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+              </archive>
               <classifier>${epoll.classifier}</classifier>
             </configuration>
           </execution>


Test patch: