Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multi-release processing support #5350

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
76 changes: 51 additions & 25 deletions biz.aQute.bndlib/src/aQute/bnd/osgi/Analyzer.java
Expand Up @@ -200,12 +200,13 @@ public static Properties getManifest(File dirOrJar) throws Exception {
*/
public void analyze() throws Exception {
if (!analyzed) {
int release = getRelease();
analyzed = true;
analyzeContent();
analyzeContent(release);

// Execute any plugins
// TODO handle better reanalyze
doPlugins();
doPlugins(release);

//
// calculate class versions in use
Expand Down Expand Up @@ -293,7 +294,7 @@ public void analyze() throws Exception {
getHostPackages().ifPresent(hostPackages -> referredAndExported.keySet()
.removeAll(hostPackages));

getRequireBundlePackages().ifPresent(hostPackages -> referredAndExported.keySet()
getRequireBundlePackages(release).ifPresent(hostPackages -> referredAndExported.keySet()
.removeAll(hostPackages));

String h = getProperty(IMPORT_PACKAGE);
Expand Down Expand Up @@ -423,6 +424,19 @@ public void analyze() throws Exception {
}
}

private int getRelease() {
String property = getProperty(JAVA_RELEASE);
if (property != null) {
try {
return Integer.parseInt(property.trim());
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
JAVA_RELEASE + " must be a valid integer but was " + property + " (" + e.getMessage() + ")", e);
}
}
return -1;
}

private void reset() {
contained.clear();
classspace.clear();
Expand All @@ -436,10 +450,10 @@ private void reset() {
bcpTypes.clear();
}

private void analyzeContent() throws Exception {
private void analyzeContent(int release) throws Exception {
// Parse all the classes in the
// the jar according to the OSGi Bundle-ClassPath
analyzeBundleClasspath();
analyzeBundleClasspath(release);

//
// Get exported packages from the
Expand All @@ -448,9 +462,10 @@ private void analyzeContent() throws Exception {
//

for (Jar current : getClasspath()) {
getManifestInfoFromClasspath(current, classpathExports, contracts);
getManifestInfoFromClasspath(current, classpathExports, contracts, release);

Manifest m = current.getManifest();
Manifest m = current.getManifest(release)
.orElse(null);
if (m == null) {
for (String dir : current.getDirectories()
.keySet()) {
Expand All @@ -472,7 +487,7 @@ private void analyzeContent() throws Exception {

// Conditional packages

doConditionalPackages();
doConditionalPackages(release);
}

/**
Expand Down Expand Up @@ -504,7 +519,12 @@ public Optional<Set<PackageRef>> getHostPackages() {
* @return the packages from the required bundles, with no Require-Bundle
* return an empty Optional
*/

public Optional<Set<PackageRef>> getRequireBundlePackages() {
return getRequireBundlePackages(Jar.MULTI_RELEASE_DEFAULT_VERSION);
}

public Optional<Set<PackageRef>> getRequireBundlePackages(int release) {

Parameters required = getRequireBundle();
if (required.isEmpty())
Expand All @@ -514,7 +534,8 @@ public Optional<Set<PackageRef>> getRequireBundlePackages() {
.stream()
.map(this::toJar)
.filter(Objects::nonNull)
.map(asFunctionOrElse(Jar::getManifest, null))
.map(asFunctionOrElse(jar -> jar.getManifest(release)
.orElse(null), null))
.filter(Objects::nonNull)
.flatMap(manifest -> {
Domain domain = Domain.domain(manifest);
Expand Down Expand Up @@ -625,7 +646,7 @@ public Clazz getPackageInfo(PackageRef packageRef) {
}
}

private void doConditionalPackages() throws Exception {
private void doConditionalPackages(int release) throws Exception {
//
// We need to find out the contained packages
// again ... so we need to clear any visited
Expand All @@ -636,7 +657,7 @@ private void doConditionalPackages() throws Exception {

for (Jar extra; (extra = getExtra()) != null;) {
dot.addAll(extra);
analyzeJar(extra, "", true, null);
analyzeJar(extra, "", true, null, release);
}
}

Expand Down Expand Up @@ -980,8 +1001,10 @@ protected Jar getExtra() throws Exception {

/**
* Call AnalyzerPlugins to analyze the content.
*
* @param release the release flag for that content should be analyzed
*/
private void doPlugins() {
private void doPlugins(int release) {
List<AnalyzerPlugin> plugins = getPlugins(AnalyzerPlugin.class);
plugins.sort(Comparator.comparingInt(AnalyzerPlugin::ordering));
for (AnalyzerPlugin plugin : plugins) {
Expand All @@ -1000,7 +1023,7 @@ private void doPlugins() {
.filterValue(Objects::nonNull)
.collect(MapStream.toMap());
reset();
analyzeContent();
analyzeContent(release);
// Restore -internal-source information
// if the package still exists
sourceInformation.forEach((pkgRef, source) -> {
Expand Down Expand Up @@ -1913,10 +1936,11 @@ public boolean referred(PackageRef packageName) {
return result;
}

private void getManifestInfoFromClasspath(Jar jar, Packages classpathExports, Contracts contracts) {
private void getManifestInfoFromClasspath(Jar jar, Packages classpathExports, Contracts contracts, int release) {
logger.debug("get Manifest Info From Classpath for {}", jar);
try {
Manifest m = jar.getManifest();
Manifest m = jar.getManifest(release)
.orElse(null);
if (m != null) {
Domain domain = Domain.domain(m);
Parameters exported = domain.getExportPackage();
Expand Down Expand Up @@ -2577,11 +2601,11 @@ public Jar getTarget() {
return getJar();
}

private void analyzeBundleClasspath() throws Exception {
private void analyzeBundleClasspath(int release) throws Exception {
Parameters bcp = getBundleClasspath();

if (bcp.isEmpty()) {
analyzeJar(dot, "", true, null);
analyzeJar(dot, "", true, null, release);
} else {
// Cleanup entries
bcp = bcp.stream()
Expand All @@ -2593,7 +2617,7 @@ private void analyzeBundleClasspath() throws Exception {

for (String path : bcp.keySet()) {
if (path.equals(".")) {
analyzeJar(dot, "", okToIncludeDirs, null);
analyzeJar(dot, "", okToIncludeDirs, null, release);
continue;
}
//
Expand All @@ -2610,7 +2634,7 @@ private void analyzeBundleClasspath() throws Exception {
if (!(resource instanceof JarResource)) {
addClose(jar);
}
analyzeJar(jar, "", true, path);
analyzeJar(jar, "", true, path, release);
} catch (Exception e) {
warning("Invalid bundle classpath entry: %s: %s", path, e);
}
Expand All @@ -2623,7 +2647,7 @@ private void analyzeBundleClasspath() throws Exception {
warning(Constants.BUNDLE_CLASSPATH
+ " uses a directory '%s' as well as '.'. This means bnd does not know if a directory is a package.",
path);
analyzeJar(dot, path.concat("/"), true, path);
analyzeJar(dot, path.concat("/"), true, path, release);
} else {
Attrs info = bcp.get(path);
if (!"optional".equals(info.get(RESOLUTION_DIRECTIVE)))
Expand All @@ -2639,16 +2663,19 @@ private void analyzeBundleClasspath() throws Exception {
* contained and referred set and uses. This method ignores the Bundle
* classpath.
*/
private boolean analyzeJar(Jar jar, String prefix, boolean okToIncludeDirs, String bcpEntry) throws Exception {
private boolean analyzeJar(Jar jar, String prefix, boolean okToIncludeDirs, String bcpEntry, int release)
throws Exception {
Map<String, Clazz> mismatched = new HashMap<>();

Parameters importPackage = Optional.ofNullable(jar.getManifest())
Parameters importPackage = jar.getManifest(release)
.map(Domain::domain)
.map(Domain::getImportPackage)
.orElseGet(() -> new Parameters());

next: for (String path : jar.getResources()
.keySet()) {
Map<String, Resource> resources = jar.getVersionedResources(release);
next: for (Entry<String, Resource> entry : resources.entrySet()) {
String path = entry.getKey();
Resource resource = entry.getValue();
if (path.startsWith(prefix)) {

String relativePath = path.substring(prefix.length());
Expand All @@ -2665,7 +2692,6 @@ private boolean analyzeJar(Jar jar, String prefix, boolean okToIncludeDirs, Stri

// Check class resources, we need to analyze them
if (path.endsWith(".class")) {
Resource resource = jar.getResource(path);
Clazz clazz;

try {
Expand Down
3 changes: 2 additions & 1 deletion biz.aQute.bndlib/src/aQute/bnd/osgi/Constants.java
Expand Up @@ -293,6 +293,7 @@ public interface Constants {
String WORKINGSET = "-workingset";
String WORKINGSET_MEMBER = "member";
String REQUIRE_BND = "-require-bnd";
String JAVA_RELEASE = "-release";

// Deprecated
String CLASSPATH = "-classpath";
Expand All @@ -314,7 +315,7 @@ public interface Constants {
CONNECTION_SETTINGS, RUNPROVIDEDCAPABILITIES, WORKINGSET, RUNSTORAGE, REPRODUCIBLE, INCLUDEPACKAGE,
CDIANNOTATIONS, REMOTEWORKSPACE, MAVEN_DEPENDENCIES, BUILDERIGNORE, STALECHECK, MAVEN_SCOPE, RUNSTARTLEVEL,
RUNOPTIONS, NOCLASSFORNAME, EXPORT_APIGUARDIAN, RESOLVE, DEFINE_CONTRACT, GENERATE, RUNFRAMEWORKRESTART,
NOIMPORTJAVA, VERSIONDEFAULTS, LIBRARY);
NOIMPORTJAVA, VERSIONDEFAULTS, LIBRARY, JAVA_RELEASE);

// Ignore bundle specific headers. These headers do not make a lot of sense
// to inherit
Expand Down