Yuta HIGUCHI
Committed by Gerrit Code Review

Fix for Netty wiring issue after 4.0 bump.

- After updating Netty 4.0 version,
  we sometimes see java.lang.NoClassDefFoundError: io/netty/util/internal/TypeParameterMatcher
  with backtrace insisting there's some dynamic class resolution inside Netty.

  It might be side-effect of recent native-epoll support inside karaf?
   https://github.com/netty/netty/issues/5119

- Add DynamicImport-Package for io.netty to allow deferred wiring
  http://felix.apache.org/documentation/tutorials-examples-and-presentations/apache-felix-osgi-faq.html#how-to-provide-optional-services
- Add a way to pass DynamicImport-Package on BUCK build

Change-Id: I50ec3400e940c56fb52563d84659ebb30c302235
......@@ -103,6 +103,7 @@ def osgi_jar(
description = '',
debug = False,
import_packages = '*',
dynamicimport_packages = '',
export_packages = '*',
package_name_root = 'org.onosproject',
include_resources = NONE,
......@@ -169,6 +170,7 @@ def osgi_jar(
"'%s'" % export_packages, #packages to export
include_resources, #custom includes to classpath
web_context, #web context (REST API only)
"'%s'" % dynamicimport_packages, #DynamicImport-Package
description, #description
)
......
......@@ -23,4 +23,5 @@ osgi_jar_with_tests (
deps = COMPILE_DEPS,
test_deps = TEST_DEPS,
visibility = ['PUBLIC'],
dynamicimport_packages = 'io.netty.*',
)
......
......@@ -120,4 +120,23 @@
<version>${netty4.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<DynamicImport-Package>
io.netty.*
</DynamicImport-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
......
......@@ -64,6 +64,8 @@ public class OSGiWrapper {
private String bundleVersion;
private String importPackages;
private String dynamicimportPackages;
private String exportPackages;
private String includeResources;
private Set<String> includedResources = Sets.newHashSet();
......@@ -73,8 +75,9 @@ public class OSGiWrapper {
private String webContext;
// FIXME should consider using Commons CLI, etc.
public static void main(String[] args) {
if (args.length < 11) {
if (args.length < 12) {
System.err.println("Not enough args");
System.exit(1);
}
......@@ -90,14 +93,17 @@ public class OSGiWrapper {
String exportPackages = args[8];
String includeResources = args[9];
String webContext = args[10];
String desc = Joiner.on(' ').join(Arrays.copyOfRange(args, 11, args.length));
String dynamicimportPackages = args[11];
String desc = Joiner.on(' ').join(Arrays.copyOfRange(args, 12, args.length));
OSGiWrapper wrapper = new OSGiWrapper(jar, output, cp,
name, group,
version, license,
importPackages, exportPackages,
includeResources,
webContext, desc);
webContext,
dynamicimportPackages,
desc);
wrapper.log(wrapper + "\n");
if (!wrapper.execute()) {
System.err.printf("Error generating %s\n", name);
......@@ -117,6 +123,7 @@ public class OSGiWrapper {
String exportPackages,
String includeResources,
String webContext,
String dynamicimportPackages,
String bundleDescription) {
this.inputJar = inputJar;
this.classpath = Lists.newArrayList(classpath.split(":"));
......@@ -134,6 +141,10 @@ public class OSGiWrapper {
this.bundleDescription = bundleDescription;
this.importPackages = importPackages;
this.dynamicimportPackages = dynamicimportPackages;
if (Objects.equals(dynamicimportPackages, "''")) {
this.dynamicimportPackages = null;
}
this.exportPackages = exportPackages;
if (!Objects.equals(includeResources, NONE)) {
this.includeResources = includeResources;
......@@ -157,6 +168,8 @@ public class OSGiWrapper {
// There are no good defaults so make sure you set the Import-Package
analyzer.setProperty(Analyzer.IMPORT_PACKAGE, importPackages);
analyzer.setProperty(Analyzer.DYNAMICIMPORT_PACKAGE, dynamicimportPackages);
// TODO include version in export, but not in import
analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackages);
......@@ -251,7 +264,7 @@ public class OSGiWrapper {
analyzer.setBundleClasspath("WEB-INF/classes," +
analyzer.getProperty(analyzer.BUNDLE_CLASSPATH));
Set<String> paths = new HashSet<String>(dot.getResources().keySet());
Set<String> paths = new HashSet<>(dot.getResources().keySet());
for (String path : paths) {
if (path.indexOf('/') > 0 && !Character.isUpperCase(path.charAt(0))) {
......