You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xbean-scm@geronimo.apache.org by ga...@apache.org on 2011/02/05 06:47:55 UTC
svn commit: r1067395 - in /geronimo/xbean/trunk/xbean-bundleutils: ./
src/main/java/org/apache/xbean/osgi/bundle/util/
src/main/java/org/apache/xbean/osgi/bundle/util/equinox/
Author: gawor
Date: Sat Feb 5 05:47:55 2011
New Revision: 1067395
URL: http://svn.apache.org/viewvc?rev=1067395&view=rev
Log:
XBEAN-163: Equinox BundleClassLoader implementation that translates bundle urls into jar urls
Added:
geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/
geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleClassLoader.java (with props)
geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleResourceHelper.java (with props)
Modified:
geronimo/xbean/trunk/xbean-bundleutils/pom.xml
geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassLoader.java
geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleResourceClassLoader.java
Modified: geronimo/xbean/trunk/xbean-bundleutils/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-bundleutils/pom.xml?rev=1067395&r1=1067394&r2=1067395&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-bundleutils/pom.xml (original)
+++ geronimo/xbean/trunk/xbean-bundleutils/pom.xml Sat Feb 5 05:47:55 2011
@@ -38,5 +38,46 @@
<version>4.2.0</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.eclipse</groupId>
+ <artifactId>osgi</artifactId>
+ <version>3.6.0.v20100517</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
+
+ <repositories>
+ <repository>
+ <!-- equinox -->
+ <!-- org.eclipse routing -->
+ <id>smx.svn</id>
+ <name>Servicemix svn Repository</name>
+ <layout>default</layout>
+ <url>http://svn.apache.org/repos/asf/servicemix/m2-repo/</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Import-Package>
+ org.eclipse.*;resolution:=optional,
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
</project>
Modified: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassLoader.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassLoader.java?rev=1067395&r1=1067394&r2=1067395&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassLoader.java (original)
+++ geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassLoader.java Sat Feb 5 05:47:55 2011
@@ -21,12 +21,7 @@ package org.apache.xbean.osgi.bundle.uti
import java.io.IOException;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleReference;
@@ -39,32 +34,40 @@ import org.osgi.framework.BundleReferenc
* (wired via <i>Import-Package</i> or <i>DynamicImport-Package</i>). This class loader implementation provides
* {@link #getResource(String) and {@link #getResources(String)} methods that do delegate such resource lookups to
* the wired bundles.
+ * <br/>
+ * The URLs returned by {@link Bundle#getResource(String)} or {@link Bundle#getResources(String)} methods are
+ * OSGi framework specific "bundle" URLs. This sometimes can cause problems with 3rd party libraries
+ * which do not understand how to interpret the "bundle" URLs. This ClassLoader implementation, if enabled,
+ * can return <tt>jar</tt> URLs for resources found in embedded jars in the bundle. If a resource is found within a
+ * directory in the bundle the URL returned for that resource is unconverted.
*
* @version $Rev$ $Date$
*/
public class BundleClassLoader extends ClassLoader implements BundleReference {
- private final static String META_INF_1 = "META-INF/";
- private final static String META_INF_2 = "/META-INF/";
-
protected final Bundle bundle;
- private LinkedHashSet<Bundle> wiredBundles = null;
- private boolean searchWiredBundles;
+ protected final BundleResourceHelper resourceHelper;
public BundleClassLoader(Bundle bundle) {
- this(bundle, true);
+ this(bundle, true, false);
}
-
+
public BundleClassLoader(Bundle bundle, boolean searchWiredBundles) {
+ this(bundle, searchWiredBundles, false);
+ }
+
+ public BundleClassLoader(Bundle bundle, boolean searchWiredBundles, boolean convertResourceUrls) {
this.bundle = bundle;
- this.searchWiredBundles = searchWiredBundles;
+ this.resourceHelper = new BundleResourceHelper(getBundle());
+ this.resourceHelper.setSearchWiredBundles(searchWiredBundles);
+ this.resourceHelper.setConvertResourceUrls(convertResourceUrls);
}
@Override
- public Class<?> loadClass(String name) throws ClassNotFoundException {
- return loadClass(name, false);
+ public String toString() {
+ return "[BundleClassLoader] " + bundle;
}
-
+
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class clazz = bundle.loadClass(name);
@@ -73,74 +76,33 @@ public class BundleClassLoader extends C
}
return clazz;
}
-
- @Override
- public String toString() {
- return "[BundleClassLoader] " + bundle;
- }
@Override
public URL getResource(String name) {
- URL resource = bundle.getResource(name);
- if (resource == null && isMetaInfResource(name)) {
- LinkedHashSet<Bundle> wiredBundles = getWiredBundles();
- Iterator<Bundle> iterator = wiredBundles.iterator();
- while (iterator.hasNext() && resource == null) {
- resource = iterator.next().getResource(name);
- }
- }
- return resource;
+ return resourceHelper.getResource(name);
}
-
- @SuppressWarnings("unchecked")
+
@Override
public Enumeration<URL> getResources(String name) throws IOException {
- Enumeration<URL> e = (Enumeration<URL>) bundle.getResources(name);
- if (isMetaInfResource(name)) {
- ArrayList<URL> allResources = new ArrayList<URL>();
- addToList(allResources, e);
- LinkedHashSet<Bundle> wiredBundles = getWiredBundles();
- for (Bundle wiredBundle : wiredBundles) {
- Enumeration<URL> resources = wiredBundle.getResources(name);
- addToList(allResources, resources);
- }
- return Collections.enumeration(allResources);
- } else {
- if (e == null) {
- return Collections.enumeration(Collections.EMPTY_LIST);
- } else {
- return e;
- }
- }
+ return resourceHelper.getResources(name);
}
-
+
public void setSearchWiredBundles(boolean search) {
- searchWiredBundles = search;
+ resourceHelper.setSearchWiredBundles(search);
}
public boolean getSearchWiredBundles() {
- return searchWiredBundles;
+ return resourceHelper.getSearchWiredBundles();
}
-
- protected synchronized LinkedHashSet<Bundle> getWiredBundles() {
- if (wiredBundles == null) {
- wiredBundles = BundleUtils.getWiredBundles(bundle);
- }
- return wiredBundles;
+
+ public void setConvertResourceUrls(boolean convert) {
+ resourceHelper.setConvertResourceUrls(convert);
}
- protected boolean isMetaInfResource(String name) {
- return searchWiredBundles && name != null && (name.startsWith(META_INF_1) || name.startsWith(META_INF_2));
- }
-
- private void addToList(List<URL> list, Enumeration<URL> enumeration) {
- if (enumeration != null) {
- while (enumeration.hasMoreElements()) {
- list.add(enumeration.nextElement());
- }
- }
+ public boolean getConvertResourceUrls() {
+ return resourceHelper.getConvertResourceUrls();
}
-
+
/**
* Return the bundle associated with this classloader.
*
Modified: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleResourceClassLoader.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleResourceClassLoader.java?rev=1067395&r1=1067394&r2=1067395&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleResourceClassLoader.java (original)
+++ geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleResourceClassLoader.java Sat Feb 5 05:47:55 2011
@@ -19,20 +19,7 @@
package org.apache.xbean.osgi.bundle.util;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.zip.ZipEntry;
-
import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.PackageAdmin;
/**
* ClassLoader for a {@link Bundle}.
@@ -45,77 +32,12 @@ import org.osgi.service.packageadmin.Pac
public class BundleResourceClassLoader extends BundleClassLoader {
public BundleResourceClassLoader(Bundle bundle) {
- super(bundle);
+ super(bundle, true, true);
}
@Override
public String toString() {
return "[BundleResourceClassLoader] " + bundle;
}
-
- @Override
- public URL getResource(String name) {
- ServiceReference reference = bundle.getBundleContext().getServiceReference(PackageAdmin.class.getName());
- PackageAdmin packageAdmin = (PackageAdmin) bundle.getBundleContext().getService(reference);
- try {
- List<URL> resources = findResources(packageAdmin, bundle, name, false);
- if (resources.isEmpty() && isMetaInfResource(name)) {
- LinkedHashSet<Bundle> wiredBundles = getWiredBundles();
- Iterator<Bundle> iterator = wiredBundles.iterator();
- while (iterator.hasNext() && resources.isEmpty()) {
- Bundle wiredBundle = iterator.next();
- resources = findResources(packageAdmin, wiredBundle, name, false);
- }
- }
- return (resources.isEmpty()) ? null : resources.get(0);
- } catch (Exception e) {
- return null;
- } finally {
- bundle.getBundleContext().ungetService(reference);
- }
- }
-
- @Override
- public Enumeration<URL> getResources(String name) throws IOException {
- ServiceReference reference = bundle.getBundleContext().getServiceReference(PackageAdmin.class.getName());
- PackageAdmin packageAdmin = (PackageAdmin) bundle.getBundleContext().getService(reference);
- try {
- List<URL> resources = findResources(packageAdmin, bundle, name, true);
- if (isMetaInfResource(name)) {
- LinkedHashSet<Bundle> wiredBundles = getWiredBundles();
- for (Bundle wiredBundle : wiredBundles) {
- resources.addAll(findResources(packageAdmin, wiredBundle, name, true));
- }
- }
- return Collections.enumeration(resources);
- } catch (Exception e) {
- throw new IOException("Error discovering resources", e);
- } finally {
- bundle.getBundleContext().ungetService(reference);
- }
- }
-
- private static List<URL> findResources(PackageAdmin packageAdmin,
- Bundle bundle,
- String name,
- final boolean continueScanning) throws Exception {
- BundleResourceFinder finder = new BundleResourceFinder(packageAdmin, bundle, "", name);
- final List<URL> resources = new ArrayList<URL>();
- finder.find(new BundleResourceFinder.ResourceFinderCallback() {
-
- public boolean foundInDirectory(Bundle bundle, String baseDir, URL url) throws Exception {
- resources.add(url);
- return continueScanning;
- }
-
- public boolean foundInJar(Bundle bundle, String jarName, ZipEntry entry, InputStream inputStream) throws Exception {
- URL jarURL = bundle.getEntry(jarName);
- URL url = new URL("jar:" + jarURL.toString() + "!/" + entry.getName());
- resources.add(url);
- return continueScanning;
- }
- });
- return resources;
- }
}
Added: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleClassLoader.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleClassLoader.java?rev=1067395&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleClassLoader.java (added)
+++ geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleClassLoader.java Sat Feb 5 05:47:55 2011
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.xbean.osgi.bundle.util.equinox;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Enumeration;
+
+import org.apache.xbean.osgi.bundle.util.BundleResourceHelper;
+import org.apache.xbean.osgi.bundle.util.DelegatingBundle;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+
+/**
+ * ClassLoader for a {@link Bundle}.
+ * <br/>
+ * This ClassLoader implementation extends the {@link URLClassLoader} and converts resource "bundle"
+ * URLs (found in directories or embedded jar files) into regular <tt>jar</tt> URLs.
+ * This ClassLoader implementation will only work on Equinox framework.
+ *
+ * @version $Rev$ $Date$
+ */
+public class EquinoxBundleClassLoader extends URLClassLoader implements BundleReference {
+
+ private final Bundle bundle;
+ private final BundleResourceHelper resourceHelper;
+
+ public EquinoxBundleClassLoader(Bundle bundle) {
+ super(new URL[] {});
+ this.bundle = bundle;
+ this.resourceHelper = new EquinoxBundleResourceHelper(getBundle());
+ this.resourceHelper.setSearchWiredBundles(true);
+ this.resourceHelper.setConvertResourceUrls(true);
+ }
+
+ @Override
+ public String toString() {
+ return "[EquinoxBundleClassLoader] " + bundle;
+ }
+
+ @Override
+ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ Class clazz = bundle.loadClass(name);
+ if (resolve) {
+ resolveClass(clazz);
+ }
+ return clazz;
+ }
+
+ @Override
+ public URL getResource(String name) {
+ return resourceHelper.getResource(name);
+ }
+
+ @Override
+ public Enumeration<URL> getResources(String name) throws IOException {
+ return resourceHelper.getResources(name);
+ }
+
+ public void setSearchWiredBundles(boolean search) {
+ resourceHelper.setSearchWiredBundles(search);
+ }
+
+ public boolean getSearchWiredBundles() {
+ return resourceHelper.getSearchWiredBundles();
+ }
+
+ public void setConvertResourceUrls(boolean convert) {
+ resourceHelper.setConvertResourceUrls(convert);
+ }
+
+ public boolean getConvertResourceUrls() {
+ return resourceHelper.getConvertResourceUrls();
+ }
+
+ /**
+ * Return the bundle associated with this classloader.
+ *
+ * In most cases the bundle associated with the classloader is a regular framework bundle.
+ * However, in some cases the bundle associated with the classloader is a {@link DelegatingBundle}.
+ * In such cases, the <tt>unwrap</tt> parameter controls whether this function returns the
+ * {@link DelegatingBundle} instance or the main application bundle backing with the {@link DelegatingBundle}.
+ *
+ * @param unwrap If true and if the bundle associated with this classloader is a {@link DelegatingBundle},
+ * this function will return the main application bundle backing with the {@link DelegatingBundle}.
+ * Otherwise, the bundle associated with this classloader is returned as is.
+ * @return The bundle associated with this classloader.
+ */
+ public Bundle getBundle(boolean unwrap) {
+ if (unwrap && bundle instanceof DelegatingBundle) {
+ return ((DelegatingBundle) bundle).getMainBundle();
+ }
+ return bundle;
+ }
+
+ /**
+ * Return the bundle associated with this classloader.
+ *
+ * This method calls {@link #getBundle(boolean) getBundle(true)} and therefore always returns a regular
+ * framework bundle.
+ * <br><br>
+ * Note: Some libraries use {@link BundleReference#getBundle()} to obtain a bundle for the given
+ * classloader and expect the returned bundle instance to be work with any OSGi API. Some of these API might
+ * not work if {@link DelegatingBundle} is returned. That is why this function will always return
+ * a regular framework bundle. See {@link #getBundle(boolean)} for more information.
+ *
+ * @return The bundle associated with this classloader.
+ */
+ public Bundle getBundle() {
+ return getBundle(true);
+ }
+
+ @Override
+ public int hashCode() {
+ return bundle.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (other == null || !other.getClass().equals(getClass())) {
+ return false;
+ }
+ EquinoxBundleClassLoader otherBundleClassLoader = (EquinoxBundleClassLoader) other;
+ return this.bundle == otherBundleClassLoader.bundle;
+ }
+
+}
Propchange: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleClassLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleClassLoader.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleClassLoader.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleResourceHelper.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleResourceHelper.java?rev=1067395&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleResourceHelper.java (added)
+++ geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleResourceHelper.java Sat Feb 5 05:47:55 2011
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.xbean.osgi.bundle.util.equinox;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.apache.xbean.osgi.bundle.util.BundleResourceHelper;
+import org.eclipse.osgi.service.urlconversion.URLConverter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Equinox implementation of BundleResourceHelper.
+ * <br/>
+ * This implementation of the {@link BundleResourceHelper} converts resource URLs
+ * returned by {@link #getResource(String)} and {@link #getResources(String)} into <tt>jar</tt> URLs
+ * using Equinox's <tt>URLConverter</tt> service.
+ *
+ * @version $Rev$ $Date$
+ */
+public class EquinoxBundleResourceHelper extends BundleResourceHelper {
+
+ private URLConverter converter;
+
+ public EquinoxBundleResourceHelper(Bundle bundle) {
+ super(bundle);
+ init();
+ }
+
+ private void init() {
+ BundleContext context = bundle.getBundleContext();
+ if (context != null) {
+ ServiceReference urlReference = context.getServiceReference(URLConverter.class.getName());
+ if (urlReference != null) {
+ converter = (URLConverter) context.getService(urlReference);
+ }
+ }
+ }
+
+ @Override
+ public URL getResource(String name) {
+ if (convertResourceUrls) {
+ return (converter == null) ? convertedFindResource(name) : findResource(name);
+ } else {
+ return findResource(name);
+ }
+ }
+
+ @Override
+ public Enumeration<URL> getResources(String name) throws IOException {
+ if (convertResourceUrls) {
+ return (converter == null) ? convertedFindResources(name) : findResources(name);
+ } else {
+ return findResources(name);
+ }
+ }
+
+ @Override
+ protected URL convert(URL url) {
+ try {
+ URL convertedURL = converter.resolve(url);
+ return convertedURL;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return url;
+ }
+ }
+
+}
Propchange: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleResourceHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleResourceHelper.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/equinox/EquinoxBundleResourceHelper.java
------------------------------------------------------------------------------
svn:mime-type = text/plain