Skip to content

Commit c31ffdf

Browse files
committed
ResourceAwareClassLoader: Add buddies as Bundle entries.
1 parent 4cb432b commit c31ffdf

File tree

1 file changed

+78
-44
lines changed

1 file changed

+78
-44
lines changed

org.knime.scijava.core/src/org/knime/scijava/core/ResourceAwareClassLoader.java

+78-44
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
package org.knime.scijava.core;
22

33
import java.io.IOException;
4-
import java.net.MalformedURLException;
54
import java.net.URL;
5+
import java.util.ArrayList;
66
import java.util.Collections;
77
import java.util.Enumeration;
88
import java.util.HashMap;
99
import java.util.HashSet;
10+
import java.util.List;
1011
import java.util.Map;
1112
import java.util.Set;
1213

1314
import org.eclipse.core.runtime.FileLocator;
15+
import org.eclipse.osgi.container.ModuleWire;
16+
import org.eclipse.osgi.container.ModuleWiring;
17+
import org.eclipse.osgi.internal.loader.EquinoxClassLoader;
1418
import org.eclipse.osgi.util.ManifestElement;
1519
import org.osgi.framework.Bundle;
1620
import org.osgi.framework.BundleException;
1721
import org.osgi.framework.Constants;
1822
import org.osgi.framework.FrameworkUtil;
23+
import org.osgi.framework.namespace.BundleNamespace;
24+
import org.osgi.framework.namespace.PackageNamespace;
1925

