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( ...@@ -103,6 +103,7 @@ def osgi_jar(
103 description = '', 103 description = '',
104 debug = False, 104 debug = False,
105 import_packages = '*', 105 import_packages = '*',
106 + dynamicimport_packages = '',
106 export_packages = '*', 107 export_packages = '*',
107 package_name_root = 'org.onosproject', 108 package_name_root = 'org.onosproject',
108 include_resources = NONE, 109 include_resources = NONE,
...@@ -169,6 +170,7 @@ def osgi_jar( ...@@ -169,6 +170,7 @@ def osgi_jar(
169 "'%s'" % export_packages, #packages to export 170 "'%s'" % export_packages, #packages to export
170 include_resources, #custom includes to classpath 171 include_resources, #custom includes to classpath
171 web_context, #web context (REST API only) 172 web_context, #web context (REST API only)
173 + "'%s'" % dynamicimport_packages, #DynamicImport-Package
172 description, #description 174 description, #description
173 ) 175 )
174 176
......
...@@ -23,4 +23,5 @@ osgi_jar_with_tests ( ...@@ -23,4 +23,5 @@ osgi_jar_with_tests (
23 deps = COMPILE_DEPS, 23 deps = COMPILE_DEPS,
24 test_deps = TEST_DEPS, 24 test_deps = TEST_DEPS,
25 visibility = ['PUBLIC'], 25 visibility = ['PUBLIC'],
26 + dynamicimport_packages = 'io.netty.*',
26 ) 27 )
......
...@@ -120,4 +120,23 @@ ...@@ -120,4 +120,23 @@
120 <version>${netty4.version}</version> 120 <version>${netty4.version}</version>
121 </dependency> 121 </dependency>
122 </dependencies> 122 </dependencies>
123 +
124 + <build>
125 + <plugins>
126 +
127 + <plugin>
128 + <groupId>org.apache.felix</groupId>
129 + <artifactId>maven-bundle-plugin</artifactId>
130 + <extensions>true</extensions>
131 + <configuration>
132 + <instructions>
133 + <DynamicImport-Package>
134 + io.netty.*
135 + </DynamicImport-Package>
136 + </instructions>
137 + </configuration>
138 + </plugin>
139 + </plugins>
140 + </build>
141 +
123 </project> 142 </project>
......
...@@ -64,6 +64,8 @@ public class OSGiWrapper { ...@@ -64,6 +64,8 @@ public class OSGiWrapper {
64 private String bundleVersion; 64 private String bundleVersion;
65 65
66 private String importPackages; 66 private String importPackages;
67 + private String dynamicimportPackages;
68 +
67 private String exportPackages; 69 private String exportPackages;
68 private String includeResources; 70 private String includeResources;
69 private Set<String> includedResources = Sets.newHashSet(); 71 private Set<String> includedResources = Sets.newHashSet();
...@@ -73,8 +75,9 @@ public class OSGiWrapper { ...@@ -73,8 +75,9 @@ public class OSGiWrapper {
73 75
74 private String webContext; 76 private String webContext;
75 77
78 + // FIXME should consider using Commons CLI, etc.
76 public static void main(String[] args) { 79 public static void main(String[] args) {
77 - if (args.length < 11) { 80 + if (args.length < 12) {
78 System.err.println("Not enough args"); 81 System.err.println("Not enough args");
79 System.exit(1); 82 System.exit(1);
80 } 83 }
...@@ -90,14 +93,17 @@ public class OSGiWrapper { ...@@ -90,14 +93,17 @@ public class OSGiWrapper {
90 String exportPackages = args[8]; 93 String exportPackages = args[8];
91 String includeResources = args[9]; 94 String includeResources = args[9];
92 String webContext = args[10]; 95 String webContext = args[10];
93 - String desc = Joiner.on(' ').join(Arrays.copyOfRange(args, 11, args.length)); 96 + String dynamicimportPackages = args[11];
97 + String desc = Joiner.on(' ').join(Arrays.copyOfRange(args, 12, args.length));
94 98
95 OSGiWrapper wrapper = new OSGiWrapper(jar, output, cp, 99 OSGiWrapper wrapper = new OSGiWrapper(jar, output, cp,
96 name, group, 100 name, group,
97 version, license, 101 version, license,
98 importPackages, exportPackages, 102 importPackages, exportPackages,
99 includeResources, 103 includeResources,
100 - webContext, desc); 104 + webContext,
105 + dynamicimportPackages,
106 + desc);
101 wrapper.log(wrapper + "\n"); 107 wrapper.log(wrapper + "\n");
102 if (!wrapper.execute()) { 108 if (!wrapper.execute()) {
103 System.err.printf("Error generating %s\n", name); 109 System.err.printf("Error generating %s\n", name);
...@@ -117,6 +123,7 @@ public class OSGiWrapper { ...@@ -117,6 +123,7 @@ public class OSGiWrapper {
117 String exportPackages, 123 String exportPackages,
118 String includeResources, 124 String includeResources,
119 String webContext, 125 String webContext,
126 + String dynamicimportPackages,
120 String bundleDescription) { 127 String bundleDescription) {
121 this.inputJar = inputJar; 128 this.inputJar = inputJar;
122 this.classpath = Lists.newArrayList(classpath.split(":")); 129 this.classpath = Lists.newArrayList(classpath.split(":"));
...@@ -134,6 +141,10 @@ public class OSGiWrapper { ...@@ -134,6 +141,10 @@ public class OSGiWrapper {
134 this.bundleDescription = bundleDescription; 141 this.bundleDescription = bundleDescription;
135 142
136 this.importPackages = importPackages; 143 this.importPackages = importPackages;
144 + this.dynamicimportPackages = dynamicimportPackages;
145 + if (Objects.equals(dynamicimportPackages, "''")) {
146 + this.dynamicimportPackages = null;
147 + }
137 this.exportPackages = exportPackages; 148 this.exportPackages = exportPackages;
138 if (!Objects.equals(includeResources, NONE)) { 149 if (!Objects.equals(includeResources, NONE)) {
139 this.includeResources = includeResources; 150 this.includeResources = includeResources;
...@@ -157,6 +168,8 @@ public class OSGiWrapper { ...@@ -157,6 +168,8 @@ public class OSGiWrapper {
157 // There are no good defaults so make sure you set the Import-Package 168 // There are no good defaults so make sure you set the Import-Package
158 analyzer.setProperty(Analyzer.IMPORT_PACKAGE, importPackages); 169 analyzer.setProperty(Analyzer.IMPORT_PACKAGE, importPackages);
159 170
171 + analyzer.setProperty(Analyzer.DYNAMICIMPORT_PACKAGE, dynamicimportPackages);
172 +
160 // TODO include version in export, but not in import 173 // TODO include version in export, but not in import
161 analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackages); 174 analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackages);
162 175
...@@ -251,7 +264,7 @@ public class OSGiWrapper { ...@@ -251,7 +264,7 @@ public class OSGiWrapper {
251 analyzer.setBundleClasspath("WEB-INF/classes," + 264 analyzer.setBundleClasspath("WEB-INF/classes," +
252 analyzer.getProperty(analyzer.BUNDLE_CLASSPATH)); 265 analyzer.getProperty(analyzer.BUNDLE_CLASSPATH));
253 266
254 - Set<String> paths = new HashSet<String>(dot.getResources().keySet()); 267 + Set<String> paths = new HashSet<>(dot.getResources().keySet());
255 268
256 for (String path : paths) { 269 for (String path : paths) {
257 if (path.indexOf('/') > 0 && !Character.isUpperCase(path.charAt(0))) { 270 if (path.indexOf('/') > 0 && !Character.isUpperCase(path.charAt(0))) {
......