Improve native code loading - bundle installation will now fail in case a native library is not in the jar and we only use the first library of a given name. Furthermore, we now support .dylib extensions on the mac as well as others (should make it possible to use .netmodules as well) FELIX-439.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@605346 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
index a8c52ac..3806787 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
@@ -176,9 +176,16 @@
}
// TODO: This will need to consider security.
- public String findLibrary(String libName) throws Exception
+ public String findLibrary(String libName) throws Exception
{
- return BundleCache.getSecureAction().getAbsolutePath(new File(m_refDir, libName));
+ String result = BundleCache.getSecureAction().getAbsolutePath(new File(m_refDir, libName));
+
+ if (result == null)
+ {
+ throw new IOException("No such file: " + libName);
+ }
+
+ return result;
}
public void dispose() throws Exception
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
index efa0f86..e942a79 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
@@ -295,19 +295,53 @@
if (clause != null)
{
- R4Library[] libraries = new R4Library[clause.getLibraryFiles().length];
- for (int i = 0; i < libraries.length; i++)
+ String[] files = clause.getLibraryFiles();
+ R4Library[] libraries = new R4Library[files.length];
+ int current = 0;
+ try
{
- libraries[i] = new R4Library(
- m_logger, revision, clause.getLibraryFiles()[i],
- clause.getOSNames(), clause.getProcessors(), clause.getOSVersions(),
- clause.getLanguages(), clause.getSelectionFilter());
+ for (int i = 0; i < libraries.length; i++)
+ {
+ String name = getName(files[i]);
+ boolean found = false;
+ for (int j = 0; !found && (j < current); j++)
+ {
+ found = getName(files[j]).equals(name);
+ }
+ if (!found)
+ {
+ libraries[current++] = new R4Library(
+ m_logger, revision, clause.getLibraryFiles()[i],
+ clause.getOSNames(), clause.getProcessors(), clause.getOSVersions(),
+ clause.getLanguages(), clause.getSelectionFilter());
+ }
+ }
+ if (current < libraries.length)
+ {
+ R4Library[] tmp = new R4Library[current];
+ System.arraycopy(libraries, 0, tmp, 0, current);
+ libraries = tmp;
+ }
+ return libraries;
}
- return libraries;
+ catch (Exception ex)
+ {
+ throw new BundleException("Unable to create library", ex);
+ }
}
return null;
}
+ private String getName(String path)
+ {
+ int idx = path.lastIndexOf('/');
+ if (idx > -1)
+ {
+ return path.substring(idx);
+ }
+ return path;
+ }
+
private R4LibraryClause getSelectedLibraryClause() throws BundleException
{
if ((m_libraryHeaders != null) && (m_libraryHeaders.length > 0))
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java
index 624b987..2a609c4 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java
@@ -36,7 +36,7 @@
public R4Library(Logger logger, BundleRevision revision,
String libraryFile, String[] osnames, String[] processors, String[] osversions,
- String[] languages, String selectionFilter)
+ String[] languages, String selectionFilter) throws Exception
{
m_logger = logger;
m_revision = revision;
@@ -46,6 +46,9 @@
m_osversions = osversions;
m_languages = languages;
m_selectionFilter = selectionFilter;
+
+ // Make sure we actually have the library in the revision
+ m_revision.findLibrary(m_libraryFile);
}
public String[] getOSNames()
@@ -84,18 +87,32 @@
public String getPath(String name)
{
String libname = System.mapLibraryName(name);
- if (m_libraryFile.indexOf(libname) >= 0)
+
+ try
{
- try
+ if (m_libraryFile.equals(libname) || m_libraryFile.endsWith("/" + libname))
{
return m_revision.findLibrary(m_libraryFile);
}
- catch (Exception ex)
+ else if (libname.endsWith(".jnilib") &&
+ m_libraryFile.endsWith(".dylib"))
{
- m_logger.log(Logger.LOG_ERROR, "R4Library: Finding library '"
- + name + "'.", new BundleException(
- "Unable to find native library '" + name + "'."));
+ libname = libname.substring(0, libname.length() - 6) + "dylib";
+ if (m_libraryFile.equals(libname) || m_libraryFile.endsWith("/" + libname))
+ {
+ return m_revision.findLibrary(m_libraryFile);
+ }
}
+ else if (m_libraryFile.equals(name) || m_libraryFile.endsWith("/" + name))
+ {
+ return m_revision.findLibrary(m_libraryFile);
+ }
+ }
+ catch (Exception ex)
+ {
+ m_logger.log(Logger.LOG_ERROR, "R4Library: Finding library '"
+ + name + "'.", new BundleException(
+ "Unable to find native library '" + name + "'."));
}
return null;
}