2026
/**
2127
* ResourceAwareClassLoader
@@ -26,14 +32,14 @@
2632
* @author Jonathan Hale (University of Konstanz)
2733
*
2834
*/
35+
@SuppressWarnings("restriction")
2936
public class ResourceAwareClassLoader extends ClassLoader {
3037

3138
/**
3239
* Resources which need to be treated in a special way.
3340
*/
3441
// TODO make an extension point to add resources as needed (later)
35-
private final String[] RESOURCES = new String[] {
36-
"META-INF/json/org.scijava.plugin.Plugin",
42+
private final String[] RESOURCES = new String[] { "META-INF/json/org.scijava.plugin.Plugin",
3743
"META-INF/services/javax.script.ScriptEngineFactory" };
3844

3945
private final Map<String, Set<URL>> urls = new HashMap<String, Set<URL>>();
@@ -77,51 +83,75 @@ public ResourceAwareClassLoader(final ClassLoader parent, Class<?> clazz) {
7783
urls.put(res, new HashSet<URL>());
7884
}
7985

80-
final String requireBundle = (String) FrameworkUtil.getBundle(clazz)
81-
.getHeaders().get(Constants.REQUIRE_BUNDLE);
82-
try {
83-
final ManifestElement[] elements = ManifestElement.parseHeader(
84-
Constants.BUNDLE_CLASSPATH, requireBundle);
85-
for (final ManifestElement manifestElement : elements) {
86-
final Bundle bundle = org.eclipse.core.runtime.Platform
87-
.getBundle(manifestElement.getValue());
88-
89-
try {
90-
// get file url for this bundle
91-
bundleUrls.add(new URL("file://"
92-
+ FileLocator.getBundleFile(bundle)
93-
.getAbsolutePath()));
94-
} catch (MalformedURLException e1) {
95-
e1.printStackTrace();
96-
} catch (IOException e1) {
97-
e1.printStackTrace();
98-
}
86+
processBuddies(clazz);
9987

100-
for (final String res : RESOURCES) {
101-
Enumeration<URL> resources;
102-
try {
103-
resources = bundle.getResources(res);
104-
} catch (IOException e) {
105-
continue;
106-
}
88+
processBundle(FrameworkUtil.getBundle(clazz), true);
89+
}
10790

108-
if (resources == null) {
109-
continue;
91+
private void processBuddies(Class<?> clazz) {
92+
final EquinoxClassLoader loader = (EquinoxClassLoader) clazz.getClassLoader();
93+
ArrayList<ModuleWiring> allDependents = new ArrayList<ModuleWiring>();
94+
List<ModuleWire> providedWires = loader.getBundleLoader().getWiring().getProvidedModuleWires(null);
95+
if (providedWires != null) {
96+
for (ModuleWire wire : providedWires) {
97+
String namespace = wire.getRequirement().getNamespace();
98+
if (PackageNamespace.PACKAGE_NAMESPACE.equals(namespace)
99+
|| BundleNamespace.BUNDLE_NAMESPACE.equals(namespace)) {
100+
ModuleWiring dependent = wire.getRequirerWiring();
101+
if (!allDependents.contains(dependent)) {
102+
bundleUrls.add(createBundleURL(dependent.getBundle()));
103+
processBundle(dependent.getBundle(), false);
110104
}
105+
}
106+
}
107+
}
108+
}
109+
110+
private void processBundle(final Bundle b, final boolean addRessources) {
111+
final String requireBundle = (String) b.getHeaders().get(Constants.REQUIRE_BUNDLE);
112+
try {
113+
final ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, requireBundle);
114+
for (final ManifestElement manifestElement : elements) {
115+
final Bundle bundle = org.eclipse.core.runtime.Platform.getBundle(manifestElement.getValue());
116+
117+
// get file url for this bundle
118+
bundleUrls.add(createBundleURL(bundle));
119+
120+
if (addRessources) {
121+
for (final String res : RESOURCES) {
122+
Enumeration<URL> resources;
123+
try {
124+
resources = bundle.getResources(res);
125+
} catch (IOException e) {
126+
continue;
127+
}
128+
129+
if (resources == null) {
130+
continue;
131+
}
111132

112-
while (resources.hasMoreElements()) {
113-
final URL resource = resources.nextElement();
114-
// we want to avoid transitive resolving of dependencies
115-
final String host = resource.getHost();
116-
if (bundle.getBundleId() == Long.valueOf(host
117-
.substring(0, host.indexOf(".")))) {
118-
safeAdd(urls.get(res), resource);
133+
while (resources.hasMoreElements()) {
134+
final URL resource = resources.nextElement();
135+
// we want to avoid transitive resolving of
136+
// dependencies
137+
final String host = resource.getHost();
138+
if (bundle.getBundleId() == Long.valueOf(host.substring(0, host.indexOf(".")))) {
139+
safeAdd(urls.get(res), resource);
140+
}
119141
}
120142
}
121143
}
122144
}
123145
} catch (BundleException e) {
124-
e.printStackTrace();
146+
throw new RuntimeException(e);
147+
}
148+
}
149+
150+
private URL createBundleURL(final Bundle bundle) {
151+
try {
152+
return new URL("file://" + FileLocator.getBundleFile(bundle).getAbsolutePath());
153+
} catch (IOException e) {
154+
throw new RuntimeException(e);
125155
}
126156
}
127157

@@ -133,26 +163,30 @@ public Enumeration<URL> getResources(final String name) throws IOException {
133163
return super.getResources(name);
134164
}
135165

136-
for(final URL url : Collections.list(super.getResources(name))){
166+
for (final URL url : Collections.list(super.getResources(name))) {
137167
safeAdd(urlList, url);
138168
}
139-
169+
140170
return Collections.enumeration(urlList);
141171
}
142-
172+
143173
/**
144174
* Get a set of file URLs to the bundles dependency bundles.
175+
*
145176
* @return set of dependency bundle file urls
146177
*/
147178
public Set<URL> getBundleUrls() {
148179
return bundleUrls;
149180
}
150-
181+
151182
/*
152183
* Add url to urls while making sure, that the resulting file urls are
153184
* always unique.
185+
*
154186
* @param urls Set to add the url to
187+
*
155188
* @param urlToAdd Url to add to the set
189+
*
156190
* @see FileLocator
157191
*/
158192
private static void safeAdd(final Set<URL> urls, final URL urlToAdd) {
@@ -173,5 +207,5 @@ private static void safeAdd(final Set<URL> urls, final URL urlToAdd) {
173207
// no duplicate found, we can safely add this url.
174208
urls.add(urlToAdd);
175209
}
176-
210+
177211
}

0 commit comments

Comments
 (0)