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

Quick-fix for Import-Package resolution failure due to missing mandatory attributes #678

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class PDECoreMessages extends NLS {

public static String BuildErrorReporter_cannotFindJar;

public static String BundleErrorReporter_MissingMandatoryDirective;

public static String BundleErrorReporter_ConflictingAutoModule;

public static String BundleErrorReporter_badFilter;
Expand Down Expand Up @@ -247,6 +249,10 @@ public class PDECoreMessages extends NLS {

public static String ManifestConsistencyChecker_buildPropertiesSubtask;

public static String AddMandatoryAttrResolution_label;

public static String AddMandatoryAttrResolution_description;

public static String BuildErrorReporter_missingEntry;
public static String BuildErrorReporter_missingFolder;
public static String BuildErrorReporter_emptyEntry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Deque;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
Expand All @@ -34,6 +34,7 @@
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
Expand All @@ -56,6 +57,7 @@
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
import org.eclipse.osgi.service.resolver.BaseDescription;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.BundleSpecification;
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
Expand Down Expand Up @@ -136,7 +138,7 @@
if (desc == null && fModel.getInstallLocation() != null) {
// There was a problem creating the OSGi bundle description, possibly a bad header
try {
StateObjectFactory stateObjectFactory = Platform.getPlatformAdmin().getFactory();

Check warning on line 141 in ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/BundleErrorReporter.java

View check run for this annotation

Jenkins - eclipse-pde / Compiler and API Tools

Deprecation

NORMAL: The method getPlatformAdmin() from the type Platform has been deprecated and marked for removal
File bundleLocation = new File(fModel.getInstallLocation());
Map<String, String> manifest = ManifestUtils.loadManifest(bundleLocation);
TargetWeaver.weaveManifest(manifest, bundleLocation);
Expand Down Expand Up @@ -1172,7 +1174,7 @@
}
}

HashMap<String, ExportPackageDescription> exported = getAvailableExportedPackages(desc.getContainingState());
Map<String, List<ExportPackageDescription>> exported = getAvailableExportedPackages(desc.getContainingState());

ImportPackageSpecification[] imports = desc.getImportPackages();
if (desc.hasDynamicImports()) {
Expand Down Expand Up @@ -1210,8 +1212,10 @@
boolean optional = isOptional(element);
int severity = getRequireBundleSeverity(element, optional);

ExportPackageDescription export = exported.get(name);
if (export != null) {
List<ExportPackageDescription> exports = exported.getOrDefault(name, List.of());
if (!exports.isEmpty()) {
exports.sort(RESOLVED_FIRST);
for (ExportPackageDescription export : exports) {
if (export.getSupplier().isResolved()) {
Version version = export.getVersion();
org.eclipse.osgi.service.resolver.VersionRange range = importSpec.getVersionRange();
Expand All @@ -1220,18 +1224,47 @@
addMarkerAttribute(marker,PDEMarkerFactory.compilerKey,CompilerFlags.P_UNRESOLVED_IMPORTS);
return;
}
String[] mandatoryAttributes = (String[]) export.getDirective(Constants.RESOLUTION_MANDATORY);
if (mandatoryAttributes != null) {
Map<String, Object> exportAttributes = export.getAttributes();
Map<String, Object> importAttributes = importSpec.getAttributes();
for (String mandatory : mandatoryAttributes) {
Object exportValue = exportAttributes != null ? exportAttributes.get(mandatory) : null;
Object importValue = importAttributes != null ? importAttributes.get(mandatory) : null;

if (importValue == null || !importValue.equals(exportValue)) {
VirtualMarker marker = report(
NLS.bind(PDECoreMessages.BundleErrorReporter_MissingMandatoryDirective,
new String[] { name, mandatory, export.getExporter().getName() }),
getPackageLine(header, element), severity,
PDEMarkerFactory.M_NO_MANDATORY_ATTR_IMPORT_PACKAGE,
PDEMarkerFactory.CAT_FATAL);
addMarkerAttribute(marker, PDEMarkerFactory.compilerKey,
CompilerFlags.P_UNRESOLVED_IMPORTS);

if (marker != null) {
marker.setAttribute("packageName", name); //$NON-NLS-1$
marker.setAttribute("mandatoryAttrName", mandatory); //$NON-NLS-1$
marker.setAttribute("mandatoryAttrValue", exportValue); //$NON-NLS-1$
}
}
}
}
} else {
VirtualMarker marker = report(NLS.bind(PDECoreMessages.BundleErrorReporter_unresolvedExporter,new String[] { export.getSupplier().getSymbolicName(), name }),getPackageLine(header, element), severity, PDEMarkerFactory.CAT_OTHER);
addMarkerAttribute(marker,PDEMarkerFactory.compilerKey, CompilerFlags.P_UNRESOLVED_IMPORTS);
return;
}
}
return;
}

VirtualMarker marker = report(NLS.bind(PDECoreMessages.BundleErrorReporter_PackageNotExported, name),
getPackageLine(header, element), severity, PDEMarkerFactory.M_IMPORT_PKG_NOT_AVAILABLE,
PDEMarkerFactory.CAT_FATAL);
addMarkerAttribute(marker, PDEMarkerFactory.compilerKey, CompilerFlags.P_UNRESOLVED_IMPORTS);
if (marker != null) {
// marker.setAttribute(PDEMarkerFactory.M_NO_MANDATORY_ATTR_IMPORT_PACKAGE);
marker.setAttribute("packageName", name); //$NON-NLS-1$
if (optional) {
marker.setAttribute("optional", true); //$NON-NLS-1$
Expand All @@ -1241,24 +1274,13 @@
}
}

private HashMap<String, ExportPackageDescription> getAvailableExportedPackages(State state) {
BundleDescription[] bundles = state.getBundles();
private static final Comparator<BaseDescription> RESOLVED_FIRST = Comparator
.comparing((BaseDescription d) -> d.getSupplier().isResolved()).reversed(); // false<true

HashMap<String, ExportPackageDescription> exported = new HashMap<>();
for (BundleDescription bundle : bundles) {
ExportPackageDescription[] exports = bundle.getExportPackages();
for (ExportPackageDescription export : exports) {
String name = export.getName();
if (exported.containsKey(name)) {
if (export.getSupplier().isResolved()) {
exported.put(name, export);
}
} else {
exported.put(name, export);
}
}
}
return exported;
private Map<String, List<ExportPackageDescription>> getAvailableExportedPackages(State state) {
BundleDescription[] bundles = state.getBundles();
return Arrays.stream(bundles).map(b -> b.getExportPackages()).flatMap(Arrays::stream)
.collect(Collectors.groupingBy(BaseDescription::getName, Collectors.toCollection(ArrayList::new)));
}

protected void validateExportPackage(IProgressMonitor monitor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ public class PDEMarkerFactory {
public static final int M_EXEC_ENV_TOO_LOW = 0x1029; // other problem
public static final int M_CONFLICTING_AUTOMATIC_MODULE = 0x1030; // other
// problem

public static final int M_NO_MANDATORY_ATTR_IMPORT_PACKAGE = 0x1031; // fatal
// problem
// build properties fixes
public static final int B_APPEND_SLASH_FOLDER_ENTRY = 0x2001;
public static final int B_REMOVE_SLASH_FILE_ENTRY = 0x2002;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ BuildErrorReporter_CompilercomplianceLevel=Compiler compliance level
Builders_Manifest_key_not_found = Key ''{0}'' is not found in localization properties file: {1}
Builders_Manifest_useless_file = A plug-in manifest must contain at least one extension or extension point
BuildErrorReporter_missingEntry = ''{0}'' build entry is missing
AddMandatoryAttrResolution_label=Adds mandatory attribute ''{0}'' with value ''{1}''
AddMandatoryAttrResolution_description=Add mandatory attribute value
BundleErrorReporter_MissingMandatoryDirective=The imported package ''{0}'' is missing the mandatory attribute ''{1}'' with a exported value from ''{2}'' bundle

Builders_Convert_missingAttribute = ''{0}'' attribute is missing
Builders_Convert_illegalValue = Illegal value for ''{0}'' attribute
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*******************************************************************************
* Copyright (c) 2023 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*Qui
* Contributors:
* IBM Corporation - initial API and implementation
* Alshama M S <ALSHAMA.M.S@ibm.com> Initial implementation
*******************************************************************************/

package org.eclipse.pde.internal.ui.correction;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.internal.core.PDECoreMessages;
import org.eclipse.pde.internal.core.text.bundle.Bundle;
import org.eclipse.pde.internal.core.text.bundle.BundleModel;
import org.eclipse.pde.internal.core.text.bundle.ImportPackageHeader;
import org.eclipse.pde.internal.core.text.bundle.ImportPackageObject;
import org.eclipse.pde.internal.ui.PDEPlugin;
import org.osgi.framework.Constants;

/**
* <p>
* Represents a resolution to the problem of import package resolution failure
* due to missing mandatory attributes
* </p>
*/
public class AddMandatoryAttributeImportPackageResolution extends AbstractManifestMarkerResolution {
/**
* Creates a new resolution
*/
public AddMandatoryAttributeImportPackageResolution(IMarker marker) {
super(AbstractPDEMarkerResolution.CREATE_TYPE, marker);
}

/**
* Resolves the problem by adding mandatory attribute
*/
@Override
protected void createChange(BundleModel model) {
try {
String packagename = (String) marker.getAttribute("packageName"); //$NON-NLS-1$
Bundle bundle = (Bundle) model.getBundle();
ImportPackageHeader header = (ImportPackageHeader) bundle.getManifestHeader(Constants.IMPORT_PACKAGE);
if (header != null) {
ImportPackageObject obj = header.getPackage(packagename);
obj.setAttribute(getAttributeName(), getAttributeValue());
header.update(true);
}
} catch (CoreException e) {
PDEPlugin.log(e);
}
}

private String getAttributeValue() throws CoreException {
return (String) marker.getAttribute("mandatoryAttrValue"); //$NON-NLS-1$
}

private String getAttributeName() throws CoreException {
return (String) marker.getAttribute("mandatoryAttrName"); //$NON-NLS-1$
}

@Override
public String getDescription() {
try {
return NLS.bind(PDECoreMessages.AddMandatoryAttrResolution_label, getAttributeName(), getAttributeValue());
} catch (CoreException e) {
PDEPlugin.log(e);
return NLS.bind(PDECoreMessages.AddMandatoryAttrResolution_label, "", ""); //$NON-NLS-1$//$NON-NLS-2$
}
}

@Override
public String getLabel() {
return PDECoreMessages.AddMandatoryAttrResolution_description;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ public IMarkerResolution[] getNonConfigSevResolutions(IMarker marker) {
return new IMarkerResolution[] {new NoLineTerminationResolution(AbstractPDEMarkerResolution.REMOVE_TYPE, marker)};
case PDEMarkerFactory.M_R4_SYNTAX_IN_R3_BUNDLE :
return new IMarkerResolution[] {new AddBundleManifestVersionResolution(marker)};
case PDEMarkerFactory.M_NO_MANDATORY_ATTR_IMPORT_PACKAGE:
return new IMarkerResolution[] { new AddMandatoryAttributeImportPackageResolution(marker) };
case PDEMarkerFactory.M_SERVICECOMPONENT_MISSING_LAZY:
return new IMarkerResolution[] {
new AddActivationPolicyResolution(AbstractPDEMarkerResolution.CREATE_TYPE, marker) };
Expand Down
Loading