diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECoreMessages.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECoreMessages.java index 87ea1ba11b..bb011c0a6c 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECoreMessages.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECoreMessages.java @@ -261,6 +261,8 @@ public class PDECoreMessages extends NLS { public static String BuildErrorReporter_BuildEntryNotRequiredMatchesDefault; + public static String BuildErrorReporter_classpathAccessRulesDiscarded; + public static String BuildErrorReporter_sourceMissing; public static String BuildErrorReporter_srcIncludesSourceFolder; diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/BuildErrorReporter.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/BuildErrorReporter.java index 1c196749a7..194bdfce88 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/BuildErrorReporter.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/BuildErrorReporter.java @@ -162,6 +162,10 @@ public void addAttributes(Map attributes) { protected int fSrcLibSeverity; protected int fOutputLibSeverity; protected int fEncodingSeverity; + protected int fJDCTClasspathMissconfigurationSeverity = Boolean + .getBoolean("pde.acceptDiscardedForbiddenAccessRules") //$NON-NLS-1$ + ? CompilerFlags.WARNING + : CompilerFlags.ERROR; public BuildErrorReporter(IFile buildFile) { super(buildFile); @@ -1108,6 +1112,13 @@ private void validateJavaCompilerSettings(IBuildEntry useJavaProjectSettings) { String message = NLS.bind(PDECoreMessages.BuildErrorReporter_buildEntryInvalidWhenNoProjectSettings, PROPERTY_PROJECT_SETTINGS); prepareCompilerError(PROPERTY_PROJECT_SETTINGS, null, message, PDEMarkerFactory.B_REMOVAL); } + + String forbiddenReferenceSeverity = options.get(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE); + if (forbiddenReferenceSeverity != null && !forbiddenReferenceSeverity.equals(JavaCore.ERROR)) { + String message = NLS.bind(PDECoreMessages.BuildErrorReporter_classpathAccessRulesDiscarded); + prepareError(null, null, message, PDEMarkerFactory.B_CLASSPATH_ACCESS_RULES, + fJDCTClasspathMissconfigurationSeverity, null, PDEMarkerFactory.CAT_OTHER); + } } } diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java index 8cd0f6a57f..3be5682b78 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java @@ -91,6 +91,7 @@ public class PDEMarkerFactory { public static final int B_REMOVAL = 0x2005; public static final int B_REPLACE = 0x2006; public static final int B_JAVA_ADDDITION = 0x2007; + public static final int B_CLASSPATH_ACCESS_RULES = 0x2008; // plugin.xml fixes public static final int P_ILLEGAL_XML_NODE = 0x3001; diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/pderesources.properties b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/pderesources.properties index 396e968f69..258cf5fd51 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/pderesources.properties +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/pderesources.properties @@ -103,6 +103,7 @@ BuildErrorReporter_buildEntryMissingProjectSpecificSettings=The ''{0}'' build en BuildErrorReporter_buildEntryMissingValidPath=The ''{0}'' build entry does not contain ''true'' or a path to an existing properties file BuildErrorReporter_buildEntryMissingValidRelativePath=The ''{0}'' build entry does not contain a path to an existing properties file BuildErrorReporter_BuildEntryNotRequiredMatchesDefault=The ''{0}'' build entry is not required because it matches the default value +BuildErrorReporter_classpathAccessRulesDiscarded=OSGi access rules not enforced by classpath access rules, which can lead to classloading errors at runtime. BuildErrorReporter_entiresMustRefDirs={0}: entries ending in / must reference directories Builders_Manifest_deprecated_rootElement = The extension point ''{0}'' is deprecated BuildErrorReporter_classpathEntryMissing={0} is not included in any "source.*" build entry diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java index 5f3aaabb7e..53ef7e5b75 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java @@ -3461,5 +3461,6 @@ public class PDEUIMessages extends NLS { public static String AddMatchingVersion; public static String AddMatchingVersionDescription; + public static String EnableStrictClasspathAccessRules_label; } diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/EnforceForbiddenAccessClasspathRules.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/EnforceForbiddenAccessClasspathRules.java new file mode 100644 index 0000000000..c5cf7fdb25 --- /dev/null +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/EnforceForbiddenAccessClasspathRules.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2026 Hannes Wellmann 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 + * + * Contributors: + * Hannes Wellmann - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.internal.ui.correction; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.pde.core.IBaseModel; +import org.eclipse.pde.internal.ui.PDEUIMessages; +import org.osgi.service.prefs.BackingStoreException; + +public class EnforceForbiddenAccessClasspathRules extends AbstractPDEMarkerResolution { + + public EnforceForbiddenAccessClasspathRules(IMarker marker) { + super(AbstractPDEMarkerResolution.CONFIGURE_TYPE, marker); + } + + @Override + public String getLabel() { + return PDEUIMessages.EnableStrictClasspathAccessRules_label; + } + + @Override + public void run(IMarker marker) { + IProject project = marker.getResource().getProject(); + IEclipsePreferences node = new ProjectScope(project).getNode("org.eclipse.jdt.core"); //$NON-NLS-1$ + try { + node.sync(); + node.put(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, JavaCore.ERROR); + node.flush(); + } catch (BackingStoreException e) { + ILog.get().error("Failed to update JDT Core preferences", e); //$NON-NLS-1$ + } + } + + @Override + protected void createChange(IBaseModel model) { + // handled by run + } +} + diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java index c8b92a5c01..4e825bb5e1 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java @@ -117,6 +117,8 @@ public IMarkerResolution[] getNonConfigSevResolutions(IMarker marker) { return new IMarkerResolution[] {new RemoveBuildEntryResolution(AbstractPDEMarkerResolution.REMOVE_TYPE, marker)}; case PDEMarkerFactory.B_REPLACE : return new IMarkerResolution[] {new ReplaceBuildEntryResolution(AbstractPDEMarkerResolution.RENAME_TYPE, marker)}; + case PDEMarkerFactory.B_CLASSPATH_ACCESS_RULES: + return new IMarkerResolution[] { new EnforceForbiddenAccessClasspathRules(marker) }; case PDEMarkerFactory.P_ILLEGAL_XML_NODE : return new IMarkerResolution[] {new RemoveNodeXMLResolution(AbstractPDEMarkerResolution.REMOVE_TYPE, marker)}; case PDEMarkerFactory.P_UNTRANSLATED_NODE : diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties index 625bed6eb4..943f15b7b2 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties @@ -1310,6 +1310,7 @@ UpdateClasspathJob_task = Update classpaths... UpdateClasspathJob_title = Updating Plug-in Classpaths AddMatchingVersion = Require latest available version range AddMatchingVersionDescription = Add a version range aligned with the latest compatible available version +EnableStrictClasspathAccessRules_label=Enable strict enforcement of classpath access rules RuntimeWorkbenchShortcut_title=Select Configuration RuntimeWorkbenchShortcut_select_debug=Select a launch configuration to debug: