Fix FELIX-4668
When a required stereotype class (or any class) is not in the bundle, tries to load it from the classpath.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1643082 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
index b9b0ce6..445caf2 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
@@ -154,6 +154,7 @@
try {
JarFile origin = new JarFile(in);
JarFileResourceStore jfrs = new JarFileResourceStore(origin, out);
+ jfrs.setClassLoader(loader);
if (in.getName().endsWith(".war")) {
// this is a war file, use the right mapper
jfrs.setResourceMapper(new WABResourceMapper());
@@ -222,6 +223,7 @@
try {
JarFile origin = new JarFile(in);
JarFileResourceStore jfrs = new JarFileResourceStore(origin, out);
+ jfrs.setClassLoader(loader);
if (in.getName().endsWith(".war")) {
// this is a war file, use the right mapper
jfrs.setResourceMapper(new WABResourceMapper());
@@ -336,7 +338,8 @@
public void pojoization(final ResourceStore store,
final MetadataProvider metadata,
- final ManipulationVisitor visitor, ClassLoader loader) {
+ final ManipulationVisitor visitor,
+ final ClassLoader loader) {
ManipulationEngine engine = new ManipulationEngine(loader);
engine.setResourceStore(store);
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java
index 0f0e660..44d185a 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java
@@ -26,10 +26,8 @@
import org.apache.felix.ipojo.manipulator.util.Streams;
import org.apache.felix.ipojo.metadata.Element;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
+import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -78,9 +76,12 @@
*/
private Manifest m_manifest;
+ private ClassLoader classLoader;
+
/**
* Construct a {@link JarFileResourceStore} wrapping the given original bundle,
* and configured to output in the given target file.
+ *
* @param source original Bundle
* @param target File where the updated Bundle will be outputted
* @throws IOException if there is an error retrieving the Manifest from the original JarFile
@@ -111,14 +112,42 @@
this.m_manifest = manifest;
}
+ public void setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
public byte[] read(String path) throws IOException {
ZipEntry entry = m_source.getEntry(getInternalPath(path));
if (entry == null) {
- throw new IOException("Jar Entry is not found for class " + path + ".");
+ // Not in the Jar file, trying from classpath
+ return tryToLoadFromClassloader(path);
}
return Streams.readBytes(m_source.getInputStream(entry));
}
+ private byte[] tryToLoadFromClassloader(String path) throws IOException {
+ if (classLoader != null) {
+ byte[] bytes = toByteArray(classLoader.getResource(path));
+ if (bytes != null) {
+ return bytes;
+ }
+ }
+ throw new IOException("Class not found " + path + ".");
+ }
+
+ public static byte[] toByteArray(URL url) throws IOException {
+ if (url == null) {
+ return null;
+ }
+ InputStream input = url.openStream();
+ try {
+ return Streams.readBytes(input);
+ } finally {
+ Streams.close(input);
+ }
+
+ }
+
private String getInternalPath(String path) {
return m_mapper.internalize(path);
}