diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27d95ab71a3..d1fbf93f0d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,7 +68,7 @@ jobs: -Dequinox.binaries.loc=${{ github.workspace }}/equinox.binaries clean verify - name: Upload native artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: success() with: name: ${{ matrix.config.name }} launcher artifacts @@ -77,7 +77,7 @@ jobs: equinox.binaries/org.eclipse.equinox.launcher.${{ matrix.config.ws }}.${{ matrix.config.os }}.x86_64/eclipse_*.${{ matrix.config.native-extension }} if-no-files-found: error - name: Upload ${{ matrix.config.name }} Test Results - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: test-results-${{ matrix.config.name }}64 if-no-files-found: error @@ -118,7 +118,7 @@ jobs: -fn clean verify - name: Upload TCK Results - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: always() with: name: tck-results @@ -129,7 +129,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Upload - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: Event File path: ${{ github.event_path }} diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f4f4b9a98b1..8e0428dc067 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -106,7 +106,7 @@ jobs: ;; esac - name: Create badge of ${{ matrix.tck.name }} - uses: emibcn/badge-action@808173dd03e2f30c980d03ee49e181626088eee8 + uses: emibcn/badge-action@f9150fde070fcca0c4e832437611b44838fcd325 with: # label: ${{ matrix.tck.chapter }} - ${{ matrix.tck.label }} ${{ matrix.tck.suffix }} label: '${{ fromJSON( steps.test-results.outputs.json ).formatted.stats.tests }} tests' diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml index 1bea74fa702..27b350875b6 100644 --- a/.mvn/extensions.xml +++ b/.mvn/extensions.xml @@ -3,6 +3,6 @@ org.eclipse.tycho tycho-build - 5.0.1 + 5.0.2 diff --git a/Jenkinsfile b/Jenkinsfile index b716b34f574..988c9a85800 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -15,6 +15,11 @@ def runOnNativeBuildAgent(String platform, Closure body) { def final nativeBuildStageName = 'Perform native launcher build' + // Use x86 agent for aarch64 build to ensure that the baseline macOS SDK (the oldest) is used consistently for all binary builds + if (platform == 'cocoa.macosx.aarch64') { + platform = 'cocoa.macosx.x86_64' + } + def agentLabel = 'native.builder-' + platform if (platform == 'gtk.linux.x86_64') { podTemplate(inheritFrom: 'basic' /* inherit general configuration */, containers: [ containerTemplate(name: 'launcherbuild', image: 'eclipse/platformreleng-debian-swtgtk3nativebuild:10', @@ -25,12 +30,9 @@ def runOnNativeBuildAgent(String platform, Closure body) { node(POD_LABEL) { stage(nativeBuildStageName) { container('launcherbuild') { body() } } } } } else { - if (platform == 'cocoa.macosx.x86_64') { - platform = 'cocoa.macosx.aarch64' - } // See the Definition of the RelEng Jenkins instance in // https://github.com/eclipse-cbi/jiro/tree/master/instances/eclipse.platform.releng - node('native.builder-' + platform) { stage(nativeBuildStageName) { body() } } + node(agentLabel) { stage(nativeBuildStageName) { body() } } } } diff --git a/bundles/org.eclipse.equinox.concurrent/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.concurrent/.settings/org.eclipse.jdt.core.prefs index f9198ba838e..4e4ae8f26d8 100644 --- a/bundles/org.eclipse.equinox.concurrent/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.eclipse.equinox.concurrent/.settings/org.eclipse.jdt.core.prefs @@ -9,6 +9,7 @@ org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled org.eclipse.jdt.core.compiler.source=17 diff --git a/bundles/org.eclipse.equinox.concurrent/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.concurrent/META-INF/MANIFEST.MF index 0c16d3ad898..33d6b430724 100644 --- a/bundles/org.eclipse.equinox.concurrent/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.concurrent/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.equinox.concurrent -Bundle-Version: 1.3.400.qualifier +Bundle-Version: 1.3.500.qualifier Bundle-Vendor: %pluginProvider Bundle-RequiredExecutionEnvironment: JavaSE-17 Import-Package: org.eclipse.core.runtime;common=split;version="3.4.0" diff --git a/bundles/org.eclipse.equinox.console.jaas.fragment/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.console.jaas.fragment/.settings/org.eclipse.jdt.core.prefs index e8e7adda28a..7ec4d72abe9 100644 --- a/bundles/org.eclipse.equinox.console.jaas.fragment/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.eclipse.equinox.console.jaas.fragment/.settings/org.eclipse.jdt.core.prefs @@ -5,6 +5,7 @@ org.eclipse.jdt.core.compiler.compliance=17 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled org.eclipse.jdt.core.compiler.source=17 diff --git a/bundles/org.eclipse.equinox.console.jaas.fragment/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.console.jaas.fragment/META-INF/MANIFEST.MF index 56d869777fc..6cfad9279a1 100644 --- a/bundles/org.eclipse.equinox.console.jaas.fragment/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.console.jaas.fragment/META-INF/MANIFEST.MF @@ -4,7 +4,7 @@ Bundle-Name: %bundleName Bundle-Vendor: %bundleVendor Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.equinox.console.jaas.fragment -Bundle-Version: 1.2.100.qualifier +Bundle-Version: 1.2.200.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 DynamicImport-Package: org.eclipse.equinox.console.jaas Fragment-Host: org.apache.sshd.osgi;bundle-version="2.2.0" diff --git a/bundles/org.eclipse.equinox.http.service.api/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.http.service.api/.settings/org.eclipse.jdt.core.prefs index 9f6ece88bdf..2d98c1a047d 100644 --- a/bundles/org.eclipse.equinox.http.service.api/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.eclipse.equinox.http.service.api/.settings/org.eclipse.jdt.core.prefs @@ -4,5 +4,6 @@ org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error org.eclipse.jdt.core.compiler.release=disabled org.eclipse.jdt.core.compiler.source=1.8 diff --git a/bundles/org.eclipse.equinox.http.service.api/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.http.service.api/META-INF/MANIFEST.MF index f7d21f721af..5e71e56df76 100644 --- a/bundles/org.eclipse.equinox.http.service.api/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.http.service.api/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: OSGi service http APIs Bundle-SymbolicName: org.eclipse.equinox.http.service.api -Bundle-Version: 1.2.102.qualifier +Bundle-Version: 1.2.202.qualifier Bundle-Vendor: Eclipse.org - Equinox Automatic-Module-Name: org.eclipse.equinox.http.service.api Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/bundles/org.eclipse.equinox.launcher.cocoa.macosx.aarch64/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.launcher.cocoa.macosx.aarch64/META-INF/MANIFEST.MF index 5a4639dfbcb..c240119147f 100644 --- a/bundles/org.eclipse.equinox.launcher.cocoa.macosx.aarch64/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.launcher.cocoa.macosx.aarch64/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.equinox.launcher.cocoa.macosx.aarch64;singleton:=true -Bundle-Version: 1.2.1400.qualifier +Bundle-Version: 1.2.1500.qualifier Fragment-Host: org.eclipse.equinox.launcher;bundle-version="[1.7.0,1.8.0)" Eclipse-PlatformFilter: (& (osgi.ws=cocoa) (osgi.os=macosx) (osgi.arch=aarch64) ) Bundle-Localization: launcher.cocoa.macosx.aarch64 diff --git a/bundles/org.eclipse.equinox.launcher.cocoa.macosx.aarch64/build.properties b/bundles/org.eclipse.equinox.launcher.cocoa.macosx.aarch64/build.properties index 5e45c16a351..8f1943387a6 100644 --- a/bundles/org.eclipse.equinox.launcher.cocoa.macosx.aarch64/build.properties +++ b/bundles/org.eclipse.equinox.launcher.cocoa.macosx.aarch64/build.properties @@ -16,7 +16,7 @@ bin.includes = META-INF/,\ about.html generateSourceBundle=false -binaryTag=LBv1-1916 +binaryTag=LBv1-1921 # Maven properties, see https://github.com/eclipse/tycho/wiki/Tycho-Pomless tycho.pomless.parent = ../../launcher-binary-parent diff --git a/bundles/org.eclipse.equinox.launcher.cocoa.macosx.x86_64/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.launcher.cocoa.macosx.x86_64/META-INF/MANIFEST.MF index 056ee170bdd..094872d3236 100644 --- a/bundles/org.eclipse.equinox.launcher.cocoa.macosx.x86_64/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.launcher.cocoa.macosx.x86_64/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.equinox.launcher.cocoa.macosx.x86_64;singleton:=true -Bundle-Version: 1.2.1400.qualifier +Bundle-Version: 1.2.1500.qualifier Fragment-Host: org.eclipse.equinox.launcher;bundle-version="[1.7.0,1.8.0)" Eclipse-PlatformFilter: (& (osgi.ws=cocoa) (osgi.os=macosx) (osgi.arch=x86_64) ) Bundle-Localization: launcher.cocoa.macosx.x86_64 diff --git a/bundles/org.eclipse.equinox.launcher.cocoa.macosx.x86_64/build.properties b/bundles/org.eclipse.equinox.launcher.cocoa.macosx.x86_64/build.properties index 2d9f4089cc7..2f0c27893ca 100644 --- a/bundles/org.eclipse.equinox.launcher.cocoa.macosx.x86_64/build.properties +++ b/bundles/org.eclipse.equinox.launcher.cocoa.macosx.x86_64/build.properties @@ -16,7 +16,7 @@ bin.includes = META-INF/,\ about.html generateSourceBundle=false -binaryTag=LBv1-1916 +binaryTag=LBv1-1921 # Maven properties, see https://github.com/eclipse/tycho/wiki/Tycho-Pomless tycho.pomless.parent = ../../launcher-binary-parent diff --git a/bundles/org.eclipse.equinox.launcher.tests/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.launcher.tests/.settings/org.eclipse.jdt.core.prefs index 62ef3488cc0..fa415ae829f 100644 --- a/bundles/org.eclipse.equinox.launcher.tests/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.eclipse.equinox.launcher.tests/.settings/org.eclipse.jdt.core.prefs @@ -4,6 +4,7 @@ org.eclipse.jdt.core.compiler.compliance=17 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled org.eclipse.jdt.core.compiler.source=17 diff --git a/bundles/org.eclipse.equinox.security.tests/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.security.tests/.settings/org.eclipse.jdt.core.prefs index 814916f088b..228bb5728db 100644 --- a/bundles/org.eclipse.equinox.security.tests/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.eclipse.equinox.security.tests/.settings/org.eclipse.jdt.core.prefs @@ -44,7 +44,7 @@ org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled org.eclipse.jdt.core.compiler.problem.fieldHiding=warning org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning diff --git a/bundles/org.eclipse.equinox.security.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.security.tests/META-INF/MANIFEST.MF index 2fd3612144f..16f4e1660d2 100644 --- a/bundles/org.eclipse.equinox.security.tests/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.security.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Equinox security tests Bundle-SymbolicName: org.eclipse.equinox.security.tests;singleton:=true -Bundle-Version: 1.3.600.qualifier +Bundle-Version: 1.3.700.qualifier Bundle-Activator: org.eclipse.equinox.internal.security.tests.SecurityTestsActivator Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-Vendor: Eclipse.org diff --git a/bundles/org.eclipse.equinox.slf4j/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.slf4j/.settings/org.eclipse.jdt.core.prefs index 62ef3488cc0..fa415ae829f 100644 --- a/bundles/org.eclipse.equinox.slf4j/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.eclipse.equinox.slf4j/.settings/org.eclipse.jdt.core.prefs @@ -4,6 +4,7 @@ org.eclipse.jdt.core.compiler.compliance=17 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled org.eclipse.jdt.core.compiler.source=17 diff --git a/bundles/org.eclipse.equinox.slf4j/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.slf4j/META-INF/MANIFEST.MF index 696d5905d7f..fa53bdf3d3b 100644 --- a/bundles/org.eclipse.equinox.slf4j/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.slf4j/META-INF/MANIFEST.MF @@ -4,7 +4,7 @@ Bundle-Name: %bundleName Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.equinox.slf4j -Bundle-Version: 1.0.200.qualifier +Bundle-Version: 1.0.300.qualifier Import-Package: org.eclipse.equinox.log;version="[1.1.0,2.0.0)", org.osgi.framework;version="[1.10.0,2.0.0)", org.osgi.service.log;version="[1.5.0,2.0.0)", diff --git a/bundles/org.eclipse.equinox.slf4j/src/org/eclipse/equinox/slf4j/EquinoxLogger.java b/bundles/org.eclipse.equinox.slf4j/src/org/eclipse/equinox/slf4j/EquinoxLogger.java index 07de11a78c0..ad9420039d2 100644 --- a/bundles/org.eclipse.equinox.slf4j/src/org/eclipse/equinox/slf4j/EquinoxLogger.java +++ b/bundles/org.eclipse.equinox.slf4j/src/org/eclipse/equinox/slf4j/EquinoxLogger.java @@ -90,26 +90,42 @@ protected void handleNormalizedLoggingCall(Level level, Marker marker, String me if (logger == null) { return; } + //Must not pass a null argument to OSGi Logger + Object[] loggerArguments = throwable != null ? new Object[] { throwable } : new Object[0]; if(level == Level.TRACE && logger.isTraceEnabled()) { - String formattedMessage = MessageFormatter.basicArrayFormat(messagePattern, arguments); - logger.trace(formattedMessage,throwable); + String formattedMessage = safeBasicArrayFormat(messagePattern, arguments); + logger.trace(formattedMessage, loggerArguments); } if(level == Level.DEBUG && logger.isDebugEnabled()) { - String formattedMessage = MessageFormatter.basicArrayFormat(messagePattern, arguments); - logger.debug(formattedMessage,throwable); + String formattedMessage = safeBasicArrayFormat(messagePattern, arguments); + logger.debug(formattedMessage, loggerArguments); } if(level == Level.WARN && logger.isWarnEnabled()) { - String formattedMessage = MessageFormatter.basicArrayFormat(messagePattern, arguments); - logger.warn(formattedMessage,throwable); + String formattedMessage = safeBasicArrayFormat(messagePattern, arguments); + logger.warn(formattedMessage, loggerArguments); } if(level == Level.INFO && logger.isInfoEnabled()) { - String formattedMessage = MessageFormatter.basicArrayFormat(messagePattern, arguments); - logger.info(formattedMessage, throwable); + String formattedMessage = safeBasicArrayFormat(messagePattern, arguments); + logger.info(formattedMessage, loggerArguments); } - if(level == Level.ERROR && logger.isInfoEnabled()) { - String formattedMessage = MessageFormatter.basicArrayFormat(messagePattern, arguments); - logger.info(formattedMessage, throwable); + if(level == Level.ERROR && logger.isErrorEnabled()) { + String formattedMessage = safeBasicArrayFormat(messagePattern, arguments); + logger.error(formattedMessage, loggerArguments); + } + } + + /** + * Wrapper around SLF4J basicArrayFormat that guards against a null message pattern. + * OSGi does not allow logging a null message + * @param messagePattern + * @param arguments + */ + private String safeBasicArrayFormat(String messagePattern, Object[] arguments) { + if(messagePattern == null) { + return String.valueOf(messagePattern); + } else { + return MessageFormatter.basicArrayFormat(messagePattern, arguments); } } diff --git a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF index 5a06f171c24..b68eb0954a3 100644 --- a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Core OSGi Tests Bundle-SymbolicName: org.eclipse.osgi.tests;singleton:=true -Bundle-Version: 3.22.500.qualifier +Bundle-Version: 3.22.600.qualifier Bundle-Vendor: Eclipse.org Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", diff --git a/bundles/org.eclipse.osgi.tests/pom.xml b/bundles/org.eclipse.osgi.tests/pom.xml index 09e3a9eaf35..7dc8e53b825 100644 --- a/bundles/org.eclipse.osgi.tests/pom.xml +++ b/bundles/org.eclipse.osgi.tests/pom.xml @@ -19,7 +19,7 @@ org.eclipse.platform org.eclipse.osgi.tests - 3.22.500-SNAPSHOT + 3.22.600-SNAPSHOT eclipse-test-plugin diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/equinox/log/test/LogEquinoxTraceTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/equinox/log/test/LogEquinoxTraceTest.java index 1c529ddbbab..111fc6caf14 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/equinox/log/test/LogEquinoxTraceTest.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/equinox/log/test/LogEquinoxTraceTest.java @@ -27,6 +27,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import org.eclipse.equinox.log.SynchronousLogListener; import org.eclipse.osgi.internal.debug.Debug; import org.eclipse.osgi.launch.Equinox; @@ -39,6 +41,7 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; +import org.osgi.framework.FrameworkEvent; import org.osgi.framework.ServiceReference; import org.osgi.service.condition.Condition; import org.osgi.service.log.LogEntry; @@ -87,16 +90,28 @@ public void setUp() throws Exception { Map configuration = new HashMap<>(); configuration.put(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath()); equinox = new Equinox(configuration); + equinox.init(); + + BundleContext systemContext = equinox.getBundleContext(); + CountDownLatch frameworkStarted = new CountDownLatch(1); + systemContext.addFrameworkListener((e) -> { + if (FrameworkEvent.STARTED == e.getType()) { + frameworkStarted.countDown(); + } + }); + equinox.start(); - loggerAdmin = equinox.getBundleContext() - .getService(equinox.getBundleContext().getServiceReference(LoggerAdmin.class)); - LogReaderService logReader = equinox.getBundleContext() - .getService(equinox.getBundleContext().getServiceReference(LogReaderService.class)); + // Need to wait for the STARTED event before continuing to ensure + // all events are flushed before adding the test log listener + frameworkStarted.await(1, TimeUnit.MINUTES); + loggerAdmin = systemContext.getService(systemContext.getServiceReference(LoggerAdmin.class)); testListener = new TestListener(); + + LogReaderService logReader = systemContext + .getService(systemContext.getServiceReference(LogReaderService.class)); logReader.addLogListener(testListener); - BundleContext systemContext = equinox.getBundleContext(); debugOptions = systemContext.getService(systemContext.getServiceReference(DebugOptions.class)); } diff --git a/bundles/org.eclipse.osgi/.classpath b/bundles/org.eclipse.osgi/.classpath index 7a20478fd02..b97d05a70c9 100644 --- a/bundles/org.eclipse.osgi/.classpath +++ b/bundles/org.eclipse.osgi/.classpath @@ -1,6 +1,7 @@ + @@ -25,6 +26,5 @@ - diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF index b16b4684244..a6a98d04c0b 100644 --- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF @@ -107,7 +107,7 @@ Bundle-Activator: org.eclipse.osgi.internal.framework.SystemBundleActivator Bundle-Description: %systemBundle Bundle-Copyright: %copyright Bundle-Vendor: %eclipse.org -Bundle-Version: 3.24.100.qualifier +Bundle-Version: 3.24.200.qualifier Bundle-Localization: systembundle Bundle-DocUrl: http://www.eclipse.org Eclipse-ExtensibleAPI: true diff --git a/bundles/org.eclipse.osgi/bnd.bnd b/bundles/org.eclipse.osgi/bnd.bnd index 2705eaef44b..3d89ded0e5a 100644 --- a/bundles/org.eclipse.osgi/bnd.bnd +++ b/bundles/org.eclipse.osgi/bnd.bnd @@ -5,7 +5,6 @@ Require-Capability: \ osgi.serviceloader;osgi.serviceloader="org.osgi.framework.connect.FrameworkUtilHelper", \ - osgi.serviceloader;osgi.serviceloader="java.net.ContentHandlerFactory", \ - osgi.serviceloader;osgi.serviceloader="java.net.URLStreamHandlerFactory" + osgi.serviceloader;osgi.serviceloader="java.net.ContentHandlerFactory" diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/equinox/plurl/impl/PlurlImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/equinox/plurl/impl/PlurlImpl.java index 1e065a5eba3..9912be54ec4 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/equinox/plurl/impl/PlurlImpl.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/equinox/plurl/impl/PlurlImpl.java @@ -150,8 +150,7 @@ static enum SetFactories { List contentHandlerFactories = Collections.emptyList(); List plurlImpls = Collections.emptyList(); - final ServiceLoader builtinURLStreamHandlerFactoryLoader; - final ServiceLoader builtinContentHandlerFactoryLoader; + final List builtinContentHandlerFactories; final CallStack callStack; private final ThreadLocal> creatingProtocols = new ThreadLocal<>(); @@ -503,8 +502,20 @@ public Field getStaticField(Class clazz, Class type) { } public PlurlImpl() { - builtinContentHandlerFactoryLoader = ServiceLoader.load(ContentHandlerFactory.class); - builtinURLStreamHandlerFactoryLoader = ServiceLoader.load(URLStreamHandlerFactory.class); + // IMPLEMENTATION NOTE: + // We must do the ServiceLoader lookup for the built-in ContentHandlerFactory + // because the Plurl ContentHandlerFactory must never return null; + // otherwise the Plurl factory will never be called again for the requested + // content type. So a check for built-in handlers must be done before returning + // the Plurl handler. + // This is not necessary for URLStreamHandlerFactory or the new + // URLStreamHandlerProvider that may be available from the JVM because returning + // null from that factory still allows us to be called again if the protocol is + // requested again later. + List serviceLoaderCHFs = new ArrayList<>(); + ServiceLoader.load(ContentHandlerFactory.class).forEach(serviceLoaderCHFs::add); + builtinContentHandlerFactories = Collections.unmodifiableList(serviceLoaderCHFs); + callStack = createCallStack(); } @@ -585,7 +596,7 @@ public URLStreamHandler run() { ContentHandler findBuiltinContentHandlerImpl(String contentType) { // first check service loader - for (ContentHandlerFactory f : builtinContentHandlerFactoryLoader) { + for (ContentHandlerFactory f : builtinContentHandlerFactories) { ContentHandler h = f.createContentHandler(contentType); if (h != null) { return h; @@ -628,14 +639,7 @@ ContentHandler findBuiltinContentHandlerImpl(String contentType) { } URLStreamHandler findBuiltinURLStreamHandlerImpl(String protocol) { - // first check service loader - for (URLStreamHandlerFactory f : builtinURLStreamHandlerFactoryLoader) { - URLStreamHandler h = f.createURLStreamHandler(protocol); - if (h != null) { - return h; - } - } - // now check property + // check handlers pkgs property String builtInHandlers = System.getProperty(PROTOCOL_HANDLER_PKGS); if (builtInHandlers == null) return null; diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java index 80ea9a1fca8..225b05ce7dd 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java @@ -365,7 +365,7 @@ public void close() throws IOException { // wait for them all to close because this is being closed by the // MRUBundleFileList try { - refCondition.await(1000, TimeUnit.MICROSECONDS); // timeout after 1 second + refCondition.await(1, TimeUnit.SECONDS); // timeout after 1 second } catch (InterruptedException e) { // do nothing for now ... } diff --git a/bundles/org.eclipse.osgi/container/src_test/org/eclipse/equinox/plurl/test/PlurlConcurrencyTest.java b/bundles/org.eclipse.osgi/container/src_test/org/eclipse/equinox/plurl/test/PlurlConcurrencyTest.java new file mode 100644 index 00000000000..9b905930583 --- /dev/null +++ b/bundles/org.eclipse.osgi/container/src_test/org/eclipse/equinox/plurl/test/PlurlConcurrencyTest.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2026 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 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.plurl.test; + +import static org.eclipse.equinox.plurl.test.PlurlContentHandlerFactoryTest.checkContent; +import static org.eclipse.equinox.plurl.test.PlurlStreamHandlerFactoryTest.checkProtocol; +import static org.eclipse.equinox.plurl.test.PlurlTestHandlers.createTestContentHandlerFactory; +import static org.eclipse.equinox.plurl.test.PlurlTestHandlers.createTestURLStreamHandlerFactory; +import static org.eclipse.equinox.plurl.test.PlurlTestHandlers.TestFactoryType.PLURL_FACTORY; +import static org.junit.Assert.assertNull; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import org.eclipse.equinox.plurl.test.PlurlTestHandlers.TestContentHandlerFactory; +import org.eclipse.equinox.plurl.test.PlurlTestHandlers.TestURLStreamHandlerFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +public class PlurlConcurrencyTest { + private static PlurlTestHandlers plurlTestHandlers; + + @Before + public synchronized void installPlurl() { + if (plurlTestHandlers == null) { + plurlTestHandlers = new PlurlTestHandlers(); + } + } + + @After + public void cleanupHandlers() { + plurlTestHandlers.cleanupHandlers(); + } + + @AfterClass + public static void uninstallPlurl() { + plurlTestHandlers.uninstall(true); + plurlTestHandlers = null; + } + + private static final int CONCURRENCY_TEST_ITERATIONS = 100; + private static final int CONCURRENT_THREAD_COUNT = 10; + @Test + public void testConcurrentGetContentCalls() throws InterruptedException, IOException { + // Note that if the test fails it only fails the first iteration because of an + // implementation detail in ServiceLoader. + for (int i = 0; i < CONCURRENCY_TEST_ITERATIONS; i++) { + // install the URL handler, unique to this iteration + TestURLStreamHandlerFactory testPlurlFactory = createTestURLStreamHandlerFactory(PLURL_FACTORY, + "getcontent" + i); //$NON-NLS-1$ + testPlurlFactory.shouldHandle.set(true); + plurlTestHandlers.add(PLURL_FACTORY, testPlurlFactory); + checkProtocol(testPlurlFactory.TYPES, true); + + // install the content factory, unique to this iteration + TestContentHandlerFactory testContentFactory = createTestContentHandlerFactory(PLURL_FACTORY, + "getcontent" + i); //$NON-NLS-1$ + testContentFactory.shouldHandle.set(true); + plurlTestHandlers.add(PLURL_FACTORY, testContentFactory); + + List threads = new ArrayList<>(); + List> errors = new ArrayList<>(); + + for (int j = 0; j < CONCURRENT_THREAD_COUNT; j++) { + AtomicReference error = new AtomicReference<>(); + errors.add(error); + + Thread thread = new Thread(() -> { + try { + checkContent(testContentFactory.TYPES, true); + } catch (Throwable t) { + error.set(t); + } + }); + threads.add(thread); + thread.start(); + } + + for (Thread thread : threads) { + thread.join(); + } + + plurlTestHandlers.remove(PLURL_FACTORY, testContentFactory); + plurlTestHandlers.remove(PLURL_FACTORY, testPlurlFactory); + + for (int j = 0; j < errors.size(); j++) { + Throwable t = errors.get(j).get(); + assertNull("Thread threw an error: " + j, t); //$NON-NLS-1$ + } + } + } +} diff --git a/bundles/org.eclipse.osgi/pom.xml b/bundles/org.eclipse.osgi/pom.xml index 1740845e6a1..64b659439f1 100644 --- a/bundles/org.eclipse.osgi/pom.xml +++ b/bundles/org.eclipse.osgi/pom.xml @@ -19,7 +19,7 @@ org.eclipse.platform org.eclipse.osgi - 3.24.100-SNAPSHOT + 3.24.200-SNAPSHOT eclipse-plugin @@ -77,7 +77,7 @@ org.mockito mockito-core - 5.18.0 + 5.23.0 test diff --git a/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF index 57c7ca02970..409bb94838e 100644 --- a/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.equinox.supplement -Bundle-Version: 1.12.200.qualifier +Bundle-Version: 1.12.300.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.equinox.log;version="1.1", diff --git a/bundles/org.eclipse.osgi/supplement/build.properties b/bundles/org.eclipse.osgi/supplement/build.properties index 0d5ad4382ea..e1fecf9b89f 100644 --- a/bundles/org.eclipse.osgi/supplement/build.properties +++ b/bundles/org.eclipse.osgi/supplement/build.properties @@ -1,6 +1,6 @@ ############################################################################### -# Copyright (c) 2005, 2022 IBM Corporation and others. +# Copyright (c) 2005, 2026 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 466e586b0a9..a22a66f5343 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - activesupport (8.0.2) + activesupport (8.0.4.1) base64 benchmark (>= 0.3) bigdecimal @@ -10,29 +10,29 @@ GEM drb i18n (>= 1.6, < 2) logger (>= 1.4.2) - minitest (>= 5.1) + minitest (>= 5.1, < 6) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) uri (>= 0.13.1) - addressable (2.8.7) - public_suffix (>= 2.0.2, < 7.0) - base64 (0.2.0) - benchmark (0.4.0) - bigdecimal (3.1.9) + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + base64 (0.3.0) + benchmark (0.5.0) + bigdecimal (4.1.1) coffee-script (2.4.1) coffee-script-source execjs coffee-script-source (1.12.2) colorator (1.1.0) commonmarker (0.23.11) - concurrent-ruby (1.3.5) - connection_pool (2.5.1) + concurrent-ruby (1.3.6) + connection_pool (3.0.2) csv (3.3.4) dnsruby (1.73.1) base64 (>= 0.2) logger (~> 1.6) simpleidn (~> 0.2.1) - drb (2.2.1) + drb (2.2.3) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) @@ -112,7 +112,7 @@ GEM activesupport (>= 2) nokogiri (>= 1.4) http_parser.rb (0.8.0) - i18n (1.14.7) + i18n (1.14.8) concurrent-ruby (~> 1.0) jekyll (3.10.0) addressable (~> 2.4) @@ -224,7 +224,7 @@ GEM gemoji (>= 3, < 5) html-pipeline (~> 2.2) jekyll (>= 3.0, < 5.0) - json (2.18.1) + json (2.19.2) kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) @@ -239,24 +239,24 @@ GEM jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - minitest (5.25.5) + minitest (5.27.0) net-http (0.9.1) uri (>= 0.11.1) - nokogiri (1.19.1-aarch64-linux-gnu) + nokogiri (1.19.3-aarch64-linux-gnu) racc (~> 1.4) - nokogiri (1.19.1-aarch64-linux-musl) + nokogiri (1.19.3-aarch64-linux-musl) racc (~> 1.4) - nokogiri (1.19.1-arm-linux-gnu) + nokogiri (1.19.3-arm-linux-gnu) racc (~> 1.4) - nokogiri (1.19.1-arm-linux-musl) + nokogiri (1.19.3-arm-linux-musl) racc (~> 1.4) - nokogiri (1.19.1-arm64-darwin) + nokogiri (1.19.3-arm64-darwin) racc (~> 1.4) - nokogiri (1.19.1-x86_64-darwin) + nokogiri (1.19.3-x86_64-darwin) racc (~> 1.4) - nokogiri (1.19.1-x86_64-linux-gnu) + nokogiri (1.19.3-x86_64-linux-gnu) racc (~> 1.4) - nokogiri (1.19.1-x86_64-linux-musl) + nokogiri (1.19.3-x86_64-linux-musl) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3) diff --git a/features/org.eclipse.equinox.core.feature/feature.xml b/features/org.eclipse.equinox.core.feature/feature.xml index 1673d330cdf..37011ac1e53 100644 --- a/features/org.eclipse.equinox.core.feature/feature.xml +++ b/features/org.eclipse.equinox.core.feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/features/org.eclipse.equinox.core.sdk/feature.xml b/features/org.eclipse.equinox.core.sdk/feature.xml index be2cebe84d9..62f8e0a7b6f 100644 --- a/features/org.eclipse.equinox.core.sdk/feature.xml +++ b/features/org.eclipse.equinox.core.sdk/feature.xml @@ -2,7 +2,7 @@ diff --git a/features/org.eclipse.equinox.executable.feature/library/cocoa/build.sh b/features/org.eclipse.equinox.executable.feature/library/cocoa/build.sh index 2996497b014..d8bb894241e 100755 --- a/features/org.eclipse.equinox.executable.feature/library/cocoa/build.sh +++ b/features/org.eclipse.equinox.executable.feature/library/cocoa/build.sh @@ -61,7 +61,6 @@ echo "build $defaultOSArch" PROGRAM_OUTPUT="$programOutput" DEFAULT_OS="$defaultOS" DEFAULT_WS="$defaultWS" -DEPLOYMENT_TARGET=11.0 if [ "$BINARIES_DIR" = "" ]; then BINARIES_DIR="../../../../../equinox.binaries"; fi if [ "$defaultOSArch" == "arm64" ] || [ "$defaultOSArch" == "aarch64" ] @@ -84,7 +83,7 @@ fi ARCHS="-arch $defaultOSArch" export PROGRAM_OUTPUT DEFAULT_OS DEFAULT_OS_ARCH DEFAULT_WS ARCHS JAVA_HEADERS EXE_OUTPUT_DIR LIB_OUTPUT_DIR -export MACOSX_DEPLOYMENT_TARGET=$DEPLOYMENT_TARGET +export MACOSX_DEPLOYMENT_TARGET=11 if [ "$extraArgs" != "" ]; then make -f $makefile $extraArgs diff --git a/features/org.eclipse.equinox.executable.feature/library/cocoa/make_cocoa.mak b/features/org.eclipse.equinox.executable.feature/library/cocoa/make_cocoa.mak index aaafb34c72d..98f8594faf1 100644 --- a/features/org.eclipse.equinox.executable.feature/library/cocoa/make_cocoa.mak +++ b/features/org.eclipse.equinox.executable.feature/library/cocoa/make_cocoa.mak @@ -44,7 +44,8 @@ ifeq ($(ARCHS),-arch x86_64) endif CFLAGS = -O \ - -Wall \ + -Wall -Werror \ + -Wunguarded-availability \ -DCOCOA -xobjective-c \ $(ARCHS) \ -DMACOSX \ diff --git a/features/org.eclipse.equinox.executable.feature/library/make_version.mak b/features/org.eclipse.equinox.executable.feature/library/make_version.mak index 6ad9147cc91..2bd0a0eedc6 100644 --- a/features/org.eclipse.equinox.executable.feature/library/make_version.mak +++ b/features/org.eclipse.equinox.executable.feature/library/make_version.mak @@ -13,5 +13,5 @@ #******************************************************************************* maj_ver=1 -min_ver=1919 +min_ver=1921 LIB_VERSION = $(maj_ver)$(min_ver) diff --git a/features/org.eclipse.equinox.server.core/feature.xml b/features/org.eclipse.equinox.server.core/feature.xml index 2f81f5b4769..6b1de67389a 100644 --- a/features/org.eclipse.equinox.server.core/feature.xml +++ b/features/org.eclipse.equinox.server.core/feature.xml @@ -2,7 +2,7 @@ diff --git a/features/org.eclipse.equinox.server.jetty/feature.xml b/features/org.eclipse.equinox.server.jetty/feature.xml index daaa1b48ba9..ab2855c5fe8 100644 --- a/features/org.eclipse.equinox.server.jetty/feature.xml +++ b/features/org.eclipse.equinox.server.jetty/feature.xml @@ -2,7 +2,7 @@ @@ -15,6 +15,10 @@ %license + + + + diff --git a/pom.xml b/pom.xml index 45ab4864749..53459951076 100644 --- a/pom.xml +++ b/pom.xml @@ -259,7 +259,7 @@ biz.aQute.bnd bnd-maven-plugin - 7.1.0 + 7.2.3 org.eclipse.tycho diff --git a/releng/org.eclipse.equinox.releng/Equinox.setup b/releng/org.eclipse.equinox.releng/Equinox.setup index b59396769a6..4b658a42c11 100644 --- a/releng/org.eclipse.equinox.releng/Equinox.setup +++ b/releng/org.eclipse.equinox.releng/Equinox.setup @@ -248,7 +248,8 @@ xsi:type="setup:ResourceCreationTask" excludedTriggers="BOOTSTRAP" targetURL="${github.clone.equinox.p2.location|uri}/bundles/org.eclipse.equinox.p2.jarprocessor/lib/jarprocessor-ant.jar" - encoding="base64"> + encoding="base64" + lastModified="0"> Create an empty jar as a placeholder for the jar that will eventually be created. This ensures that PDE will add the jar to the classpath of projects needing the ant jar. UEsDBAoAAAAAAHtelUw05vp1HAAAABwAAAAFAHAAZW1wdHlTRFsApAAAAAAIAL/UyvdjZGBpEGFg @@ -262,7 +263,8 @@ xsi:type="setup:ResourceCreationTask" excludedTriggers="BOOTSTRAP" targetURL="${github.clone.equinox.p2.location|uri}/bundles/org.eclipse.equinox.p2.repository.tools/lib/repository-tools-ant.jar" - encoding="base64"> + encoding="base64" + lastModified="0"> Create an empty jar as a placeholder for the jar that will eventually be created. This ensures that PDE will add the jar to the classpath of projects needing the ant jar. UEsDBAoAAAAAAHtelUw05vp1HAAAABwAAAAFAHAAZW1wdHlTRFsApAAAAAAIAL/UyvdjZGBpEGFg