Class ClassPathUtil
- java.lang.Object
-
- org.ops4j.pax.web.utils.ClassPathUtil
-
public class ClassPathUtil extends Object
Utilities to perform bundle scanning - using only OSGi Core APIs (without using e.g., XBean Finder)- Author:
- achim
-
-
Method Summary
All Methods Static Methods Concrete Methods Deprecated Methods Modifier and Type Method Description static List<URL>
findEntries(ClassLoader loader, String path, String pattern, boolean recurse)
This method matchesBundle.findEntries(String, String, boolean)
but should be used when we don't have access to anyBundle
.static List<URL>
findEntries(Iterable<org.osgi.framework.Bundle> bundles, String path, String pattern, boolean recurse, boolean useBundleClasspath)
This method usesBundleWiring.findEntries(java.lang.String, java.lang.String, int)
that doesn't involve classloaders so we can get resources from fixed path.static List<URL>
findEntries(org.osgi.framework.Bundle bundle, String path, String pattern, boolean recurse, boolean useBundleClasspath)
This method usesBundleWiring.findEntries(java.lang.String, java.lang.String, int)
that doesn't involve classloaders so we can get resources from fixed path.static List<URL>
findEntries(org.osgi.framework.Bundle bundle, URL[] roots, String path, String pattern, boolean recurse)
ThirdfindEntries()
method - this one starts with an array of roots (which are for example JARs fromBundle-ClassPath
, but may be other "roots".static Set<org.osgi.framework.Bundle>
getBundlesInClassSpace(org.osgi.framework.Bundle bundle, Set<org.osgi.framework.Bundle> bundleSet)
Gets a list of bundles that are: imported by given bundle required by given bundle attached as fragments to given bundle extended by given bundlestatic URL[]
getClassPathJars(org.osgi.framework.Bundle bundle)
Deprecated.static URL[]
getClassPathJars(org.osgi.framework.Bundle bundle, boolean useClassSpace)
Returns a list of urls for jars that compose the Bundle-ClassPath and (withuseClassSpace
=true
) also a list of different URLs for bundles in class space (which includes bundles for imported packages, fragments, wires of fragments and required bundles).static URL[]
getClassPathNonJars(org.osgi.framework.Bundle bundle)
Returns a list of urls for all non-JAR entries that compose the Bundle-ClassPath.static URL[]
getClassPathURLs(org.osgi.framework.Bundle bundle)
Returns a list of urls for all entries that compose the Bundle-ClassPath.static List<URL>
getResources(Iterable<org.osgi.framework.Bundle> bundles, String path)
This method usesBundle.getResources(String)
that delegates to classloader.static URL[]
getURLs(ClassLoader loader)
Helper method to getClassLoader
s URLs (if possible)static boolean
jarClassPathEntryExists(URL root)
Checks whether jar: location exists as proper classpath elementstatic URL[]
jarToItsClassPath(URL url)
Used in tests, when there's only surefire on the classpathstatic List<URL>
listResources(Iterable<org.osgi.framework.Bundle> bundles, String path, String pattern, boolean recurse)
This method usesBundleWiring.listResources(java.lang.String, java.lang.String, int)
that delegates to classloader.
-
-
-
Method Detail
-
getClassPathJars
public static URL[] getClassPathJars(org.osgi.framework.Bundle bundle, boolean useClassSpace)
Returns a list of urls for jars that compose the Bundle-ClassPath and (with
useClassSpace
=true
) also a list of different URLs for bundles in class space (which includes bundles for imported packages, fragments, wires of fragments and required bundles).This method doesn't return the URL of passed bundle itself.
- Parameters:
bundle
- the bundle from which the class path should be takenuseClassSpace
- wheter to add also bundles reachable via different wires (required bundles, imported packages and fragments)- Returns:
- list or urls to jars that composes the Bundle-ClassPath. Each JAR is returned as URL in the form
jar:<location>!/
, where<location>
may be for examplebundle://30.0:0/WEB-INF/lib/myfaces-impl-2.2.12.jar
-
getClassPathURLs
public static URL[] getClassPathURLs(org.osgi.framework.Bundle bundle)
Returns a list of urls for all entries that compose the Bundle-ClassPath.
- Parameters:
bundle
-- Returns:
-
getClassPathNonJars
public static URL[] getClassPathNonJars(org.osgi.framework.Bundle bundle)
Returns a list of urls for all non-JAR entries that compose the Bundle-ClassPath.
- Parameters:
bundle
-- Returns:
-
getClassPathJars
@Deprecated public static URL[] getClassPathJars(org.osgi.framework.Bundle bundle)
Deprecated.Returns a list of urls to jars that composes the Bundle-ClassPath and also a list of different URLs for bundles in class space (which includes bundles for imported packages, fragments, wires of fragments and required bundles)- Parameters:
bundle
- the bundle from which the class path should be taken- Returns:
- list or urls to jars that composes the Bundle-ClassPath.
-
getBundlesInClassSpace
public static Set<org.osgi.framework.Bundle> getBundlesInClassSpace(org.osgi.framework.Bundle bundle, Set<org.osgi.framework.Bundle> bundleSet)
Gets a list of bundles that are:
- imported by given bundle
- required by given bundle
- attached as fragments to given bundle
- extended by given bundle
- Parameters:
bundle
-bundleSet
-- Returns:
-
listResources
public static List<URL> listResources(Iterable<org.osgi.framework.Bundle> bundles, String path, String pattern, boolean recurse)
This method uses
BundleWiring.listResources(java.lang.String, java.lang.String, int)
that delegates to classloader. If there are more visible resources with the same name, only one is returned.This method is not a good choice to discover manifests or e.g.,
faces-context.xml
files, if for single bundle many resources with the same path may be returned (as in case of WAR with Bundle-ClassPath or with fragments).This method is also not good choice to get
/META-INF/services/*
files, as these should be accessed using classloaders - aBundle
may have multiple entries on itsBundle-ClassPath
, so such service descriptors should be loaded from all the roots.- Parameters:
bundles
-path
-pattern
-recurse
-- Returns:
-
getResources
public static List<URL> getResources(Iterable<org.osgi.framework.Bundle> bundles, String path)
This method uses
Bundle.getResources(String)
that delegates to classloader. If there are more visible resources with the same name, all are returned (differently than withlistResources(java.lang.Iterable<org.osgi.framework.Bundle>, java.lang.String, java.lang.String, boolean)
).This method is the only choice to load resources using classloaders (respecting
Bundle-ClassPath
), and checking attached bundle fragments, but the problem is that it doesn't allow to use patterns.The important thing to note is that if the bundle is in INSTALLED state, there'll be an attempt to resolve it.
- Parameters:
bundles
-path
-- Returns:
-
findEntries
public static List<URL> findEntries(org.osgi.framework.Bundle bundle, String path, String pattern, boolean recurse, boolean useBundleClasspath) throws IOException
This method usesBundleWiring.findEntries(java.lang.String, java.lang.String, int)
that doesn't involve classloaders so we can get resources from fixed path. This way we can find multiple resources with the same path (when for example a bundle has attached fragment, which has the same entries). NormallyBundleWiring.findEntries(java.lang.String, java.lang.String, int)
doesn't check JARs listed onBundle-ClassPath
(because it doesn't work at classloader level), however we can explicitly tell it to do so.- Parameters:
bundle
-path
-pattern
-recurse
-useBundleClasspath
-- Returns:
- Throws:
IOException
-
findEntries
public static List<URL> findEntries(Iterable<org.osgi.framework.Bundle> bundles, String path, String pattern, boolean recurse, boolean useBundleClasspath) throws IOException
This method usesBundleWiring.findEntries(java.lang.String, java.lang.String, int)
that doesn't involve classloaders so we can get resources from fixed path. This way we can find multiple resources with the same path (when for example a bundle has attached fragment, which has the same entries). NormallyBundleWiring.findEntries(java.lang.String, java.lang.String, int)
doesn't check JARs listed onBundle-ClassPath
(because it doesn't work at classloader level), however we can explicitly tell it to do so.- Parameters:
bundles
-path
-pattern
-recurse
-useBundleClasspath
- additionally search the JARs on Bundle-ClassPath- Returns:
- Throws:
IOException
-
getURLs
public static URL[] getURLs(ClassLoader loader)
Helper method to getClassLoader
s URLs (if possible)- Parameters:
loader
-- Returns:
-
findEntries
public static List<URL> findEntries(ClassLoader loader, String path, String pattern, boolean recurse) throws IOException
This method matches
Bundle.findEntries(String, String, boolean)
but should be used when we don't have access to anyBundle
. It is used as a fallback in some resource-finding methods whenFrameworkUtil.getBundle(Class)
doesn't return anything (which may be a case in unit tests).This method is inspired by Spring's
org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindAllClassPathResources()
where the most important problem of""
resource base was cleverly solved. Though we won't traverse up the classloader parents and we won't checkClassLoader.getSystemResources(String)
.Spring's
org.springframework.core.io.support.PathMatchingResourcePatternResolver#getResources()
allows passing argument likeclasspath*:/META-INF/** /*.tld
(ANT-style), howeverorg.springframework.util.AntPathMatcher#doMatch()
is a bit complicated and very different fromBundle.findEntries(String, String, boolean)
, so we'll just test the entry for:- begins with
path
- ends (or matches)
pattern
, where the patterns is simple glob (*
and?
supported). /META-INF/tlds/my.tld
should NOT match whenpath=/META-INF/tlds
andpattern=tlds/*.tld
- Parameters:
loader
-path
- never a pattern. Should indicate the base used for relative path searching and is always treated as base directorypattern
- file pattern (only for matching last path segment == no slashes) to match. If this pattern isnull
, we assume*
which means directory listing in the base pathrecurse
- whether we should look at any depth or only withinpath
- Returns:
- Throws:
IOException
- begins with
-
jarToItsClassPath
public static URL[] jarToItsClassPath(URL url) throws IOException
Used in tests, when there's only surefire on the classpath- Parameters:
url
-- Returns:
- Throws:
IOException
-
findEntries
public static List<URL> findEntries(org.osgi.framework.Bundle bundle, URL[] roots, String path, String pattern, boolean recurse) throws IOException
ThirdfindEntries()
method - this one starts with an array of roots (which are for example JARs fromBundle-ClassPath
, but may be other "roots".- Parameters:
bundle
- the bundle from where the roots come from. It's needed if extracting a directory entry from a bundleroots
- URLs that should end with "/" (jar: URLs should end with "!/")path
-pattern
-recurse
-- Returns:
- Throws:
IOException
-
jarClassPathEntryExists
public static boolean jarClassPathEntryExists(URL root)
Checks whether jar: location exists as proper classpath element- Parameters:
root
-- Returns:
-
-