diff --git a/.ci-orchestrator/checks.yml b/.ci-orchestrator/checks.yml index b3cadb908b9..a4a3cbceded 100644 --- a/.ci-orchestrator/checks.yml +++ b/.ci-orchestrator/checks.yml @@ -41,13 +41,18 @@ steps: properties: isBvtCodeChanged: ${PR Changes:is.bvt.code.changed} isFatCodeChanged: ${PR Changes:is.fat.code.changed} + isFeatureFilesChanged: ${PR Changes:is.feature.files.changed} isInfraCodeChanged: ${PR Changes:is.infra.code.changed} + isMsgsFilesChanged: ${PR Changes:is.msgs.files.changed} + isNlsFilesChanged: ${PR Changes:is.nls.files.changed} isProductCodeChanged: ${PR Changes:is.product.code.changed} isTestInfraCodeChanged: ${PR Changes:is.test.infra.code.changed} isUnittestCodeChanged: ${PR Changes:is.unittest.code.changed} bvtFilesCount: ${PR Changes:bvt.files.count} fatFilesCount: ${PR Changes:fat.files.count} infraFilesCount: ${PR Changes:infra.files.count} + msgsFiles: ${PR Changes:msgs.files} + nlsFiles: ${PR Changes:nls.files} productFilesCount: ${PR Changes:product.files.count} testInfraFilesCount: ${PR Changes:test.infra.files.count} unittestFilesCount: ${PR Changes:unittest.files.count} diff --git a/.ci-orchestrator/pb.yml b/.ci-orchestrator/pb.yml index 14dba40cdc7..302e95d3193 100644 --- a/.ci-orchestrator/pb.yml +++ b/.ci-orchestrator/pb.yml @@ -10,9 +10,11 @@ triggers: groups: ["LibertyDev"] keyword: "!pbbeta" aliasKeywords: - - "#build" - - "#pbbeta" - "!build" + - "!pb" + - "#pbbeta" + - "#build" + - "#pb" propertyDefinitions: # If a user defines this property, set it for all steps that use it except the "Distributed Full FATs" step. - name: fat.buckets.to.run @@ -77,7 +79,9 @@ triggers: groups: ["LibertyDev"] keyword: "!fullpbbeta" aliasKeywords: + - "!fullpb" - "#fullpbbeta" + - "#fullpb" propertyDefinitions: # Run all buckets in full mode. - name: fat.buckets.to.run @@ -149,13 +153,18 @@ steps: githubPRNumber: ${github_pr_number} isBvtCodeChanged: ${PR Changes:is.bvt.code.changed} isFatCodeChanged: ${PR Changes:is.fat.code.changed} + isFeatureFilesChanged: ${PR Changes:is.feature.files.changed} isInfraCodeChanged: ${PR Changes:is.infra.code.changed} + isMsgsFilesChanged: ${PR Changes:is.msgs.files.changed} + isNlsFilesChanged: ${PR Changes:is.nls.files.changed} isProductCodeChanged: ${PR Changes:is.product.code.changed} isTestInfraCodeChanged: ${PR Changes:is.test.infra.code.changed} isUnittestCodeChanged: ${PR Changes:is.unittest.code.changed} bvtFilesCount: ${PR Changes:bvt.files.count} fatFilesCount: ${PR Changes:fat.files.count} infraFilesCount: ${PR Changes:infra.files.count} + msgsFiles: ${PR Changes:msgs.files} + nlsFiles: ${PR Changes:nls.files} productFilesCount: ${PR Changes:product.files.count} testInfraFilesCount: ${PR Changes:test.infra.files.count} unittestFilesCount: ${PR Changes:unittest.files.count} diff --git a/.ci-orchestrator/pbRTCBuild.yml b/.ci-orchestrator/pbRTCBuild.yml deleted file mode 100644 index 3dad515faf3..00000000000 --- a/.ci-orchestrator/pbRTCBuild.yml +++ /dev/null @@ -1,118 +0,0 @@ -type: pipeline_definition -product: Liberty -name: Open Liberty Personal Build RTC -description: A build run against Open Liberty Pull Requests -triggers: -- type: github - triggerName: "ol-pb" - triggerRank: 20 - groups: ["LibertyDev"] - keyword: "!pb" - aliasKeywords: - - "#pb" - -- type: github - triggerName: "ol-pb-build" - triggerRank: 20 - groups: ["LibertyDev"] - keyword: "!build" - -- type: github - triggerName: "ol-fullpb" - triggerRank: 20 - groups: ["LibertyDev"] - keyword: "!fullpb" - aliasKeywords: - - "#fullpb" - propertyDefinitions: - - name: fat.test.mode - defaultValue: full - steps: - - stepName: Compile - - name: create.im.repo - defaultValue: true - steps: - - stepName: Compile - - name: spawn.zos - defaultValue: true - steps: - - stepName: Compile - - name: fat.buckets.to.run - defaultValue: all - steps: - - stepName: Compile - -steps: -- stepName: PR Changes - workType: PRChangesDetection - timeoutInMinutes: 30 - properties: - githubPRApi: ${github_pr_api} - githubPRNumber: ${github_pr_number} - -- stepName: Copyright Header Check - workType: Jenkins - projectName: copyrightHeaderCheck - timeoutInMinutes: 120 - properties: - githubPRApi: ${github_pr_api} - githubPRNumber: ${github_pr_number} - -- stepName: Prohibited Terms Check - workType: Jenkins - projectName: prohibitedTermsCheck - timeoutInMinutes: 120 - properties: - githubPRApi: ${github_pr_api} - githubPRNumber: ${github_pr_number} - -- stepName: Code Checklist Creation - workType: Jenkins - projectName: codeCheckListBuilder - timeoutInMinutes: 120 - dependsOn: - - stepName: PR Changes - awaitOutputProperties: true - properties: - githubPRApi: ${github_pr_api} - githubPRNumber: ${github_pr_number} - isBvtCodeChanged: ${PR Changes:is.bvt.code.changed} - isFatCodeChanged: ${PR Changes:is.fat.code.changed} - isInfraCodeChanged: ${PR Changes:is.infra.code.changed} - isProductCodeChanged: ${PR Changes:is.product.code.changed} - isTestInfraCodeChanged: ${PR Changes:is.test.infra.code.changed} - isUnittestCodeChanged: ${PR Changes:is.unittest.code.changed} - bvtFilesCount: ${PR Changes:bvt.files.count} - fatFilesCount: ${PR Changes:fat.files.count} - infraFilesCount: ${PR Changes:infra.files.count} - productFilesCount: ${PR Changes:product.files.count} - testInfraFilesCount: ${PR Changes:test.infra.files.count} - unittestFilesCount: ${PR Changes:unittest.files.count} - -- stepName: Compile - coreStep: true - workType: RTC - projectName: "Liberty Personal Build - EBC" - timeoutInMinutes: 2160 - dependsOn: - - stepName: PR Changes - awaitOutputProperties: true - properties: - run.packaging.verification: ${PR Changes:run.packaging.verification} - fat.buckets.to.run: ${PR Changes:fat.buckets.to.run} - disable.run.runBvtTests: ${PR Changes:disable.run.runBvtTests} - disable.run.runUnitTests: ${PR Changes:disable.run.runUnitTests} - run.chkpii: ${PR Changes:run.chkpii} - run.findbugs: ${PR Changes:run.findbugs} - spawn.zos: ${PR Changes:spawn.zos} - create.im.repo: ${PR Changes:create.im.repo} - personal.im.build: ${PR Changes:personal.im.build} - disable.run.createDoc: ${PR Changes:disable.run.createDoc} - skip.open.liberty.build.if.possible: ${PR Changes:skip.open.liberty.build.if.possible} - skip.open.liberty.fats.if.possible: ${PR Changes:skip.open.liberty.fats.if.possible} - fat.run.count: ${PR Changes:fat.run.count} - spawn.fullfat.buckets: ${PR Changes:spawn.fullfat.buckets} - zos.fat.buckets.to.exclude: ${PR Changes:zos.fat.buckets.to.exclude} - zos.unittests.to.exclude: ${PR Changes:zos.unittests.to.exclude} - includeProperties: - - file: compilePersonalRTC.properties diff --git a/dev/build.depScanner/src/io/openliberty/depScanner/BestMatch.java b/dev/build.depScanner/src/io/openliberty/depScanner/BestMatch.java index 0c31fc332b3..b8e24bb0cfe 100644 --- a/dev/build.depScanner/src/io/openliberty/depScanner/BestMatch.java +++ b/dev/build.depScanner/src/io/openliberty/depScanner/BestMatch.java @@ -296,6 +296,7 @@ private static boolean filteredLibraries(Module library) { return (library.getGroupId().equals("org.glassfish") && (library.getArtifactId().equals("javax.faces"))) || (library.getArtifactId().equals("tomcat-embed-core")) || (library.getArtifactId().equals("woodstox-core") && (library.getVersion().equals("6.2.6") || library.getVersion().equals("6.2.4"))) || + (library.getArtifactId().equals("commons-io") && (library.getVersion().equals("2.13.0"))) || (library.getArtifactId().equals("netty-codec-http") && (library.getVersion().equals("4.1.73.Final") || library.getVersion().equals("4.1.78.Final") || library.getVersion().equals("4.1.92.Final"))) || diff --git a/dev/build.image/publish/ibm.com_Open_Liberty-24.0.0.swidtag b/dev/build.image/publish/ibm.com_Open_Liberty-25.0.0.swidtag similarity index 90% rename from dev/build.image/publish/ibm.com_Open_Liberty-24.0.0.swidtag rename to dev/build.image/publish/ibm.com_Open_Liberty-25.0.0.swidtag index 3e87e0f8eb2..42d450c50d3 100644 --- a/dev/build.image/publish/ibm.com_Open_Liberty-24.0.0.swidtag +++ b/dev/build.image/publish/ibm.com_Open_Liberty-25.0.0.swidtag @@ -1,5 +1,5 @@ - + diff --git a/dev/build.image/publish/ibm.com_Open_Liberty_release.swidtag b/dev/build.image/publish/ibm.com_Open_Liberty_release.swidtag index 89990892b76..5c64a8145b6 100644 --- a/dev/build.image/publish/ibm.com_Open_Liberty_release.swidtag +++ b/dev/build.image/publish/ibm.com_Open_Liberty_release.swidtag @@ -1,8 +1,8 @@ - + - + diff --git a/dev/cnf/dependabot/check_this_in_if_it_changes/pom.xml b/dev/cnf/dependabot/check_this_in_if_it_changes/pom.xml index 156d8bf9a7f..cb3864d1516 100644 --- a/dev/cnf/dependabot/check_this_in_if_it_changes/pom.xml +++ b/dev/cnf/dependabot/check_this_in_if_it_changes/pom.xml @@ -3289,7 +3289,7 @@ org.eclipse.platform org.eclipse.osgi - 3.18.600 + 3.21.0 org.eclipse.transformer @@ -3949,7 +3949,7 @@ org.jboss.weld.environment weld-environment-common - 6.0.0.Beta1 + 6.0.0.CR1 org.jboss.weld.se @@ -3969,7 +3969,7 @@ org.jboss.weld.se weld-se-core - 6.0.0.Beta1 + 6.0.0.CR1 org.jboss.weld @@ -3994,7 +3994,7 @@ org.jboss.weld weld-osgi-bundle - 6.0.0.Beta1 + 6.0.0.CR1 org.jetbrains.kotlin diff --git a/dev/cnf/oss_dependencies.maven b/dev/cnf/oss_dependencies.maven index edb29163f31..b37b7121303 100644 --- a/dev/cnf/oss_dependencies.maven +++ b/dev/cnf/oss_dependencies.maven @@ -785,16 +785,16 @@ org.jboss.shrinkwrap:shrinkwrap-api:1.2.3 org.jboss.shrinkwrap:shrinkwrap-impl-base:1.2.3 org.jboss.shrinkwrap:shrinkwrap-spi:1.2.3 org.jboss.weld.environment:weld-environment-common:5.1.1.SP2 -org.jboss.weld.environment:weld-environment-common:6.0.0.Beta1 +org.jboss.weld.environment:weld-environment-common:6.0.0.CR1 org.jboss.weld.se:weld-se-core:3.1.9.Final org.jboss.weld.se:weld-se-core:4.0.3.Final org.jboss.weld.se:weld-se-core:5.1.1.SP2 -org.jboss.weld.se:weld-se-core:6.0.0.Beta1 +org.jboss.weld.se:weld-se-core:6.0.0.CR1 org.jboss.weld:weld-osgi-bundle:2.4.8.Final org.jboss.weld:weld-osgi-bundle:3.1.9.Final org.jboss.weld:weld-osgi-bundle:4.0.3.Final org.jboss.weld:weld-osgi-bundle:5.1.1.SP2 -org.jboss.weld:weld-osgi-bundle:6.0.0.Beta1 +org.jboss.weld:weld-osgi-bundle:6.0.0.CR1 org.jetbrains.kotlin:kotlin-stdlib-common:1.9.0 org.jetbrains.kotlin:kotlin-stdlib:1.9.0 org.jetbrains:annotations:13.0 diff --git a/dev/cnf/resources/bnd/liberty-release.props b/dev/cnf/resources/bnd/liberty-release.props index a394d669d73..15723a913af 100644 --- a/dev/cnf/resources/bnd/liberty-release.props +++ b/dev/cnf/resources/bnd/liberty-release.props @@ -13,14 +13,14 @@ releaseTypeGA=true -libertyBaseVersion=24.0.0 -libertyFixpackVersion=12 +libertyBaseVersion=25.0.0 +libertyFixpackVersion=1 libertyServiceVersion=${libertyBaseVersion}.${libertyFixpackVersion} -libertyBetaVersion=2024.12.0.0 +libertyBetaVersion=2025.1.0.0 libertyRelease=${if;${releaseTypeGA};${libertyServiceVersion};${libertyBetaVersion}} -libertyBundleMicroVersion=96 -copyrightBuildYear=2024 +libertyBundleMicroVersion=97 +copyrightBuildYear=2025 buildID=${libertyRelease}-${def;buildLabel} productEdition=BASE_ILAN productLicenseType=ILAN diff --git a/dev/com.ibm.rls.jdbc/src/com/ibm/ws/recoverylog/custom/jdbc/impl/SQLMultiScopeRecoveryLog.java b/dev/com.ibm.rls.jdbc/src/com/ibm/ws/recoverylog/custom/jdbc/impl/SQLMultiScopeRecoveryLog.java index 6433e625478..3425ab88b01 100644 --- a/dev/com.ibm.rls.jdbc/src/com/ibm/ws/recoverylog/custom/jdbc/impl/SQLMultiScopeRecoveryLog.java +++ b/dev/com.ibm.rls.jdbc/src/com/ibm/ws/recoverylog/custom/jdbc/impl/SQLMultiScopeRecoveryLog.java @@ -144,7 +144,7 @@ public class SQLMultiScopeRecoveryLog implements LogCursorCallback, MultiScopeLo /** * Which RDBMS are we working against? */ - private DBProduct dbProduct; + private volatile DBProduct dbProduct; private boolean isolationFailureReported; @@ -223,7 +223,7 @@ public class SQLMultiScopeRecoveryLog implements LogCursorCallback, MultiScopeLo * A flag to indicate that the log was being recovered by a peer * but it has been reclaimed by its "home" server. */ - volatile private boolean _peerServerLostLogOwnership; + private volatile boolean _peerServerLostLogOwnership; /** * These strings are used for Database table creation. DDL is diff --git a/dev/com.ibm.rls.jdbc/src/com/ibm/ws/recoverylog/custom/jdbc/impl/SQLSharedServerLeaseLog.java b/dev/com.ibm.rls.jdbc/src/com/ibm/ws/recoverylog/custom/jdbc/impl/SQLSharedServerLeaseLog.java index e2f63b66af6..8d49e061a74 100644 --- a/dev/com.ibm.rls.jdbc/src/com/ibm/ws/recoverylog/custom/jdbc/impl/SQLSharedServerLeaseLog.java +++ b/dev/com.ibm.rls.jdbc/src/com/ibm/ws/recoverylog/custom/jdbc/impl/SQLSharedServerLeaseLog.java @@ -70,9 +70,9 @@ public class SQLSharedServerLeaseLog extends LeaseLogImpl implements SharedServe /** * Which RDBMS are we working against? */ - private DBProduct dbProduct; + private volatile DBProduct dbProduct; - volatile private boolean _leaseTableExists; + private volatile boolean _leaseTableExists; private boolean _sqlTransientErrorHandlingEnabled = true; private boolean _logRetriesEnabled; private int _leaseTimeout; diff --git a/dev/com.ibm.tx.jta/src/com/ibm/tx/jta/impl/RecoveryManager.java b/dev/com.ibm.tx.jta/src/com/ibm/tx/jta/impl/RecoveryManager.java index 37d7129b37c..d1853d0e36d 100644 --- a/dev/com.ibm.tx.jta/src/com/ibm/tx/jta/impl/RecoveryManager.java +++ b/dev/com.ibm.tx.jta/src/com/ibm/tx/jta/impl/RecoveryManager.java @@ -86,8 +86,8 @@ public class RecoveryManager implements Runnable { private final RecoveryAgent _agent; protected RecoveryLog _tranLog; // 169107 - protected RecoveryLog _xaLog; // 169107 - protected final RecoveryLog _recoverXaLog; //@MD18134A + private RecoveryLog _xaLog; // 169107 + private final RecoveryLog _recoverXaLog; //@MD18134A private SharedServerLeaseLog _leaseLog; private String _recoveryGroup; @@ -95,7 +95,7 @@ public class RecoveryManager implements Runnable { private boolean _peerTranLogEverOpened = false; private boolean _peerXaLogEverOpened = false; - protected PartnerLogTable _recoveryPartnerLogTable; + private PartnerLogTable _recoveryPartnerLogTable; private byte[] _ourApplId; private int _ourEpoch; @@ -126,16 +126,10 @@ public class RecoveryManager implements Runnable { // The following relate to the service data recoverable unit in the transaction log // This is reserved and holds the servername, applid and epoch. // - protected RecoverableUnit _tranlogServiceData; - protected RecoverableUnitSection _tranlogServerSection; - protected RecoverableUnitSection _tranlogApplIdSection; - protected RecoverableUnitSection _tranlogEpochSection; - - protected String _classPath; // current classpath for recovery - // These are static as they are only initialized from the "server's" own log - // We use our own classpaths and not from other servers in case we recover - // for a filesystem that does not match our own. - protected static String _loggedClassPath; // classpath read from the log at startup + private RecoverableUnit _tranlogServiceData; + private RecoverableUnitSection _tranlogServerSection; + private RecoverableUnitSection _tranlogApplIdSection; + private RecoverableUnitSection _tranlogEpochSection; // Server States logged for serviceability private static final int STARTING = 1; @@ -152,9 +146,9 @@ public class RecoveryManager implements Runnable { /** * This set contains a list of all recovering transactions. */ - protected Set _recoveringTransactions; + private final Set _recoveringTransactions; - protected final Object _recoveryMonitor = new Object(); + private final Object _recoveryMonitor = new Object(); private boolean _cleanRemoteShutdown; diff --git a/dev/com.ibm.websphere.appserver.features/visibility/public/cdi-4.1/io.openliberty.cdi-4.1.feature b/dev/com.ibm.websphere.appserver.features/visibility/public/cdi-4.1/io.openliberty.cdi-4.1.feature index 0e83135366d..8de091c5ac4 100644 --- a/dev/com.ibm.websphere.appserver.features/visibility/public/cdi-4.1/io.openliberty.cdi-4.1.feature +++ b/dev/com.ibm.websphere.appserver.features/visibility/public/cdi-4.1/io.openliberty.cdi-4.1.feature @@ -55,7 +55,7 @@ Subsystem-Name: Jakarta Contexts and Dependency Injection 4.1 io.openliberty.org.jboss.weld6.se, \ com.ibm.ws.org.jboss.jdeparser.1.0.0, \ com.ibm.ws.managedobject, \ - io.openliberty.org.jboss.logging35, \ + io.openliberty.org.jboss.logging36, \ io.openliberty.org.jboss.classfilewriter.1.3, \ com.ibm.ws.cdi.weld.jakarta, \ com.ibm.ws.cdi.internal.jakarta, \ @@ -64,7 +64,7 @@ Subsystem-Name: Jakarta Contexts and Dependency Injection 4.1 com.ibm.ws.cdi.interfaces.jakarta, \ io.openliberty.cdi.4.0.internal.interfaces, \ io.openliberty.cdi.spi; location:="dev/spi/ibm/,lib/" --jars=io.openliberty.cdi.4.1.thirdparty; location:="dev/api/third-party/,lib/"; mavenCoordinates="org.jboss.weld:weld-osgi-bundle:6.0.0.Beta1" +-jars=io.openliberty.cdi.4.1.thirdparty; location:="dev/api/third-party/,lib/"; mavenCoordinates="org.jboss.weld:weld-osgi-bundle:6.0.0.CR1" -files=dev/api/ibm/schema/ibm-managed-bean-bnd_1_0.xsd, \ dev/api/ibm/schema/ibm-managed-bean-bnd_1_1.xsd, \ dev/spi/ibm/javadoc/io.openliberty.cdi.spi_1.1-javadoc.zip diff --git a/dev/com.ibm.ws.app.manager.lifecycle/src/com/ibm/wsspi/application/lifecycle/ApplicationPrereq.java b/dev/com.ibm.ws.app.manager.lifecycle/src/com/ibm/wsspi/application/lifecycle/ApplicationPrereq.java index cdbad0249b0..1a7d0383ac7 100644 --- a/dev/com.ibm.ws.app.manager.lifecycle/src/com/ibm/wsspi/application/lifecycle/ApplicationPrereq.java +++ b/dev/com.ibm.ws.app.manager.lifecycle/src/com/ibm/wsspi/application/lifecycle/ApplicationPrereq.java @@ -1,24 +1,131 @@ -/******************************************************************************* - * Copyright (c) 2020 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2020,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.wsspi.application.lifecycle; /** - * This a marker interface for Service components that must be present before wsspi.applications are started. - * - * Implementors must also provide a config element in their defaultInstances.xml as follows: - * {@code - * - * } + * A marker interface for service components indicating + * they must be present before applications are started. + *

+ * Liberty's processing of configuration and metatype will discover + * these declarations and wait for the configured services before + * allowing applications to start. + *

+ * + * Every implementor must observe the following conventions: + *
    + *
  1. Edit the {@code bnd.bnd} for the bundle to instruct bnd appropriately: + *
      + *
    • Process the class for declarative services annotations: + *
      + * -dsannotations: com.acme.Widget
      + *         
      + *
    • + *
    • Add the metatype and default instances to the bundle: + *
      + * Include-Resource: OSGI-INF=resources/OSGI-INF
      + *         
      + *
    • + *
    • Declare the default instances (if required — see below): + *
      + * IBM-Default-Config: OSGI-INF/wlp/defaultInstances.xml
      + *         
      + *
    • + *
    • Add the app manager lifecycle bundle to the build path: + *
      + * -buildpath: com.ibm.ws.app.manager.lifecycle;version=latest
      + *         
      + *
    • + *
    + *
  2. + *
  3. The implementation must declare itself as a declarative services (DS) component. + *
      + *
    • The component declaration must provide {@link ApplicationPrereq} as a service.
      + * + * If this is not done, the configured component instance will never be discovered, and applications will not start up. + * + *
    • + *
    • The component declaration must require configuration.
    • + *
    + * e.g.: + *
    + * package com.acme;
    + * {@code @Component}(
    + *         service = ApplicationPrereq.class,
    + *         configurationPolicy = REQUIRE,
    + *         configurationPid = "com.acme.Widget",
    + *         property = "service.vendor=Acme")
    + * public class Widget implements ApplicationPrereq {…}
    + *     
    + * + * Note: Components can be declared in the Java source or in the {@code bnd.bnd} file.
    + * Verify the component xml in the generated bundle, + * e.g. {@code OSGI-INF/com.acme.Widget.xml} + *
    + *
  4. + *
  5. + * The implementing bundle must provide an {@code OCD} and a {@code Designate} + * for the configuration in an XML file in {@code resources/OSGI-INF/metatype/}, + * usually {@code metatype.xml}. + *
      + *
    • the OCD must declare its objectClass to be {@link ApplicationPrereq}
      + * e.g. + *
      + * {@code }
      + * ⋮
      + * {@code }
      + *         
      + * + * Declaring the objectClass correctly allows every configuration of this OCD to be discovered. + * Application containers will start only after the configured component instances become available. + * + *
    • + *
    • + * Either the Designate must use a factoryPid instead of a pid, + *
      + * {@code }
      + *   {@code }
      + * {@code }
      + *         
      + *       
      + *       
    • + * Or the OCD must contain a required AD without a default value: + *
      + * {@code }
      + *   {@code }
      + * {@code }
      + *         
      + * + * If the delegate uses a pid and the OCD has no required non-default AD, + * Liberty's configuration processing may not be invoked for this OCD, + * and the counting of application prereqs may fail. + * This can be very difficult to debug! + * + *
    • + * + * + *
    • The configuration may be user-specified in the server.xml or provided in the bundle's default instances: + *
      + * {@code }
      + *   {@code }
      + * {@code }
      + *     
      + *
    • + * */ public interface ApplicationPrereq { } diff --git a/dev/com.ibm.ws.artifact.zip/src/com/ibm/ws/artifact/zip/cache/internal/ZipFileReaper.java b/dev/com.ibm.ws.artifact.zip/src/com/ibm/ws/artifact/zip/cache/internal/ZipFileReaper.java index b8cfb1736b0..038bc4cb341 100644 --- a/dev/com.ibm.ws.artifact.zip/src/com/ibm/ws/artifact/zip/cache/internal/ZipFileReaper.java +++ b/dev/com.ibm.ws.artifact.zip/src/com/ibm/ws/artifact/zip/cache/internal/ZipFileReaper.java @@ -25,8 +25,7 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Supplier; -//import java.util.function.Consumer; +import java.util.function.Function; import java.util.zip.ZipException; import java.util.zip.ZipFile; @@ -917,12 +916,21 @@ private static class PendingStorageLock { // - private static final class ZipFilePathLock { } + private static final class ZipFilePathLock { + private final String path; + ZipFilePathLock(String path){ + this.path = path; + } + @Override + public String toString() { + return "ZipFilePathLock: " + path; + } + } - private static KeyBasedLockStore zipFilePathLockStore = new KeyBasedLockStore<>(new Supplier() { + private static KeyBasedLockStore zipFilePathLockStore = new KeyBasedLockStore<>(new Function() { @Override - public ZipFilePathLock get() { - return new ZipFilePathLock(); + public ZipFilePathLock apply(String path) { + return new ZipFilePathLock(path); } }); diff --git a/dev/com.ibm.ws.classloading/src/com/ibm/ws/classloading/internal/ClassLoadingServiceImpl.java b/dev/com.ibm.ws.classloading/src/com/ibm/ws/classloading/internal/ClassLoadingServiceImpl.java index f76d0cab678..76bedff1305 100644 --- a/dev/com.ibm.ws.classloading/src/com/ibm/ws/classloading/internal/ClassLoadingServiceImpl.java +++ b/dev/com.ibm.ws.classloading/src/com/ibm/ws/classloading/internal/ClassLoadingServiceImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2023 IBM Corporation and others. + * Copyright (c) 2010, 2024 IBM Corporation and others. * All rights reserved. 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 @@ -41,7 +41,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Supplier; +import java.util.function.Function; import org.eclipse.equinox.region.RegionDigraph; import org.osgi.framework.Bundle; @@ -112,9 +112,9 @@ public class ClassLoadingServiceImpl implements LibertyClassLoadingService tcclLockStore = new KeyBasedLockStore<>(new Supplier() { + private static final KeyBasedLockStore tcclLockStore = new KeyBasedLockStore<>(new Function() { @Override - public ReentrantLock get() { + public ReentrantLock apply(String key) { return new ReentrantLock(); } }); diff --git a/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/DynamicConfigRuleCheckpoint.java b/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/DynamicConfigRuleCheckpoint.java new file mode 100644 index 00000000000..e6298127897 --- /dev/null +++ b/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/DynamicConfigRuleCheckpoint.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright (c) 2014, 2024 IBM Corporation and others. + * All rights reserved. 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 + * http://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package batch.fat.junit; + +import static org.junit.Assert.assertNotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runner.RunWith; +import org.junit.runners.model.Statement; + +import com.ibm.websphere.simplicity.log.Log; +import batch.fat.util.BatchFATHelper; +import componenttest.annotation.CheckpointTest; +import com.ibm.websphere.simplicity.log.Log; +import com.ibm.ws.jbatch.test.FatUtils; + +import componenttest.custom.junit.runner.FATRunner; +import componenttest.topology.impl.LibertyServer; + +/** + * The DynamicConfigRuleCheckpoint takes a list of server.xml file names and runs the + * test(s) multiple times, once for each server.xml file. The server.xml updates + * are applied dynamically (i.e the server is not restarted). + * + */ +@RunWith(FATRunner.class) +public class DynamicConfigRuleCheckpoint implements TestRule { + + public static void log(String method, String msg) { + Log.info(DynamicConfigRuleCheckpoint.class, method, msg); + } + + /** + * A function that does setup of a {@code LibertyServer}. + * + * @param + */ + @FunctionalInterface + public static interface ServerSetup { + /** + * Setup the server + * @return the checkpointed server + * @throws T + */ + public LibertyServer call() throws T; + } + + /** + * A function that does some action. + * + * @param + */ + @FunctionalInterface + public static interface Action { + /** + * Perform some action + */ + public void call() throws T; + } + + private ServerSetup initialSetup; + + private Action finalTearDown; + + private Action beforeEach; + + private LibertyServer server; + + /** + * The list of server.xml config files to run the tests against. + */ + private final List serverXmlFileNames = new ArrayList(); + + /** + * Sets the mandatory function that does server setup for the normal and checkpoint mode for the test + * + * @param + * @param serverSetup + * @return + */ + public DynamicConfigRuleCheckpoint setInitialSetup(ServerSetup initialSetup) { + this.initialSetup = initialSetup; + return this; + } + + /** + * @param finalTearDown Executed after iterating thru ALL server xmls. + * + * @return this + */ + public DynamicConfigRuleCheckpoint setFinalTearDown(Action finalTearDown) { + this.finalTearDown = finalTearDown; + return this; + } + + /** + * @param beforeEach Executed before each iteration of the server.xmls + * + * @return this + */ + public DynamicConfigRuleCheckpoint setBeforeEach(Action beforeEach) { + this.beforeEach = beforeEach; + return this; + } + + /** + * @param serverXmlFileName Add a server.xml file to the list + * + * @return this + */ + public DynamicConfigRuleCheckpoint addServerXml(String serverXmlFileName) { + this.serverXmlFileNames.add(serverXmlFileName); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public Statement apply(Statement base, Description desc) { + return new DynamicConfigStatement(base); + } + + /** + * Statement class - performs the before/after operations around a + * call to the base Statement's evaulate() method (which runs the test). + */ + protected class DynamicConfigStatement extends Statement { + + /** + * A reference to the Statement that this Statement wraps around. + */ + private final Statement base; + + /** + * CTOR. + * + * @param base The Statement that this Statement wraps around. + */ + public DynamicConfigStatement(Statement base) { + this.base = base; + } + + /** + * This method is called by the test runner in order to execute the test. + * + * Before/After logic is embedded here around a call to base.evaluate(), + * which processes the Statement chain (for any other @Rules that have been + * applied) until at last the test method is executed. + * + */ + @Override + public void evaluate() throws Throwable { + assertNotNull("initialSetup must not be null.", initialSetup); + assertNotNull("beforeEach must not be null.", beforeEach); + assertNotNull("finalTearDown must not be null.", finalTearDown); + log("evaluate", "running initial setup"); + + server = initialSetup.call(); + + try { + iterateServerXmls(); + + } finally { + finalTearDown.call(); + } + } + + /** + * Iterate thru all server.xml and run the suite of tests against each. + */ + protected void iterateServerXmls() throws Throwable { + + server.setMarkToEndOfLog(); + for (String serverXmlFileName : serverXmlFileNames) { + + log("evaluate", "setting server.xml to " + serverXmlFileName); + + server.setServerConfigurationFile(serverXmlFileName); + server.checkpointRestore(); + + beforeEach.call(); + + try { + base.evaluate(); + } finally { + // TODO: if a test fails will I be able to run the other configs + // and still report the test failure? + } + + server.stopServer(); + } + } + + } + +} + diff --git a/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/FATSuite.java b/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/FATSuite.java index 1ced2355142..605a3f056e2 100644 --- a/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/FATSuite.java +++ b/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/FATSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2022 IBM Corporation and others. + * Copyright (c) 2012, 2024 IBM Corporation and others. * All rights reserved. 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 diff --git a/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/JdbcConfigTestCheckpoint.java b/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/JdbcConfigTestCheckpoint.java index 5028a5afd9c..3bb4f1daaae 100644 --- a/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/JdbcConfigTestCheckpoint.java +++ b/dev/com.ibm.ws.jbatch.open_fat/fat/src/batch/fat/junit/JdbcConfigTestCheckpoint.java @@ -1,3 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2024 IBM Corporation and others. + * All rights reserved. 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 + * http://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package batch.fat.junit; import java.util.Collections; @@ -8,14 +20,13 @@ import org.junit.runner.RunWith; import com.ibm.websphere.simplicity.log.Log; - -import batch.fat.util.BatchFATHelper; -import componenttest.annotation.CheckpointTest; - import com.ibm.ws.jbatch.test.BatchAppUtils; import com.ibm.ws.jbatch.test.FatUtils; +import batch.fat.util.BatchFATHelper; +import componenttest.annotation.CheckpointTest; import componenttest.custom.junit.runner.FATRunner; +import componenttest.topology.impl.LibertyServer; import componenttest.topology.impl.LibertyServerFactory; import io.openliberty.checkpoint.spi.CheckpointPhase; @@ -28,39 +39,6 @@ @CheckpointTest public class JdbcConfigTestCheckpoint extends BatchFATHelper { - /** - * Used with DynamicConfigRule. - */ - public static Callable initialSetup = new Callable() { - @Override - public Void call() throws Exception { - setup(); - return null; - } - }; - - /** - * Used with DynamicConfigRule. - */ - public static Callable finalTearDown = new Callable() { - @Override - public Void call() throws Exception { - tearDown(); - return null; - } - }; - - /** - * Used with DynamicConfigRule. Called after each iteration. - */ - public static Callable afterEach = new Callable() { - @Override - public Void call() throws Exception { - afterEach(); - return null; - } - }; - /** * This ClassRule will run all the tests in this class multiple times, against * all the given server.xml configuration files. @@ -69,12 +47,18 @@ public Void call() throws Exception { * tests (against all configurations) have run. */ @ClassRule - public static DynamicConfigRule dynamicConfigRule = new DynamicConfigRule().setServer(server).setInitialSetup(initialSetup).setFinalTearDown(finalTearDown).setAfterEach(afterEach).addServerXml("JDBCPersistenceCheckpoint/jdbc.config.myschema1.server.xml").addServerXml("JDBCPersistenceCheckpoint/jdbc.config.myschema2.server.xml").addServerXml("JDBCPersistenceCheckpoint/jdbc.config.myschema1.tp1.server.xml").addServerXml("JDBCPersistenceCheckpoint/jdbc.config.myschema1.tp2.server.xml"); - + public static DynamicConfigRuleCheckpoint dynamicConfigRuleCheckpoint = new DynamicConfigRuleCheckpoint() // + .setInitialSetup(JdbcConfigTestCheckpoint::setup) // + .setBeforeEach(JdbcConfigTestCheckpoint::beforeEach) // + .setFinalTearDown(JdbcConfigTestCheckpoint::tearDown) // + .addServerXml("JDBCPersistenceCheckpoint/jdbc.config.myschema1.server.xml") // + .addServerXml("JDBCPersistenceCheckpoint/jdbc.config.myschema2.server.xml") // + .addServerXml("JDBCPersistenceCheckpoint/jdbc.config.myschema1.tp1.server.xml") // + .addServerXml("JDBCPersistenceCheckpoint/jdbc.config.myschema1.tp2.server.xml"); /** * Start the server and setup the DB. */ - public static void setup() throws Exception { + public static LibertyServer setup() throws Exception { log("setup", "start server and execute DDLs"); @@ -88,23 +72,9 @@ public static void setup() throws Exception { // Start server server.setServerConfigurationFile("JDBCPersistenceCheckpoint/jdbc.config.myschema1.server.xml"); - server.setCheckpoint(CheckpointPhase.AFTER_APP_START, true, null); - server.startServer("JdbcConfig.log"); - - // Apply config and restore - server.waitForStringInLog("CWWKF0011I", 20000); - FatUtils.waitForSmarterPlanet(server); - - // Setup chunk test data - executeSql("jdbc/batch", getChunkInTableSql()); - executeSql("jdbc/batch", getChunkOutTableSql("APP.OUT4")); - - executeSql("jdbc/myds", getChunkInTableSql()); - executeSql("jdbc/myds", getChunkOutTableSql("APP.OUT1")); - executeSql("jdbc/myds", getChunkOutTableSql("APP.OUT2")); - - executeSql("jdbc/mydsNonTran", getChunkInTableSql()); - executeSql("jdbc/mydsNonTran", getChunkOutTableSql("APP.OUT3")); + server.setCheckpoint(CheckpointPhase.AFTER_APP_START, false, null); + server.startServer("JdbcConfigTestCheckpoint.log"); + return server; } /** @@ -118,11 +88,24 @@ public static void tearDown() throws Exception { } /** - * Clear out the OUT4 table used by the chunk tests. + * Do a Checkpoint restore and setup chunk test data. */ - public static void afterEach() throws Exception { - log("afterEach", ""); - executeSql(DFLT_PERSISTENCE_JNDI, "DELETE FROM APP.OUT4;"); + public static void beforeEach() throws Exception { + log("beforeEach", ""); + // Apply config and restore + server.waitForStringInLog("CWWKF0011I", 20000); + FatUtils.waitForSmarterPlanet(server); + + // Setup chunk test data + executeSql("jdbc/batch", getChunkInTableSql()); + executeSql("jdbc/batch", getChunkOutTableSql("APP.OUT4")); + + executeSql("jdbc/myds", getChunkInTableSql()); + executeSql("jdbc/myds", getChunkOutTableSql("APP.OUT1")); + executeSql("jdbc/myds", getChunkOutTableSql("APP.OUT2")); + + executeSql("jdbc/mydsNonTran", getChunkInTableSql()); + executeSql("jdbc/mydsNonTran", getChunkOutTableSql("APP.OUT3")); } /** diff --git a/dev/com.ibm.ws.jca/src/com/ibm/ws/jca/internal/ConnectorModuleRuntimeContainer.java b/dev/com.ibm.ws.jca/src/com/ibm/ws/jca/internal/ConnectorModuleRuntimeContainer.java index 3eeb8b59bdb..c04fbd467fd 100644 --- a/dev/com.ibm.ws.jca/src/com/ibm/ws/jca/internal/ConnectorModuleRuntimeContainer.java +++ b/dev/com.ibm.ws.jca/src/com/ibm/ws/jca/internal/ConnectorModuleRuntimeContainer.java @@ -1,10 +1,10 @@ /******************************************************************************* - * Copyright (c) 2013, 2014 IBM Corporation and others. + * Copyright (c) 2013, 2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -22,7 +22,6 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.resource.spi.BootstrapContext; @@ -34,7 +33,7 @@ import org.osgi.framework.ServiceReference; import org.osgi.service.cm.Configuration; import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.ConfigurationPolicy; import org.osgi.service.component.annotations.Reference; @@ -64,18 +63,13 @@ public class ConnectorModuleRuntimeContainer implements ModuleRuntimeContainer { private static final TraceComponent tc = Tr.register(ConnectorModuleRuntimeContainer.class); - private BundleContext bundleContext = null; + private final BundleContext bundleContext; - private ConfigurationAdmin configAdmin; + private final ConfigurationAdmin configAdmin; - private FutureMonitor futureMonitor; + private final FutureMonitor futureMonitor; - /** - * Read/write lock for bundleContext - */ - private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - - private MetaDataService metaDataService; + private final MetaDataService metaDataService; private final ConcurrentHashMap moduleMetatype = new ConcurrentHashMap();; @@ -84,50 +78,17 @@ public class ConnectorModuleRuntimeContainer implements ModuleRuntimeContainer { */ private final ConcurrentHashMap serviceListeners = new ConcurrentHashMap(); - protected void activate(ComponentContext context) { - lock.writeLock().lock(); - try { - bundleContext = Utils.priv.getBundleContext(context); - } finally { - lock.writeLock().unlock(); - } - } - - protected void deactivate(ComponentContext context) { - lock.writeLock().lock(); - try { - bundleContext = null; - } finally { - lock.writeLock().unlock(); - } - } - - @Reference - protected void setConfigurationAdmin(ConfigurationAdmin configAdmin) { + @Activate + public ConnectorModuleRuntimeContainer(BundleContext bundleContext, // + @Reference ConfigurationAdmin configAdmin, + @Reference FutureMonitor futureMonitor, + @Reference MetaDataService metaDataService) { + this.bundleContext = bundleContext; this.configAdmin = configAdmin; - } - - protected void unsetConfigurationAdmin(ConfigurationAdmin configAdmin) { - this.configAdmin = null; - } - - @Reference(name = "futureMonitor") - protected void setFutureMonitor(FutureMonitor futureMonitor) { this.futureMonitor = futureMonitor; - } - - protected void unsetFutureMonitor(FutureMonitor futureMonitor) { - this.futureMonitor = null; - } - - @Reference(name = "metaDataService") - protected void setMetaDataService(MetaDataService metaDataService) { this.metaDataService = metaDataService; } - protected void unsetMetaDataService(MetaDataService metaDataService) { - } - /* * (non-Javadoc) * @@ -152,17 +113,13 @@ public ModuleMetaData createModuleMetaData(ExtendedModuleInfo moduleInfo) throws */ private void removeServiceListeners(String id) { final ServiceListener[] listeners = serviceListeners.remove(id); - if (listeners != null) - for (ServiceListener listener : listeners) + if (listeners != null) { + for (ServiceListener listener : listeners) { if (listener != null) { - lock.readLock().lock(); - try { - if (bundleContext != null) - bundleContext.removeServiceListener(listener); - } finally { - lock.readLock().unlock(); - } + bundleContext.removeServiceListener(listener); } + } + } } private class RARInstallListener implements ServiceListener { @@ -227,31 +184,25 @@ private RARInstallListener(String id, String bootstrapContextFactoryPid, boolean final ServiceListener[] listeners = new ServiceListener[4]; serviceListeners.put(id, listeners); - lock.readLock().lock(); - try { - if (bundleContext != null) { - // properties for resourceAdapter - bundleContext.addServiceListener(listeners[0] = this, - "(&(objectClass=ja*.resource.spi.BootstrapContext)(id=" + id + "))"); - - // properties for adminObject, jmsDestination, jmsQueue, jmsTopic - bundleContext.addServiceListener(listeners[1] = new ResourceListener(), - "(&(objectClass=com.ibm.ws.jca.service.AdminObjectService)(properties.0.config.referenceType=com.ibm.ws.jca.*.properties." - + id + ".*))"); - - // properties for connectionFactory, jmsConnectionFactory, jmsQueueConnectionFactory, jmsTopicConnectionFactory - bundleContext.addServiceListener(listeners[2] = new ResourceListener(), - "(&(objectClass=com.ibm.ws.jca.service.ConnectionFactoryService)(properties.0.config.referenceType=com.ibm.ws.jca.*onnectionFactory.properties." - + id + ".*))"); - - // properties for activationSpec, jmsActivationSpec - bundleContext.addServiceListener(listeners[3] = new ResourceListener(), - "(&(objectClass=com.ibm.ws.jca.service.EndpointActivationService)(properties.0.config.referenceType=com.ibm.ws.jca.*ctivationSpec.properties." - + id + ".*))"); - } - } finally { - lock.readLock().unlock(); - } + // properties for resourceAdapter + bundleContext.addServiceListener(listeners[0] = this, + "(&(objectClass=ja*.resource.spi.BootstrapContext)(id=" + id + "))"); + + // properties for adminObject, jmsDestination, jmsQueue, jmsTopic + bundleContext.addServiceListener(listeners[1] = new ResourceListener(), + "(&(objectClass=com.ibm.ws.jca.service.AdminObjectService)(properties.0.config.referenceType=com.ibm.ws.jca.*.properties." + + id + ".*))"); + + // properties for connectionFactory, jmsConnectionFactory, jmsQueueConnectionFactory, jmsTopicConnectionFactory + bundleContext.addServiceListener(listeners[2] = new ResourceListener(), + "(&(objectClass=com.ibm.ws.jca.service.ConnectionFactoryService)(properties.0.config.referenceType=com.ibm.ws.jca.*onnectionFactory.properties." + + id + ".*))"); + + // properties for activationSpec, jmsActivationSpec + bundleContext.addServiceListener(listeners[3] = new ResourceListener(), + "(&(objectClass=com.ibm.ws.jca.service.EndpointActivationService)(properties.0.config.referenceType=com.ibm.ws.jca.*ctivationSpec.properties." + + id + ".*))"); + } /** @@ -282,13 +233,9 @@ public void serviceChanged(ServiceEvent event) { if ("com.ibm.ws.jca.resourceAdapter.properties".equals(pid)) { latch.countDown(); if (autoStart) { - lock.readLock().lock(); try { - if (bundleContext != null) - Utils.priv.getService(bundleContext, event.getServiceReference()); + Utils.priv.getService(bundleContext, event.getServiceReference()); } catch (Throwable x) { - } finally { - lock.readLock().unlock(); } } } else { @@ -403,12 +350,7 @@ public Future startModule(ExtendedModuleInfo moduleInfo) throws StateCh try { Collection> refs; - lock.readLock().lock(); - try { - refs = bundleContext == null ? null : Utils.priv.getServiceReferences(bundleContext, BootstrapContext.class, "(id=" + id + ')'); - } finally { - lock.readLock().unlock(); - } + refs = Utils.priv.getServiceReferences(bundleContext, BootstrapContext.class, "(id=" + id + ')'); if (refs == null || refs.isEmpty()) { FFDCFilter.processException(x, getClass().getName(), "420", this, new Object[] { id, bootstrapContextFactoryPid }); futureMonitor.setResult(rarInstallListener.future, x); diff --git a/dev/com.ibm.ws.jsp.2.3_fat/fat/src/com/ibm/ws/jsp23/fat/tests/JSP23JSP22ServerTest.java b/dev/com.ibm.ws.jsp.2.3_fat/fat/src/com/ibm/ws/jsp23/fat/tests/JSP23JSP22ServerTest.java index e3f7af144cb..8b6f4a282d4 100644 --- a/dev/com.ibm.ws.jsp.2.3_fat/fat/src/com/ibm/ws/jsp23/fat/tests/JSP23JSP22ServerTest.java +++ b/dev/com.ibm.ws.jsp.2.3_fat/fat/src/com/ibm/ws/jsp23/fat/tests/JSP23JSP22ServerTest.java @@ -88,10 +88,9 @@ public static void testCleanup() throws Exception { * * @throws Exception */ - @Test @SkipForRepeat({ SkipForRepeat.EE9_OR_LATER_FEATURES }) - public void testJsp23to22FeatureChange() throws Exception { + public void testJsp23toJsp22FeatureChange() throws Exception { WebConversation wc = new WebConversation(); wc.setExceptionsThrownOnErrorStatus(false); @@ -132,7 +131,7 @@ public void testJsp23to22FeatureChange() throws Exception { */ @Test @SkipForRepeat({ SkipForRepeat.NO_MODIFICATION, SkipForRepeat.EE10_OR_LATER_FEATURES }) - public void testJsp30to23FeatureChange() throws Exception { + public void testPages30toJsp23FeatureChange() throws Exception { WebConversation wc = new WebConversation(); wc.setExceptionsThrownOnErrorStatus(false); @@ -174,7 +173,7 @@ public void testJsp30to23FeatureChange() throws Exception { */ @Test @SkipForRepeat({ SkipForRepeat.NO_MODIFICATION, SkipForRepeat.EE9_FEATURES, SkipForRepeat.EE11_OR_LATER_FEATURES }) - public void testJsp31to23FeatureChange() throws Exception { + public void testPages31toJsp23FeatureChange() throws Exception { WebConversation wc = new WebConversation(); wc.setExceptionsThrownOnErrorStatus(false); @@ -215,8 +214,8 @@ public void testJsp31to23FeatureChange() throws Exception { * @throws Exception */ @Test - @SkipForRepeat({ SkipForRepeat.NO_MODIFICATION, SkipForRepeat.EE9_OR_LATER_FEATURES }) - public void testJsp40to31FeatureChange() throws Exception { + @SkipForRepeat({ SkipForRepeat.NO_MODIFICATION, SkipForRepeat.EE9_FEATURES, SkipForRepeat.EE10_FEATURES }) + public void testPages40toJsp31FeatureChange() throws Exception { WebConversation wc = new WebConversation(); wc.setExceptionsThrownOnErrorStatus(false); diff --git a/dev/com.ibm.ws.kernel.boot.common/src/com/ibm/ws/kernel/boot/classloader/NameBasedClassLoaderLock.java b/dev/com.ibm.ws.kernel.boot.common/src/com/ibm/ws/kernel/boot/classloader/NameBasedClassLoaderLock.java index 86ac3dc1a70..bd8c528626a 100644 --- a/dev/com.ibm.ws.kernel.boot.common/src/com/ibm/ws/kernel/boot/classloader/NameBasedClassLoaderLock.java +++ b/dev/com.ibm.ws.kernel.boot.common/src/com/ibm/ws/kernel/boot/classloader/NameBasedClassLoaderLock.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 IBM Corporation and others. + * Copyright (c) 2023, 2024 IBM Corporation and others. * All rights reserved. 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 @@ -9,17 +9,25 @@ *******************************************************************************/ package com.ibm.ws.kernel.boot.classloader; -import java.util.function.Supplier; +import java.util.function.Function; public class NameBasedClassLoaderLock { - public static final Supplier LOCK_SUPPLIER = new Supplier() { + public static final Function LOCK_SUPPLIER = new Function() { @Override - public NameBasedClassLoaderLock get() { - return new NameBasedClassLoaderLock(); + public NameBasedClassLoaderLock apply(String className) { + return new NameBasedClassLoaderLock(className); } }; - private NameBasedClassLoaderLock() { + private final String className; + + private NameBasedClassLoaderLock(String className) { + this.className = className; + } + + @Override + public String toString() { + return "NameBasedClassLoaderLock: " + className; } } diff --git a/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/utils/KeyBasedLockStore.java b/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/utils/KeyBasedLockStore.java index fb19038f54d..b9937b85690 100644 --- a/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/utils/KeyBasedLockStore.java +++ b/dev/com.ibm.ws.kernel.boot.core/src/com/ibm/ws/kernel/boot/utils/KeyBasedLockStore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022, 2023 IBM Corporation and others. + * Copyright (c) 2022, 2024 IBM Corporation and others. * All rights reserved. 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 @@ -15,18 +15,18 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; +import java.util.function.Function; import com.ibm.websphere.ras.annotation.Trivial; @Trivial public final class KeyBasedLockStore { - private final ReferenceQueue refQueue = new ReferenceQueue<>(); + final ReferenceQueue refQueue = new ReferenceQueue<>(); private final ConcurrentHashMap lockMap = new ConcurrentHashMap<>(); - private final Supplier lockCreator; + private final Function lockCreator; - public KeyBasedLockStore(Supplier lockCreator) { + public KeyBasedLockStore(Function lockCreator) { this.lockCreator = lockCreator; } @@ -48,7 +48,7 @@ public final Lock getLock(Key key) { return lock; } - lock = lockCreator.get(); + lock = lockCreator.apply(key); while (true) { LockWeakRef retVal = lockMap.putIfAbsent(key, new LockWeakRef(lock, key)); diff --git a/dev/com.ibm.ws.kernel.boot/publish/platform/kernel-1.0.mf b/dev/com.ibm.ws.kernel.boot/publish/platform/kernel-1.0.mf index 538e8596690..0c569d615ea 100644 --- a/dev/com.ibm.ws.kernel.boot/publish/platform/kernel-1.0.mf +++ b/dev/com.ibm.ws.kernel.boot/publish/platform/kernel-1.0.mf @@ -56,7 +56,7 @@ Subsystem-Content: README.TXT; location:="README.TXT"; type="file", com.ibm.wsspi.org.osgi.service.log; version="[1.2,1.3)"; location:="dev/spi/spec/"; type="jar", com.ibm.wsspi.org.osgi.service.metatype; version="[1.1,1.2)"; location:="dev/spi/spec/"; type="jar", com.ibm.wsspi.org.osgi.service.metatype.annotations; version="[1,1.1)"; location:="dev/spi/spec/"; type="jar", - com.ibm.wsspi.thirdparty.equinox; version="[1.1,1.4)"; location:="dev/spi/third-party/"; type="jar", + com.ibm.wsspi.thirdparty.equinox; version="[1.1,1.5)"; location:="dev/spi/third-party/"; type="jar", com.ibm.websphere.appserver.api.config; version="[1,1.3)"; type="jar"; location:="dev/api/ibm/", com.ibm.websphere.appserver.api.config_1.2-javadoc.zip; type="file"; location:="dev/api/ibm/javadoc/com.ibm.websphere.appserver.api.config_1.2-javadoc.zip", com.ibm.ws.config.schemagen; version="[1,1.1)"; type="jar", diff --git a/dev/com.ibm.ws.kernel.feature_fat/publish/servers/com.ibm.ws.kernel.active.condition/server.xml b/dev/com.ibm.ws.kernel.feature_fat/publish/servers/com.ibm.ws.kernel.active.condition/server.xml index 2a2c6d0a55d..a937993a6c2 100755 --- a/dev/com.ibm.ws.kernel.feature_fat/publish/servers/com.ibm.ws.kernel.active.condition/server.xml +++ b/dev/com.ibm.ws.kernel.feature_fat/publish/servers/com.ibm.ws.kernel.active.condition/server.xml @@ -5,5 +5,5 @@ test.active.condition-1.0 - + diff --git a/dev/com.ibm.ws.kernel.feature_fat/test.active.condition.bnd b/dev/com.ibm.ws.kernel.feature_fat/test.active.condition.bnd index d4ec46b727a..8a976dab9e8 100644 --- a/dev/com.ibm.ws.kernel.feature_fat/test.active.condition.bnd +++ b/dev/com.ibm.ws.kernel.feature_fat/test.active.condition.bnd @@ -4,7 +4,7 @@ # are made available under the terms of the Eclipse Public License 2.0 # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-2.0/ -# +# # SPDX-License-Identifier: EPL-2.0 # # Contributors: diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/JmsBodyType.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/JmsBodyType.java index 7d39f533b55..3f262df9548 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/JmsBodyType.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/JmsBodyType.java @@ -1,152 +1,153 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp; -import com.ibm.websphere.sib.SIApiConstants; -import com.ibm.ws.sib.utils.ras.SibTr; +import static com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled; +import static com.ibm.websphere.sib.SIApiConstants.JMS_FORMAT; +import static com.ibm.websphere.sib.SIApiConstants.JMS_FORMAT_BYTES; +import static com.ibm.websphere.sib.SIApiConstants.JMS_FORMAT_MAP; +import static com.ibm.websphere.sib.SIApiConstants.JMS_FORMAT_OBJECT; +import static com.ibm.websphere.sib.SIApiConstants.JMS_FORMAT_STREAM; +import static com.ibm.websphere.sib.SIApiConstants.JMS_FORMAT_TEXT; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_BUNDLE; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_GROUP; +import static com.ibm.ws.sib.utils.ras.SibTr.debug; +import static com.ibm.ws.sib.utils.ras.SibTr.entry; +import static com.ibm.ws.sib.utils.ras.SibTr.exit; +import static com.ibm.ws.sib.utils.ras.SibTr.register; +import static java.util.Collections.unmodifiableMap; + +import java.util.HashMap; +import java.util.Map; + import com.ibm.websphere.ras.TraceComponent; /** * JmsBodyType is a type-safe enumeration for JmsBody types. */ -public final class JmsBodyType implements IntAble { - - private static TraceComponent tc = SibTr.register(JmsBodyType.class, MfpConstants.MSG_GROUP, MfpConstants.MSG_BUNDLE); - - /** Integer value of the NULL JMsBodyType */ - public final static int NULL_INT = 0; - /** Integer value of the BYTES JMsBodyType */ - public final static int BYTES_INT = 1; - /** Integer value of the MAP JMsBodyType */ - public final static int MAP_INT = 2; - /** Integer value of the OBJECT JMsBodyType */ - public final static int OBJECT_INT = 3; - /** Integer value of the STREAM JMsBodyType */ - public final static int STREAM_INT = 4; - /** Integer value of the TEXT JMsBodyType */ - public final static int TEXT_INT = 5; - - - - /** Constant denoting a null-bodied JMS Message */ - public final static JmsBodyType NULL = new JmsBodyType("NULL" ,(byte)NULL_INT); - - /** Constant denoting JmsBody Type of Bytes */ - public final static JmsBodyType BYTES = new JmsBodyType("BYTES" ,(byte)BYTES_INT); - - /** Constant denoting JmsBody Type of Map */ - public final static JmsBodyType MAP = new JmsBodyType("MAP" ,(byte)MAP_INT); - - /** Constant denoting JmsBody Type of Object */ - public final static JmsBodyType OBJECT = new JmsBodyType("OBJECT",(byte)OBJECT_INT); - - /** Constant denoting JmsBody Type of Stream */ - public final static JmsBodyType STREAM = new JmsBodyType("STREAM",(byte)STREAM_INT); - - /** Constant denoting JmsBody Type of Text */ - public final static JmsBodyType TEXT = new JmsBodyType("TEXT" ,(byte)TEXT_INT); - - /* Array of defined JmsBodyTypes - needed by getJmsBodyType */ - private final static JmsBodyType[] set = {NULL - ,BYTES - ,MAP - ,OBJECT - ,STREAM - ,TEXT - }; - - private String name; - private Byte value; - private int intValue; - - /* Private constructor - ensures the 'constants' define here are the total set. */ - private JmsBodyType(String aName, byte aValue) { - name = aName; - value = new Byte(aValue); - intValue = (int)aValue; - } - - /** - * Return the appropriate JMSBodyType for a specific format string - * - * @param format A String corresponding to the SDO format of a JMS Message - * - * @return JmsBodyType The JmsBodyType singleton which maps to the given format string - */ - public static JmsBodyType getBodyType(String format) { - if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(tc, "getBodyType"); - - JmsBodyType result = null; - if (format.equals(SIApiConstants.JMS_FORMAT_BYTES)) - result = BYTES; - else if (format.equals(SIApiConstants.JMS_FORMAT_TEXT)) - result = TEXT; - else if (format.equals(SIApiConstants.JMS_FORMAT_OBJECT)) - result = OBJECT; - else if (format.equals(SIApiConstants.JMS_FORMAT_STREAM)) - result = STREAM; - else if (format.equals(SIApiConstants.JMS_FORMAT_MAP)) - result = MAP; - else if (format.equals(SIApiConstants.JMS_FORMAT)) - result = NULL; - - if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(tc, "getBodyType"); - return result; - } - - /** - * Returns the corresponding JmsBodyType for a given Byte. - * This method should NOT be called by any code outside the TEXT component. - * It is only public so that it can be accessed by sub-packages. - * - * @param aValue The Byte for which an JmsBodyType is required. - * - * @return The corresponding JmsBodyType - */ - public final static JmsBodyType getJmsBodyType(Byte aValue) { - if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(tc,"Value = " + aValue); - return set[aValue.intValue()]; - } - - /** - * Returns the Byte representation of the JmsBodyType. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @return The Byte representation of the instance. - */ - public final Byte toByte() { - return value; - } - - /** - * Returns the integer representation of the JmsBodyType. - * This method should NOT be called by any code outside the SIBus. - * It is only public so that it can be accessed by SIBus components. - * - * @return The int representation of the instance. - */ - public final int toInt() { - return intValue; - } - - /** - * Returns the name of the JmsBodyType. - * - * @return The name of the instance. - */ - public final String toString() { - return name; - } - +public enum JmsBodyType implements IntAble { + /** Constant denoting a null-bodied JMS Message */ + NULL(0, JMS_FORMAT), + /** Constant denoting JmsBody Type of Bytes */ + BYTES(1, JMS_FORMAT_BYTES), + /** Constant denoting JmsBody Type of Map */ + MAP(2, JMS_FORMAT_MAP), + /** Constant denoting JmsBody Type of Object */ + OBJECT(3, JMS_FORMAT_OBJECT), + /** Constant denoting JmsBody Type of Stream */ + STREAM(4, JMS_FORMAT_STREAM), + /** Constant denoting JmsBody Type of Text */ + TEXT(5, JMS_FORMAT_TEXT), + ; + + private static final TraceComponent tc = register(JmsBodyType.class, MSG_GROUP, MSG_BUNDLE); + + // TODO remove constants once all dependencies addressed + public static final int NULL_INT = 0; + public static final int BYTES_INT = 1; + public static final int MAP_INT = 2; + public static final int OBJECT_INT = 3; + public static final int STREAM_INT = 4; + public static final int TEXT_INT = 5; + + private static final Map types; + private static final Map typesByFormat; + + static { + Map map = new HashMap<>(); + Map formatMap = new HashMap<>(); + for (JmsBodyType type: values()) { + map.put(type.toInt(), type); + formatMap.put(type.format, type); + } + types = unmodifiableMap(map); + typesByFormat = unmodifiableMap(formatMap); + } + + private final String format; + private final Byte value; + private final int intValue; + + private JmsBodyType(int aValue, String sdoFormat) { + format = sdoFormat; + value = Byte.valueOf((byte)aValue); + intValue = aValue; + } + + /** + * Return the appropriate JMSBodyType for a specific format string + * + * @param format A String corresponding to the SDO format of a JMS Message + * + * @return JmsBodyType The JmsBodyType singleton which maps to the given format string + */ + public static JmsBodyType getBodyType(String format) { + if (isAnyTracingEnabled() && tc.isEntryEnabled()) entry(tc, "getBodyType"); + + JmsBodyType result = typesByFormat.get(format); + + if (isAnyTracingEnabled() && tc.isEntryEnabled()) exit(tc, "getBodyType", result); + return result; + } + + /** + * Returns the corresponding JmsBodyType for a given Byte. + * This method should NOT be called by any code outside the TEXT component. + * It is only public so that it can be accessed by sub-packages. + * + * @param aValue The Byte for which an JmsBodyType is required. + * + * @return The corresponding JmsBodyType + */ + public static final JmsBodyType getJmsBodyType(Byte aValue) { + if (isAnyTracingEnabled() && tc.isDebugEnabled()) debug(tc,"Value = " + aValue); + return types.get(aValue.intValue()); + } + + /** + * Returns the corresponding JmsBodyType for a given integer. + * This method should NOT be called by any code outside the TEXT component. + * It is only public so that it can be accessed by sub-packages. + * + * @param aValue The integer for which an JmsBodyType is required. + * + * @return The corresponding JmsBodyType + */ + public static final JmsBodyType getJmsBodyType(int aValue) { + if (isAnyTracingEnabled() && tc.isDebugEnabled()) debug(tc,"Value = " + aValue); + return types.get(aValue); + } + + /** + * Returns the Byte representation of the JmsBodyType. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @return The Byte representation of the instance. + */ + public final Byte toByte() { + return value; + } + + /** + * Returns the integer representation of the JmsBodyType. + * This method should NOT be called by any code outside the SIBus. + * It is only public so that it can be accessed by SIBus components. + * + * @return The int representation of the instance. + */ + public final int toInt() { + return intValue; + } } diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/control/ControlMessageType.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/control/ControlMessageType.java index 84e33c66aee..165934a011d 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/control/ControlMessageType.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/control/ControlMessageType.java @@ -1,239 +1,173 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp.control; -import com.ibm.ws.sib.mfp.*; -import com.ibm.ws.sib.utils.ras.SibTr; +import static com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_BUNDLE; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_GROUP; +import static com.ibm.ws.sib.utils.ras.SibTr.debug; +import static com.ibm.ws.sib.utils.ras.SibTr.register; +import static java.util.Collections.unmodifiableMap; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + import com.ibm.websphere.ras.TraceComponent; +import com.ibm.ws.sib.mfp.IntAble; /** * ControlMessageType is a type-safe enumeration which indicates the type of a * Control Message. */ -public final class ControlMessageType implements IntAble { - - private static TraceComponent tc = SibTr.register(ControlMessageType.class, MfpConstants.MSG_GROUP, MfpConstants.MSG_BUNDLE); - - /** Integer value of the Control Message Types */ - public final static int UNKNOWN_INT = 0; - public final static int ACKEXPECTED_INT = 1; - public final static int SILENCE_INT = 2; - public final static int ACK_INT = 3; - public final static int NACK_INT = 4; - public final static int PREVALUE_INT = 5; - public final static int ACCEPT_INT = 6; - public final static int REJECT_INT = 7; - public final static int DECISION_INT = 8; - public final static int REQUEST_INT = 9; - public final static int REQUESTACK_INT = 10; - public final static int REQUESTHIGHESTGENERATEDTICK_INT = 11; - public final static int HIGHESTGENERATEDTICK_INT = 12; - public final static int RESETREQUESTACK_INT = 13; - public final static int RESETREQUESTACKACK_INT = 14; - public final static int BROWSEGET_INT = 15; - public final static int BROWSEEND_INT = 16; - public final static int BROWSESTATUS_INT = 17; - public final static int COMPLETED_INT = 18; - public final static int DECISIONEXPECTED_INT = 19; - public final static int CREATESTREAM_INT = 20; - public final static int AREYOUFLUSHED_INT = 21; - public final static int FLUSHED_INT = 22; - public final static int NOTFLUSHED_INT = 23; - public final static int REQUESTFLUSH_INT = 24; - public final static int REQUESTCARDINALITYINFO_INT = 25; - public final static int CARDINALITYINFO_INT = 26; - public final static int CREATEDURABLE_INT = 27; - public final static int DELETEDURABLE_INT = 28; - public final static int DURABLECONFIRM_INT = 29; - - - /** Constant denoting an indeterminate DDD Message */ - public final static ControlMessageType UNKNOWN = new ControlMessageType("UNKNOWN" ,(byte)UNKNOWN_INT ); - - /** Constant denoting an Ack Expected Messge */ - public final static ControlMessageType ACKEXPECTED = new ControlMessageType("ACKEXPECTED" ,(byte)ACKEXPECTED_INT ); - - /** Constant denoting a Silence Message */ - public final static ControlMessageType SILENCE = new ControlMessageType("SILENCE" ,(byte)SILENCE_INT ); - - /** Constant denoting an Ack Message */ - public final static ControlMessageType ACK = new ControlMessageType("ACK" ,(byte)ACK_INT ); - - /** Constant denoting a Nack Message */ - public final static ControlMessageType NACK = new ControlMessageType("NACK" ,(byte)NACK_INT ); - - /** Constant denoting a Prevalue Message */ - public final static ControlMessageType PREVALUE = new ControlMessageType("PREVALUE" ,(byte)PREVALUE_INT ); - - /** Constant denoting an Accept Message */ - public final static ControlMessageType ACCEPT = new ControlMessageType("ACCEPT" ,(byte)ACCEPT_INT ); - - /** Constant denoting a Reject Message */ - public final static ControlMessageType REJECT = new ControlMessageType("REJECT" ,(byte)REJECT_INT ); - - /** Constant denoting a Decision Message */ - public final static ControlMessageType DECISION = new ControlMessageType("DECISION" ,(byte)DECISION_INT ); - - /** Constant denoting a Request Message */ - public final static ControlMessageType REQUEST = new ControlMessageType("REQUEST ",(byte)REQUEST_INT ); - - /** Constant denoting a RequestAck Message */ - public final static ControlMessageType REQUESTACK = new ControlMessageType("REQUESTACK ",(byte)REQUESTACK_INT ); - - /** Constant denoting a RequestHighestGeneratedTick Message */ - public final static ControlMessageType REQUESTHIGHESTGENERATEDTICK = new ControlMessageType("REQUESTHIGHESTGENERATEDTICK",(byte)REQUESTHIGHESTGENERATEDTICK_INT ); - - /** Constant denoting a HighestGeneratedTick Message */ - public final static ControlMessageType HIGHESTGENERATEDTICK = new ControlMessageType("HIGHESTGENERATEDTICK ",(byte)HIGHESTGENERATEDTICK_INT ); - - /** Constant denoting a RequestRequestAck Message */ - public final static ControlMessageType RESETREQUESTACK = new ControlMessageType("RESETREQUESTACK ",(byte)RESETREQUESTACK_INT ); - - /** Constant denoting a RequestRequestAckAck Message */ - public final static ControlMessageType RESETREQUESTACKACK = new ControlMessageType("RESETREQUESTACKACK ",(byte)RESETREQUESTACKACK_INT ); - - /** Constant denoting a BrowseGet Message */ - public final static ControlMessageType BROWSEGET = new ControlMessageType("BROWSEGET ",(byte)BROWSEGET_INT ); - - /** Constant denoting a BrowseEnd Message */ - public final static ControlMessageType BROWSEEND = new ControlMessageType("BROWSEEND ",(byte)BROWSEEND_INT ); - - /** Constant denoting a BrowseStatus Message */ - public final static ControlMessageType BROWSESTATUS = new ControlMessageType("BROWSESTATUS ",(byte)BROWSESTATUS_INT ); - - /** Constant denoting a Completed Message */ - public final static ControlMessageType COMPLETED = new ControlMessageType("COMPLETED ",(byte)COMPLETED_INT ); - - /** Constant denoting a DecisionExpected Message */ - public final static ControlMessageType DECISIONEXPECTED = new ControlMessageType("DECISIONEXPECTED ",(byte)DECISIONEXPECTED_INT ); - - /** Constant denoting a CreateStream Message */ - public final static ControlMessageType CREATESTREAM = new ControlMessageType("CREATESTREAM ",(byte)CREATESTREAM_INT ); - - /** Constant denoting an AreYouFlushed Message */ - public final static ControlMessageType AREYOUFLUSHED = new ControlMessageType("AREYOUFLUSHED ",(byte)AREYOUFLUSHED_INT ); - - /** Constant denoting a Flushed Message */ - public final static ControlMessageType FLUSHED = new ControlMessageType("FLUSHED ",(byte)FLUSHED_INT ); - - /** Constant denoting a NotFlushed Message */ - public final static ControlMessageType NOTFLUSHED = new ControlMessageType("NOTFLUSHED ",(byte)NOTFLUSHED_INT ); - - /** Constant denoting a RequestFlushed Message */ - public final static ControlMessageType REQUESTFLUSH = new ControlMessageType("REQUESTFLUSH ",(byte)REQUESTFLUSH_INT ); - - /** Constant denoting a RequestCardinalityInfo Message */ - public final static ControlMessageType REQUESTCARDINALITYINFO = new ControlMessageType("REQUESTCARDINALITYINFO ",(byte)REQUESTCARDINALITYINFO_INT ); - - /** Constant denoting a CardinalityInfo Message */ - public final static ControlMessageType CARDINALITYINFO = new ControlMessageType("CARDINALITYINFO ",(byte)CARDINALITYINFO_INT ); - - /** Constant denoting a CreateDurable Message */ - public final static ControlMessageType CREATEDURABLE = new ControlMessageType("CREATEDURABLE ",(byte)CREATEDURABLE_INT ); - - /** Constant denoting a DeleteDurable Message */ - public final static ControlMessageType DELETEDURABLE = new ControlMessageType("DELETEDURABLE ",(byte)DELETEDURABLE_INT ); - - /** Constant denoting a DurableConfirm Message */ - public final static ControlMessageType DURABLECONFIRM = new ControlMessageType("DURABLECONFIRM ",(byte)DURABLECONFIRM_INT ); - - /* Array of defined ControlMessageTypes - needed by getControlMessageType */ - private final static ControlMessageType[] set = {UNKNOWN - ,ACKEXPECTED - ,SILENCE - ,ACK - ,NACK - ,PREVALUE - ,ACCEPT - ,REJECT - ,DECISION - ,REQUEST - ,REQUESTACK - ,REQUESTHIGHESTGENERATEDTICK - ,HIGHESTGENERATEDTICK - ,RESETREQUESTACK - ,RESETREQUESTACKACK - ,BROWSEGET - ,BROWSEEND - ,BROWSESTATUS - ,COMPLETED - ,DECISIONEXPECTED - ,CREATESTREAM - ,AREYOUFLUSHED - ,FLUSHED - ,NOTFLUSHED - ,REQUESTFLUSH - ,REQUESTCARDINALITYINFO - ,CARDINALITYINFO - ,CREATEDURABLE - ,DELETEDURABLE - ,DURABLECONFIRM - }; - - private String name; - private Byte value; - private int intValue; - - /* Private constructor - ensures the 'constants' defined here are the total set. */ - private ControlMessageType(String aName, byte aValue) { - name = aName; - value = Byte.valueOf(aValue); - intValue = (int)aValue; - } - - /** - * Returns the corresponding ControlMessageType for a given integer. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @param aValue The integer for which an ControlMessageType is required. - * - * @return The corresponding ControlMessageType - */ - public final static ControlMessageType getControlMessageType(Byte aValue) { - if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(tc,"Value = " + aValue); - return set[aValue.intValue()]; - } - - /** - * Returns the Byte representation of the ControlMessageType. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @return The Byte representation of the instance. - */ - public final Byte toByte() { - return value; - } - - /** - * Returns the integer representation of the ControlMessageType. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @return The int representation of the instance. - */ - public final int toInt() { - return intValue; - } - - /** - * Returns the name of the ControlMessageType. - * - * @return The name of the instance. - */ - public final String toString() { - return name; - } - +public enum ControlMessageType implements IntAble { + /** Constant denoting an indeterminate DDD Message */ + UNKNOWN(0, false), + /** Constant denoting an Ack Expected Messge */ + ACKEXPECTED(1, false), + /** Constant denoting a Silence Message */ + SILENCE(2, false), + /** Constant denoting an Ack Message */ + ACK(3, false), + /** Constant denoting a Nack Message */ + NACK(4, false), + /** Constant denoting a Prevalue Message */ + PREVALUE(5, false), + /** Constant denoting an Accept Message */ + ACCEPT(6, false), + /** Constant denoting a Reject Message */ + REJECT(7, false), + /** Constant denoting a Decision Message */ + DECISION(8, false), + /** Constant denoting a Request Message */ + REQUEST(9), + /** Constant denoting a RequestAck Message */ + REQUESTACK(10), + /** Constant denoting a RequestHighestGeneratedTick Message */ + REQUESTHIGHESTGENERATEDTICK(11), + /** Constant denoting a HighestGeneratedTick Message */ + HIGHESTGENERATEDTICK(12), + /** Constant denoting a RequestRequestAck Message */ + RESETREQUESTACK(13), + /** Constant denoting a RequestRequestAckAck Message */ + RESETREQUESTACKACK(14), + /** Constant denoting a BrowseGet Message */ + BROWSEGET(15), + /** Constant denoting a BrowseEnd Message */ + BROWSEEND(16), + /** Constant denoting a BrowseStatus Message */ + BROWSESTATUS(17), + /** Constant denoting a Completed Message */ + COMPLETED(18), + /** Constant denoting a DecisionExpected Message */ + DECISIONEXPECTED(19), + /** Constant denoting a CreateStream Message */ + CREATESTREAM(20), + /** Constant denoting an AreYouFlushed Message */ + AREYOUFLUSHED(21), + /** Constant denoting a Flushed Message */ + FLUSHED(22), + /** Constant denoting a NotFlushed Message */ + NOTFLUSHED(23), + /** Constant denoting a RequestFlushed Message */ + REQUESTFLUSH(24), + /** Constant denoting a RequestCardinalityInfo Message */ + REQUESTCARDINALITYINFO(25), + /** Constant denoting a CardinalityInfo Message */ + CARDINALITYINFO(26), + /** Constant denoting a CreateDurable Message */ + CREATEDURABLE(27), + /** Constant denoting a DeleteDurable Message */ + DELETEDURABLE(28), + /** Constant denoting a DurableConfirm Message */ + DURABLECONFIRM(29), + ; + + private static final TraceComponent tc = register(ControlMessageType.class, MSG_GROUP, MSG_BUNDLE); + + private static String format(String name) { return String.format("%-27s", name); } + + private static final Map types; + + static { + Map map = new HashMap<>(); + for (ControlMessageType type: values()) map.put(type.toInt(), type); + types = unmodifiableMap(map); + } + + private final Function nameFormatter; + private final Byte value; + private final int intValue; + + private ControlMessageType(int aValue) { + this(aValue, true); + } + + private ControlMessageType(int aValue, boolean customFormatted) { + nameFormatter = customFormatted ? ControlMessageType::format : s -> s; + value = Byte.valueOf((byte)aValue); + intValue = aValue; + } + + + /** + * Returns the corresponding ControlMessageType for a given integer. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @param aValue The integer for which an ControlMessageType is required. + * + * @return The corresponding ControlMessageType + */ + public static final ControlMessageType getControlMessageType(Byte aValue) { + if (isAnyTracingEnabled() && tc.isDebugEnabled()) debug(tc,"Value = " + aValue); + return types.get(aValue.intValue()); + } + + public static final ControlMessageType getControlMessageType(int aValue) { + return types.get(aValue); + } + + /** + * Returns the Byte representation of the ControlMessageType. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @return The Byte representation of the instance. + */ + public final Byte toByte() { + return value; + } + + /** + * Returns the integer representation of the ControlMessageType. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @return The int representation of the instance. + */ + public final int toInt() { + return intValue; + } + + /** + * Returns the name of the ControlMessageType. + * + * @return The name of the instance. + */ + @Override + public final String toString() { + return nameFormatter.apply(name()); + } } diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/control/SubscriptionMessageType.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/control/SubscriptionMessageType.java index 456c84a6059..c3706bd2dbe 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/control/SubscriptionMessageType.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/control/SubscriptionMessageType.java @@ -1,105 +1,88 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp.control; -import com.ibm.ws.sib.mfp.*; -import com.ibm.ws.sib.utils.ras.SibTr; +import static com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_BUNDLE; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_GROUP; +import static com.ibm.ws.sib.utils.ras.SibTr.debug; +import static com.ibm.ws.sib.utils.ras.SibTr.register; +import static java.util.Collections.unmodifiableMap; + +import java.util.HashMap; +import java.util.Map; + import com.ibm.websphere.ras.TraceComponent; +import com.ibm.ws.sib.mfp.IntAble; /** * SubscriptionMessageType is a type-safe enumeration which indicates the type of a * Subscription Propagation message. */ -public final class SubscriptionMessageType implements IntAble { - - private static TraceComponent tc = SibTr.register(SubscriptionMessageType.class, MfpConstants.MSG_GROUP, MfpConstants.MSG_BUNDLE); - - /** Integer value of the Subscription Message Types */ - public final static int UNKNOWN_INT = 0; - public final static int RESET_INT = 1; - public final static int CREATE_INT = 2; - public final static int DELETE_INT = 3; - public final static int REQUEST_INT = 4; - public final static int REPLY_INT = 5; - - /** Constant denoting an indeterminate Subscription Propagation Message */ - public final static SubscriptionMessageType UNKNOWN = new SubscriptionMessageType("UNKNOWN" ,UNKNOWN_INT ); - - /** Constant denoting a Reset Message */ - public final static SubscriptionMessageType RESET = new SubscriptionMessageType("RESET" ,RESET_INT ); - - /** Constant denoting a Create Message */ - public final static SubscriptionMessageType CREATE = new SubscriptionMessageType("CREATE" ,CREATE_INT ); - - /** Constant denoting a Delete Message */ - public final static SubscriptionMessageType DELETE = new SubscriptionMessageType("DELETE" ,DELETE_INT ); - - /** Constant denoting a Request Message */ - public final static SubscriptionMessageType REQUEST = new SubscriptionMessageType("REQUEST" ,REQUEST_INT ); - - /** Constant denoting a Reply Message */ - public final static SubscriptionMessageType REPLY = new SubscriptionMessageType("REPLY" ,REPLY_INT ); - - /* Array of defined SubscriptionMessageTypes - needed by getSubscriptionMessageType */ - private final static SubscriptionMessageType[] set = {UNKNOWN - ,RESET - ,CREATE - ,DELETE - ,REQUEST - ,REPLY - }; - - private String name; - private int value; - - /* Private constructor - ensures the 'constants' defined here are the total set. */ - private SubscriptionMessageType(String aName, int aValue) { - name = aName; - value = aValue; - } - - /** - * Returns the corresponding SubscriptionMessageType for a given integer. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @param aValue The integer for which an SubscriptionMessageType is required. - * - * @return The corresponding SubscriptionMessageType - */ - public final static SubscriptionMessageType getSubscriptionMessageType(int aValue) { - if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(tc,"Value = " + aValue); - return set[aValue]; - } - - /** - * Returns the integer representation of the SubscriptionMessageType. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @return The int representation of the instance. - */ - public final int toInt() { - return value; - } - - /** - * Returns the name of the SubscriptionMessageType. - * - * @return The name of the instance. - */ - public final String toString() { - return name; - } - +public enum SubscriptionMessageType implements IntAble { + /** Constant denoting an indeterminate Subscription Propagation Message */ + UNKNOWN(0), + /** Constant denoting a Reset Message */ + RESET(1), + /** Constant denoting a Create Message */ + CREATE(2), + /** Constant denoting a Delete Message */ + DELETE(3), + /** Constant denoting a Request Message */ + REQUEST(4), + /** Constant denoting a Reply Message */ + REPLY(5), + ; + + private static final TraceComponent tc = register(SubscriptionMessageType.class, MSG_GROUP, MSG_BUNDLE); + + private static final Map types; + + static { + Map map = new HashMap<>(); + for (SubscriptionMessageType type: values()) map.put(type.toInt(), type); + types = unmodifiableMap(map); + } + + private final int value; + + private SubscriptionMessageType(int aValue) { + value = aValue; + } + + /** + * Returns the corresponding SubscriptionMessageType for a given integer. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @param aValue The integer for which an SubscriptionMessageType is required. + * + * @return The corresponding SubscriptionMessageType + */ + public static final SubscriptionMessageType getSubscriptionMessageType(int aValue) { + if (isAnyTracingEnabled() && tc.isDebugEnabled()) debug(tc,"Value = " + aValue); + return types.get(aValue); + } + + /** + * Returns the integer representation of the SubscriptionMessageType. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @return The int representation of the instance. + */ + public final int toInt() { + return value; + } } diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/ControlMessageFactoryImpl.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/ControlMessageFactoryImpl.java index f478a7b0280..becf38f72e0 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/ControlMessageFactoryImpl.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/ControlMessageFactoryImpl.java @@ -1,15 +1,16 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp.impl; import java.util.List; @@ -819,124 +820,94 @@ private final ControlMessage makeInboundControlMessage(JsMsgObject jmo, int mess ControlMessage controlMessage = null; /* Create an instance of the appropriate message subclass */ - switch (messageType) { - - case ControlMessageType.ACKEXPECTED_INT: + switch (ControlMessageType.getControlMessageType(messageType)) { + case ACKEXPECTED: controlMessage = new ControlAckExpectedImpl(jmo); break; - - case ControlMessageType.SILENCE_INT: + case SILENCE: controlMessage = new ControlSilenceImpl(jmo); break; - - case ControlMessageType.ACK_INT: + case ACK: controlMessage = new ControlAckImpl(jmo); break; - - case ControlMessageType.NACK_INT: + case NACK: controlMessage = new ControlNackImpl(jmo); break; - - case ControlMessageType.PREVALUE_INT: + case PREVALUE: controlMessage = new ControlPrevalueImpl(jmo); break; - - case ControlMessageType.ACCEPT_INT: + case ACCEPT: controlMessage = new ControlAcceptImpl(jmo); break; - - case ControlMessageType.REJECT_INT: + case REJECT: controlMessage = new ControlRejectImpl(jmo); break; - - case ControlMessageType.DECISION_INT: + case DECISION: controlMessage = new ControlDecisionImpl(jmo); break; - - case ControlMessageType.REQUEST_INT: + case REQUEST: controlMessage = new ControlRequestImpl(jmo); break; - - case ControlMessageType.REQUESTACK_INT: + case REQUESTACK: controlMessage = new ControlRequestAckImpl(jmo); break; - - case ControlMessageType.REQUESTHIGHESTGENERATEDTICK_INT: + case REQUESTHIGHESTGENERATEDTICK: controlMessage = new ControlRequestHighestGeneratedTickImpl(jmo); break; - - case ControlMessageType.HIGHESTGENERATEDTICK_INT: + case HIGHESTGENERATEDTICK: controlMessage = new ControlHighestGeneratedTickImpl(jmo); break; - - case ControlMessageType.RESETREQUESTACK_INT: + case RESETREQUESTACK: controlMessage = new ControlResetRequestAckImpl(jmo); break; - - case ControlMessageType.RESETREQUESTACKACK_INT: + case RESETREQUESTACKACK: controlMessage = new ControlResetRequestAckAckImpl(jmo); break; - - case ControlMessageType.BROWSEGET_INT: + case BROWSEGET: controlMessage = new ControlBrowseGetImpl(jmo); break; - - case ControlMessageType.BROWSEEND_INT: + case BROWSEEND: controlMessage = new ControlBrowseEndImpl(jmo); break; - - case ControlMessageType.BROWSESTATUS_INT: + case BROWSESTATUS: controlMessage = new ControlBrowseStatusImpl(jmo); break; - - case ControlMessageType.COMPLETED_INT: + case COMPLETED: controlMessage = new ControlCompletedImpl(jmo); break; - - case ControlMessageType.DECISIONEXPECTED_INT: + case DECISIONEXPECTED: controlMessage = new ControlDecisionExpectedImpl(jmo); break; - - case ControlMessageType.CREATESTREAM_INT: + case CREATESTREAM: controlMessage = new ControlCreateStreamImpl(jmo); break; - - case ControlMessageType.AREYOUFLUSHED_INT: + case AREYOUFLUSHED: controlMessage = new ControlAreYouFlushedImpl(jmo); break; - - case ControlMessageType.FLUSHED_INT: + case FLUSHED: controlMessage = new ControlFlushedImpl(jmo); break; - - case ControlMessageType.NOTFLUSHED_INT: + case NOTFLUSHED: controlMessage = new ControlNotFlushedImpl(jmo); break; - - case ControlMessageType.REQUESTFLUSH_INT: + case REQUESTFLUSH: controlMessage = new ControlRequestFlushImpl(jmo); break; - - case ControlMessageType.REQUESTCARDINALITYINFO_INT: + case REQUESTCARDINALITYINFO: controlMessage = new ControlRequestCardinalityInfoImpl(jmo); break; - - case ControlMessageType.CARDINALITYINFO_INT: + case CARDINALITYINFO: controlMessage = new ControlCardinalityInfoImpl(jmo); break; - - case ControlMessageType.CREATEDURABLE_INT: + case CREATEDURABLE: controlMessage = new ControlCreateDurableImpl(jmo); break; - - case ControlMessageType.DELETEDURABLE_INT: + case DELETEDURABLE: controlMessage = new ControlDeleteDurableImpl(jmo); break; - - case ControlMessageType.DURABLECONFIRM_INT: + case DURABLECONFIRM: controlMessage = new ControlDurableConfirmImpl(jmo); break; - default: /* This shouldn't happen at the moment but will provide some support */ /* for new types being added by future releases & arriving at an old */ diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/JsJmsMessageFactoryImpl.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/JsJmsMessageFactoryImpl.java index 977fcfa3755..3fccd7eb53e 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/JsJmsMessageFactoryImpl.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/JsJmsMessageFactoryImpl.java @@ -1,19 +1,23 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp.impl; import com.ibm.ws.sib.mfp.*; import com.ibm.ws.sib.utils.ras.SibTr; + +import static com.ibm.ws.sib.mfp.JmsBodyType.getJmsBodyType; + import com.ibm.websphere.ras.TraceComponent; /** @@ -185,25 +189,25 @@ final JsJmsMessage createInboundJmsMessage(JsMsgObject jmo, int messageType) { JsJmsMessage jmsMessage = null; - switch (messageType) { + switch (getJmsBodyType(messageType)) { - case JmsBodyType.BYTES_INT: + case BYTES: jmsMessage = new JsJmsBytesMessageImpl(jmo); break; - case JmsBodyType.MAP_INT: + case MAP: jmsMessage = new JsJmsMapMessageImpl(jmo); break; - case JmsBodyType.OBJECT_INT: + case OBJECT: jmsMessage = new JsJmsObjectMessageImpl(jmo); break; - case JmsBodyType.STREAM_INT: + case STREAM: jmsMessage = new JsJmsStreamMessageImpl(jmo); break; - case JmsBodyType.TEXT_INT: + case TEXT: jmsMessage = new JsJmsTextMessageImpl(jmo); break; diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/JsJmsMessageImpl.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/JsJmsMessageImpl.java index a0d106bd178..d040620ed9b 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/JsJmsMessageImpl.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/JsJmsMessageImpl.java @@ -1,17 +1,20 @@ -/******************************************************************************* - * Copyright (c) 2012, 2014 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp.impl; +import static com.ibm.ws.sib.mfp.JmsBodyType.getJmsBodyType; + import java.util.HashSet; import java.util.List; import java.util.Set; @@ -110,7 +113,7 @@ class JsJmsMessageImpl extends JsApiMessageImpl implements JsJmsMessage { /* Set the JMS message fields */ setJsMessageType(MessageType.JMS); - setSubtype(JmsBodyType.NULL_INT); + setSubtype(JmsBodyType.NULL.toInt()); /* Set some of the JMS specific header values unless flagged not to */ /* For an Inbound MQ message the fields will be set by the */ @@ -319,8 +322,7 @@ public JsMessage getSent(boolean copy) throws MessageCopyFailedException { @Override public final JmsBodyType getBodyType() { /* Get the subtype and get the corresponding JmsBodyType to return */ - int bType = getSubtype(); - return JmsBodyType.getJmsBodyType(Byte.valueOf((byte) bType)); + return getJmsBodyType(getSubtype()); } /* ************************************************************************* */ diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/SubscriptionMessageImpl.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/SubscriptionMessageImpl.java index cdb608d8923..e55fcca00c6 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/SubscriptionMessageImpl.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/SubscriptionMessageImpl.java @@ -1,15 +1,16 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp.impl; import java.util.ArrayList; @@ -80,7 +81,7 @@ public class SubscriptionMessageImpl extends JsMessageImpl implements Subscripti setProducerType(ProducerType.MP); /* Default all the fields */ - setSubtype(SubscriptionMessageType.UNKNOWN_INT); + setSubtype(SubscriptionMessageType.UNKNOWN.toInt()); setTopics(null); setTopicSpaces(null); setTopicSpaceMappings(null); diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/TrmMessageFactoryImpl.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/TrmMessageFactoryImpl.java index c82723d570a..317bebf4650 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/TrmMessageFactoryImpl.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/TrmMessageFactoryImpl.java @@ -1,21 +1,25 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp.impl; import com.ibm.ws.sib.mfp.*; import com.ibm.ws.sib.mfp.schema.TrmFirstContactAccess; import com.ibm.ws.sib.mfp.trm.*; import com.ibm.ws.sib.utils.ras.SibTr; + +import static com.ibm.ws.sib.mfp.trm.TrmMessageType.getTrmMessageType; + import com.ibm.websphere.ras.TraceComponent; /** @@ -392,13 +396,11 @@ final TrmMessage createInboundTrmMessage(JsMsgObject jmo, int messageType) { TrmMessage trmMessage = null; /* Create an instance of the appropriate message subclass */ - switch (messageType) { - - case TrmMessageType.ROUTE_DATA_INT: + switch (getTrmMessageType(messageType)) { + case ROUTE_DATA: trmMessage = new TrmRouteDataImpl(jmo); break; - - default: + default: trmMessage = new TrmMessageImpl(jmo); } diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/TrmRouteDataImpl.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/TrmRouteDataImpl.java index 56ddfa7c669..f6df48eab72 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/TrmRouteDataImpl.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/impl/TrmRouteDataImpl.java @@ -1,15 +1,16 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp.impl; import java.util.List; @@ -56,7 +57,7 @@ final class TrmRouteDataImpl extends TrmMessageImpl implements TrmRouteData { TrmRouteDataImpl(int flag) throws MessageDecodeFailedException { super(flag); if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(tc, ""); - setSubtype(TrmMessageType.ROUTE_DATA_INT); + setSubtype(TrmMessageType.ROUTE_DATA.toInt()); } diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/trm/TrmFirstContactMessageType.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/trm/TrmFirstContactMessageType.java index 0773a89109a..6d3c8af7e35 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/trm/TrmFirstContactMessageType.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/trm/TrmFirstContactMessageType.java @@ -1,125 +1,103 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ + package com.ibm.ws.sib.mfp.trm; -import com.ibm.ws.sib.mfp.*; -import com.ibm.ws.sib.utils.ras.SibTr; +import static com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_BUNDLE; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_GROUP; +import static com.ibm.ws.sib.utils.ras.SibTr.debug; +import static com.ibm.ws.sib.utils.ras.SibTr.register; +import static java.util.Collections.unmodifiableMap; + +import java.util.HashMap; +import java.util.Map; + import com.ibm.websphere.ras.TraceComponent; +import com.ibm.ws.sib.mfp.IntAble; /** * TrmFirstContactMessageType is a type-safe enumeration which indicates the * type of a TRM First Contact message. */ -public final class TrmFirstContactMessageType implements IntAble { - - private static TraceComponent tc = SibTr.register(TrmFirstContactMessageType.class, MfpConstants.MSG_GROUP, MfpConstants.MSG_BUNDLE); - - /** Constant denoting a Client Bootstrap Request */ - public final static TrmFirstContactMessageType CLIENT_BOOTSTRAP_REQUEST = new TrmFirstContactMessageType("CLIENT_BOOTSTRAP_REQUEST" ,0); - - /** Constant denoting a Client Bootstrap Reply */ - public final static TrmFirstContactMessageType CLIENT_BOOTSTRAP_REPLY = new TrmFirstContactMessageType("CLIENT_BOOTSTRAP_REPLY" ,1); - - /** Constant denoting a Client Attach Request */ - public final static TrmFirstContactMessageType CLIENT_ATTACH_REQUEST = new TrmFirstContactMessageType("CLIENT_ATTACH_REQUEST" ,2); - - /** Constant denoting a Client Attach Request 2 */ - public final static TrmFirstContactMessageType CLIENT_ATTACH_REQUEST2 = new TrmFirstContactMessageType("CLIENT_ATTACH_REQUEST2" ,3); - - /** Constant denoting a Client Attach Reply */ - public final static TrmFirstContactMessageType CLIENT_ATTACH_REPLY = new TrmFirstContactMessageType("CLIENT_ATTACH_REPLY" ,4); - - /** Constant denoting a ME Bootstrap Request */ - public final static TrmFirstContactMessageType ME_CONNECT_REQUEST = new TrmFirstContactMessageType("ME_CONNECT_REQUEST" ,5); - - /** Constant denoting a ME Bootstrap Reply */ - public final static TrmFirstContactMessageType ME_CONNECT_REPLY = new TrmFirstContactMessageType("ME_CONNECT_REPLY" ,6); - - /** Constant denoting a ME Link Request */ - public final static TrmFirstContactMessageType ME_LINK_REQUEST = new TrmFirstContactMessageType("ME_LINK_REQUEST" ,7); - - /** Constant denoting a ME Link Reply */ - public final static TrmFirstContactMessageType ME_LINK_REPLY = new TrmFirstContactMessageType("ME_LINK_REPLY" ,8); - - /** Constant denoting a ME Bridge Request */ - public final static TrmFirstContactMessageType ME_BRIDGE_REQUEST = new TrmFirstContactMessageType("ME_BRIDGE_REQUEST" ,9); - - /** Constant denoting a ME Bridge Reply */ - public final static TrmFirstContactMessageType ME_BRIDGE_REPLY = new TrmFirstContactMessageType("ME_BRIDGE_REPLY" ,10); - - /** Constant denoting a ME Bridge Bootstrap Request */ - public final static TrmFirstContactMessageType ME_BRIDGE_BOOTSTRAP_REQUEST = new TrmFirstContactMessageType("ME_BRIDGE_BOOTSTRAP_REQUEST", 11); - - /** Constant denoting a ME Bridge Bootstrap Reply */ - public final static TrmFirstContactMessageType ME_BRIDGE_BOOTSTRAP_REPLY = new TrmFirstContactMessageType("ME_BRIDGE_BOOTSTRAP_REPLY", 12); - - /* Array of defined TrmFirstContactMessageTypes - needed by getTrmFirstContactMessageType */ - private final static TrmFirstContactMessageType[] set = {CLIENT_BOOTSTRAP_REQUEST - ,CLIENT_BOOTSTRAP_REPLY - ,CLIENT_ATTACH_REQUEST - ,CLIENT_ATTACH_REQUEST2 - ,CLIENT_ATTACH_REPLY - ,ME_CONNECT_REQUEST - ,ME_CONNECT_REPLY - ,ME_LINK_REQUEST - ,ME_LINK_REPLY - ,ME_BRIDGE_REQUEST - ,ME_BRIDGE_REPLY - ,ME_BRIDGE_BOOTSTRAP_REQUEST - ,ME_BRIDGE_BOOTSTRAP_REPLY - }; - - private String name; - private int value; - - /* Private constructor - ensures the 'constants' defined here are the total set. */ - private TrmFirstContactMessageType(String aName, int aValue) { - name = aName; - value = aValue; - } - - /** - * Returns the corresponding TrmFirstContactMessageType for a given integer. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @param aValue The integer for which an TrmFirstContactMessageType is required. - * - * @return The corresponding TrmFirstContactMessageType - */ - public final static TrmFirstContactMessageType getTrmFirstContactMessageType(int aValue) { - if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(tc,"Value = " + aValue); - return set[aValue]; - } - - /** - * Returns the integer representation of the TrmFirstContactMessageType. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @return The int representation of the instance. - */ - public final int toInt() { - return value; - } - - /** - * Returns the name of the TrmFirstContactMessageType. - * - * @return The name of the instance. - */ - public final String toString() { - return name; - } - +public enum TrmFirstContactMessageType implements IntAble { + /** Constant denoting a Client Bootstrap Request */ + CLIENT_BOOTSTRAP_REQUEST(0), + /** Constant denoting a Client Bootstrap Reply */ + CLIENT_BOOTSTRAP_REPLY(1), + /** Constant denoting a Client Attach Request */ + CLIENT_ATTACH_REQUEST(2), + /** Constant denoting a Client Attach Request 2 */ + CLIENT_ATTACH_REQUEST2(3), + /** Constant denoting a Client Attach Reply */ + CLIENT_ATTACH_REPLY(4), + /** Constant denoting a ME Bootstrap Request */ + ME_CONNECT_REQUEST(5), + /** Constant denoting a ME Bootstrap Reply */ + ME_CONNECT_REPLY(6), + /** Constant denoting a ME Link Request */ + ME_LINK_REQUEST(7), + /** Constant denoting a ME Link Reply */ + ME_LINK_REPLY(8), + /** Constant denoting a ME Bridge Request */ + ME_BRIDGE_REQUEST(9), + /** Constant denoting a ME Bridge Reply */ + ME_BRIDGE_REPLY(10), + /** Constant denoting a ME Bridge Bootstrap Request */ + ME_BRIDGE_BOOTSTRAP_REQUEST(11), + /** Constant denoting a ME Bridge Bootstrap Reply */ + ME_BRIDGE_BOOTSTRAP_REPLY(12), + ; + + private static final TraceComponent tc = register(TrmFirstContactMessageType.class, MSG_GROUP, MSG_BUNDLE); + + private static final Map types; + + static { + Map map = new HashMap<>(); + for (TrmFirstContactMessageType type: values()) map.put(type.toInt(), type); + types = unmodifiableMap(map); + } + + private final int value; + + private TrmFirstContactMessageType(int aValue) { + value = aValue; + } + + /** + * Returns the corresponding TrmFirstContactMessageType for a given integer. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @param aValue The integer for which an TrmFirstContactMessageType is required. + * + * @return The corresponding TrmFirstContactMessageType + */ + public static final TrmFirstContactMessageType getTrmFirstContactMessageType(int aValue) { + if (isAnyTracingEnabled() && tc.isDebugEnabled()) debug(tc,"Value = " + aValue); + return types.get(aValue); + } + + /** + * Returns the integer representation of the TrmFirstContactMessageType. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @return The int representation of the instance. + */ + public final int toInt() { + return value; + } } diff --git a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/trm/TrmMessageType.java b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/trm/TrmMessageType.java index 5035f4d9e3c..d2103ff9d6b 100644 --- a/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/trm/TrmMessageType.java +++ b/dev/com.ibm.ws.messaging.common/src/com/ibm/ws/sib/mfp/trm/TrmMessageType.java @@ -1,86 +1,81 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.mfp.trm; -import com.ibm.ws.sib.mfp.*; -import com.ibm.ws.sib.utils.ras.SibTr; +import static com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_BUNDLE; +import static com.ibm.ws.sib.mfp.MfpConstants.MSG_GROUP; +import static com.ibm.ws.sib.utils.ras.SibTr.debug; +import static com.ibm.ws.sib.utils.ras.SibTr.register; +import static java.util.Collections.unmodifiableMap; + +import java.util.HashMap; +import java.util.Map; + import com.ibm.websphere.ras.TraceComponent; +import com.ibm.ws.sib.mfp.IntAble; /** * TrmMessageType is a type-safe enumeration which indicates the type of a TRM * message. */ -public final class TrmMessageType implements IntAble { - - private static TraceComponent tc = SibTr.register(TrmMessageType.class, MfpConstants.MSG_GROUP, MfpConstants.MSG_BUNDLE); - - /** Integer value of the Trm Message Types */ - public final static int UNKNOWN_INT = 0; - public final static int ROUTE_DATA_INT = 1; - - /** Constant denoting an indeterminate TRM Message */ - public final static TrmMessageType UNKNOWN = new TrmMessageType("UNKNOWN" ,UNKNOWN_INT ); - - /** Constant denoting a Route data Message */ - public final static TrmMessageType ROUTE_DATA = new TrmMessageType("ROUTE_DATA" ,ROUTE_DATA_INT ); +public enum TrmMessageType implements IntAble { + /** Constant denoting an indeterminate TRM Message */ + UNKNOWN(0), + /** Constant denoting a Route data Message */ + ROUTE_DATA(1), + ; - /* Array of defined TrmMessageTypes - needed by getTrmMessageType */ - private final static TrmMessageType[] set = {UNKNOWN - ,ROUTE_DATA - }; + private static final TraceComponent tc = register(TrmMessageType.class, MSG_GROUP, MSG_BUNDLE); - private String name; - private int value; + private static final Map types; - /* Private constructor - ensures the 'constants' defined here are the total set. */ - private TrmMessageType(String aName, int aValue) { - name = aName; - value = aValue; - } + static { + Map map = new HashMap<>(); + for (TrmMessageType type: values()) map.put(type.toInt(), type); + types = unmodifiableMap(map); + } - /** - * Returns the corresponding TrmMessageType for a given integer. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @param aValue The integer for which an TrmMessageType is required. - * - * @return The corresponding TrmMessageType - */ - public final static TrmMessageType getTrmMessageType(int aValue) { - if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(tc,"Value = " + aValue); - return set[aValue]; - } + private final int value; - /** - * Returns the integer representation of the TrmMessageType. - * This method should NOT be called by any code outside the MFP component. - * It is only public so that it can be accessed by sub-packages. - * - * @return The int representation of the instance. - */ - public final int toInt() { - return value; - } + private TrmMessageType(int aValue) { + value = aValue; + } - /** - * Returns the name of the TrmMessageType. - * - * @return The name of the instance. - */ - public final String toString() { - return name; - } + /** + * Returns the corresponding TrmMessageType for a given integer. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @param aValue The integer for which an TrmMessageType is required. + * + * @return The corresponding TrmMessageType + */ + public static final TrmMessageType getTrmMessageType(int aValue) { + if (isAnyTracingEnabled() && tc.isDebugEnabled()) debug(tc,"Value = " + aValue); + return types.get(aValue); + } + /** + * Returns the integer representation of the TrmMessageType. + * This method should NOT be called by any code outside the MFP component. + * It is only public so that it can be accessed by sub-packages. + * + * @return The int representation of the instance. + */ + public final int toInt() { + return value; + } } diff --git a/dev/com.ibm.ws.messaging.jms.2.0/src/com/ibm/ws/sib/api/jms/impl/JmsMessageImpl.java b/dev/com.ibm.ws.messaging.jms.2.0/src/com/ibm/ws/sib/api/jms/impl/JmsMessageImpl.java index 26a112244a9..07a2dff3a4a 100644 --- a/dev/com.ibm.ws.messaging.jms.2.0/src/com/ibm/ws/sib/api/jms/impl/JmsMessageImpl.java +++ b/dev/com.ibm.ws.messaging.jms.2.0/src/com/ibm/ws/sib/api/jms/impl/JmsMessageImpl.java @@ -1,15 +1,16 @@ -/******************************************************************************* - * Copyright (c) 2012, 2015, 2020 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 * http://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.api.jms.impl; import java.io.IOException; @@ -1987,34 +1988,29 @@ static Message inboundJmsInstance(JsJmsMessage newMsg, JmsSessionImpl newSess, M if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(tc, "body type: " + bt); - int bodyTypeInt = -2; // This is not one of the JmsBodyType constants. - if (bt != null) { - bodyTypeInt = bt.toInt(); - } - - switch (bodyTypeInt) { + switch (bt) { - case JmsBodyType.NULL_INT: + case NULL: jmsMsg = new JmsMessageImpl(newMsg, newSess); break; - case JmsBodyType.TEXT_INT: + case TEXT: jmsMsg = new JmsTextMessageImpl((JsJmsTextMessage) newMsg, newSess); break; - case JmsBodyType.MAP_INT: + case MAP: jmsMsg = new JmsMapMessageImpl((JsJmsMapMessage) newMsg, newSess); break; - case JmsBodyType.OBJECT_INT: + case OBJECT: jmsMsg = new JmsObjectMessageImpl((JsJmsObjectMessage) newMsg, newSess); break; - case JmsBodyType.BYTES_INT: + case BYTES: jmsMsg = new JmsBytesMessageImpl((JsJmsBytesMessage) newMsg, newSess); break; - case JmsBodyType.STREAM_INT: + case STREAM: jmsMsg = new JmsStreamMessageImpl((JsJmsStreamMessage) newMsg, newSess); break; @@ -2736,63 +2732,60 @@ public T getBody(Class paramClass) throws JMSException, MessageFormatExce T returnObj = null; try { - int bodyType = msg.getBodyType().toInt(); - Object _messageObject = null; - switch (bodyType) { - case JmsBodyType.TEXT_INT: - try { + final Object _messageObject; + switch (msg.getBodyType()) { + case TEXT: + try { _messageObject = ((JsJmsTextMessage) msg).getText(); - } catch (UnsupportedEncodingException exp) { + } catch (UnsupportedEncodingException exp) { throw getJMSException(paramClass, exp); - } - break; + } + break; - case JmsBodyType.OBJECT_INT: - try { + case OBJECT: + try { _messageObject = ((JsJmsObjectMessage) msg).getRealObject(); - //As per spec: if the message is an ObjectMessage and object deserialization fails + //As per spec: if the message is an ObjectMessage and object deserialization fails //then throw MessageFormatException. if (_messageObject != null && !Serializable.class.isAssignableFrom(paramClass)) { - throw getMessageFormatException(paramClass); + throw getMessageFormatException(paramClass); } - } catch (ClassNotFoundException cnfe) { + } catch (ClassNotFoundException cnfe) { throw getJMSException(paramClass, cnfe); - } catch (IOException ioe) { + } catch (IOException ioe) { throw getJMSException(paramClass, ioe); - } - break; + } + break; - case JmsBodyType.MAP_INT: - try { + case MAP: + try { _messageObject = getMapMessage(); - //As per spec: If the message is a MapMessage then this parameter must be set to java.util.Map.class (or java.lang.Object.class). + //As per spec: If the message is a MapMessage then this parameter must be set to java.util.Map.class (or java.lang.Object.class). //then throw MessageFormatException. if (_messageObject != null && !paramClass.isAssignableFrom(Map.class)) { - throw getMessageFormatException(paramClass); + throw getMessageFormatException(paramClass); } - } catch (UnsupportedEncodingException uee) { + } catch (UnsupportedEncodingException uee) { throw getJMSException(paramClass, uee); - } - break; + } + break; - case JmsBodyType.BYTES_INT: - byte[] byteMsg = ((JsJmsBytesMessage) msg).getBytes(); - _messageObject = (byteMsg != null && byteMsg.length > 0) ? byteMsg : null; + case BYTES: + byte[] byteMsg = ((JsJmsBytesMessage) msg).getBytes(); + _messageObject = (byteMsg != null && byteMsg.length > 0) ? byteMsg : null; - if (_messageObject != null && !paramClass.isAssignableFrom(byte[].class)) { + if (_messageObject != null && !paramClass.isAssignableFrom(byte[].class)) { throw getMessageFormatException(paramClass); - } - break; - - case JmsBodyType.STREAM_INT: - throw getMessageFormatException(paramClass); - - case JmsBodyType.NULL_INT: - _messageObject = null; - break; + } + break; + case STREAM: + throw getMessageFormatException(paramClass); + default: + _messageObject = null; + break; } if (_messageObject != null) { if (paramClass.isAssignableFrom(_messageObject.getClass())) { @@ -2894,35 +2887,37 @@ public boolean isBodyAssignableTo(Class paramClass) throws JMSException, Message if (paramClass == null) return false; try { - // get the body type - int bodyType = msg.getBodyType().toInt(); - - if (bodyType == JmsBodyType.TEXT_INT) { + switch(msg.getBodyType()) { + case TEXT: decision = String.class.isAssignableFrom(paramClass); - } else if (bodyType == JmsBodyType.OBJECT_INT) { + break; + case OBJECT: decision = Serializable.class.isAssignableFrom(paramClass); // try if the object can be deserialized, if not then return false if (decision) { try { Object object = ((JsJmsObjectMessage) msg).getRealObject(); - decision = (paramClass.isAssignableFrom(object.getClass())); + decision = paramClass.isAssignableFrom(object.getClass()); } catch (IOException jmse) { return false; } catch (ClassNotFoundException e) { return false; } } - } else if (bodyType == JmsBodyType.MAP_INT) { + break; + case MAP: decision = Map.class.isAssignableFrom(paramClass); - } else if (bodyType == JmsBodyType.BYTES_INT) { + break; + case BYTES: decision = byte[].class.isAssignableFrom(paramClass); - } else if (bodyType == JmsBodyType.STREAM_INT) { - decision = false; - } else if (bodyType == JmsBodyType.NULL_INT) { // return false if message does not have a body + break; + case STREAM: + case NULL: + default: // return false if message does not have a body decision = false; + break; } - } finally { if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(tc, "isBodyAssignableTo", new Object[] { decision }); diff --git a/dev/com.ibm.ws.messaging.open_jms20deliverydelay_fat/test-applications/DeliveryDelay/src/deliverydelay/web/DeliveryDelayServlet.java b/dev/com.ibm.ws.messaging.open_jms20deliverydelay_fat/test-applications/DeliveryDelay/src/deliverydelay/web/DeliveryDelayServlet.java index 0796d12b554..5a358d72322 100644 --- a/dev/com.ibm.ws.messaging.open_jms20deliverydelay_fat/test-applications/DeliveryDelay/src/deliverydelay/web/DeliveryDelayServlet.java +++ b/dev/com.ibm.ws.messaging.open_jms20deliverydelay_fat/test-applications/DeliveryDelay/src/deliverydelay/web/DeliveryDelayServlet.java @@ -1260,29 +1260,69 @@ public void testGetDeliveryDelayTopic_Tcp( } } + + // Tests for delayed message persistence over server restart. + // These tests are each in two parts; a sender part that sends 2 messages, and a receiver part that attempts to receive the messages. + // The methods are driven from the Test class, which calls the sender method, restarts the server, and then calls the receiver method. + + // new tests for simplified API + + // New consolidated simplified API persistent test sender method + private void testPersistentMessageSimplifiedAPI_send(ConnectionFactory cf, + Destination persistentMessageDestination, + Destination nonpersistentMessageDestination, + String identifier) + throws Exception { + + boolean pubSub = persistentMessageDestination instanceof Topic; + JMSConsumer jmsConsumer1 = null, jmsConsumer2 = null; + + try (JMSContext jmsContext = cf.createContext()) { + + JMSProducer jmsProducer = jmsContext.createProducer(); + + // If we are sending messages to Topic destinations then there needs to be subscriptions to receive the messages + if (pubSub) { + jmsConsumer1 = jmsContext.createDurableConsumer((Topic) persistentMessageDestination, "durPersMsg1_" + identifier); + jmsConsumer2 = jmsContext.createDurableConsumer((Topic) nonpersistentMessageDestination, "durPersMsg2_" + identifier); + } + else { + // empty the message queue before sending the new messages. + // This is replicating previous behaviour, but will probably need to be removed if we re-work the tests to run concurrently. + emptyQueue(cf, (Queue)persistentMessageDestination); + emptyQueue(cf, (Queue)nonpersistentMessageDestination); + } + + // Send the messages + jmsProducer.setDeliveryDelay(defaultTestDeliveryDelay).setDeliveryMode(DeliveryMode.PERSISTENT) + .send(persistentMessageDestination, "PersistentMessage_" + identifier); + + jmsProducer.setDeliveryDelay(defaultTestDeliveryDelay).setDeliveryMode(DeliveryMode.NON_PERSISTENT) + .send(nonpersistentMessageDestination, "NonPersistentMessage_" + identifier); + + // If we're running in the pub/sub domain then close the subscribers (the subscriptions will remain open + if (pubSub) { + jmsConsumer1.close(); + jmsConsumer2.close(); + } + + } + + return; + } + + private String testPersistentQueueMessageIdentifier = "testPersistentQueueMessage"; public void testPersistentMessage( HttpServletRequest request, HttpServletResponse response) throws Exception { - - boolean testFailed = false; - - JMSContext jmsContext = jmsQCFBindings.createContext(); - JMSConsumer jmsConsumer = jmsContext.createConsumer(jmsQueue); - JMSProducer jmsProducer = jmsContext.createProducer(); - - emptyQueue(jmsQCFBindings, jmsQueue); - emptyQueue(jmsQCFBindings, jmsQueue1); - - jmsProducer.setDeliveryMode(DeliveryMode.PERSISTENT).setDeliveryDelay(1000); - - jmsProducer.send(jmsQueue, "testPersistentMessage_PersistentMsg"); - - jmsProducer.setDeliveryDelay(1000).setDeliveryMode(DeliveryMode.NON_PERSISTENT); - jmsProducer.send(jmsQueue1, "testPersistentMessage_NonPersistentMsg"); - - jmsConsumer.close(); - jmsContext.close(); + // Originally used message text "testPersistentMessage_PersistentMsg" "testPersistentMessage_NonPersistentMsg" + // jmsQCFBindings, jmsQueue, jmsQueue1 + + testPersistentMessageSimplifiedAPI_send(jmsQCFBindings, jmsQueue, jmsQueue1, testPersistentQueueMessageIdentifier); + + return; + } public void testPersistentMessageReceive( @@ -1300,7 +1340,7 @@ public void testPersistentMessageReceive( if ( ((recMsg1 == null) || (recMsg1.getText() == null) || - !recMsg1.getText().equals("testPersistentMessage_PersistentMsg")) || + !recMsg1.getText().equals("PersistentMessage_" + testPersistentQueueMessageIdentifier)) || (recMsg2 != null) ) { testFailed = true; } @@ -1314,25 +1354,16 @@ public void testPersistentMessageReceive( } } + private String testPersistentQueueMessageTcpIdentifier = "testPersistentQueueMessageTcp"; + public void testPersistentMessage_Tcp( HttpServletRequest request, HttpServletResponse response) throws Exception { + // Originally used message text "testPersistentMessage_PersistentMsgTcp" "testPersistentMessage_NonPersistentMsgTcp" + // jmsQCFTCP, jmsQueue, jmsQueue1 + + testPersistentMessageSimplifiedAPI_send(jmsQCFTCP, jmsQueue, jmsQueue1, testPersistentQueueMessageTcpIdentifier); - boolean testFailed = false; - - JMSContext jmsContext = jmsQCFTCP.createContext(); - JMSConsumer jmsConsumer = jmsContext.createConsumer(jmsQueue); - JMSProducer jmsProducer = jmsContext.createProducer(); - emptyQueue(jmsQCFTCP, jmsQueue); - emptyQueue(jmsQCFTCP, jmsQueue1); - - jmsProducer.setDeliveryMode(DeliveryMode.PERSISTENT).setDeliveryDelay(1000); - jmsProducer.send(jmsQueue, "testPersistentMessage_PersistentMsgTcp"); - - jmsProducer.setDeliveryDelay(1000).setDeliveryMode(DeliveryMode.NON_PERSISTENT); - jmsProducer.send(jmsQueue1, "testPersistentMessage_NonPersistentMsgTcp"); - - jmsConsumer.close(); - jmsContext.close(); + return; } public void testPersistentMessageReceive_Tcp( @@ -1350,7 +1381,7 @@ public void testPersistentMessageReceive_Tcp( if ( ((recMsg1 == null) || (recMsg1.getText() == null) || - !recMsg1.getText().equals("testPersistentMessage_PersistentMsgTcp")) || + !recMsg1.getText().equals("PersistentMessage_" + testPersistentQueueMessageTcpIdentifier)) || (recMsg2 != null) ) { testFailed = true; } @@ -1364,33 +1395,29 @@ public void testPersistentMessageReceive_Tcp( } } + private String testPersistentTopicMessageIdentifier = "testPersistentTopicMessage"; + public void testPersistentMessageTopic( HttpServletRequest request, HttpServletResponse response) throws Exception { + // Originally used message text "testPersistentMessage_PersistentMsgTopic" "testPersistentMessage_NonPersistentMsgTopic" + // jmsTCFBindings, jmsTopic, jmsTopic1 - boolean testFailed = false; - - JMSContext jmsContext = jmsTCFBindings.createContext(); - JMSConsumer jmsConsumer1 = jmsContext.createDurableConsumer(jmsTopic, "durPersMsg1"); - JMSConsumer jmsConsumer2 = jmsContext.createDurableConsumer(jmsTopic1, "durPersMsg2"); - JMSProducer jmsProducer = jmsContext.createProducer(); - - jmsProducer.setDeliveryMode(DeliveryMode.PERSISTENT) .setDeliveryDelay(1000); - jmsProducer.send(jmsTopic, "testPersistentMessage_PersistentMsgTopic"); - - jmsProducer.setDeliveryDelay(1000).setDeliveryMode(DeliveryMode.NON_PERSISTENT); - jmsProducer.send(jmsTopic1, "testPersistentMessage_NonPersistentMsgTopic"); - - // First half of test .. verification in the second half. + testPersistentMessageSimplifiedAPI_send(jmsTCFBindings, jmsTopic, jmsTopic1, testPersistentTopicMessageIdentifier); + + return; } public void testPersistentMessageReceiveTopic( HttpServletRequest request, HttpServletResponse response) throws Exception { boolean testFailed = false; + + String subscriber1Name = "durPersMsg1_" + testPersistentTopicMessageIdentifier; + String subscriber2Name = "durPersMsg2_" + testPersistentTopicMessageIdentifier; JMSContext jmsContext = jmsTCFBindings.createContext(); - JMSConsumer jmsConsumer1 = jmsContext.createDurableConsumer(jmsTopic, "durPersMsg1"); - JMSConsumer jmsConsumer2 = jmsContext.createDurableConsumer(jmsTopic1, "durPersMsg2"); + JMSConsumer jmsConsumer1 = jmsContext.createDurableConsumer(jmsTopic, subscriber1Name); + JMSConsumer jmsConsumer2 = jmsContext.createDurableConsumer(jmsTopic1, subscriber2Name); JMSProducer jmsProducer = jmsContext.createProducer(); TextMessage recMsg1 = (TextMessage) jmsConsumer1.receive(30000); @@ -1398,15 +1425,15 @@ public void testPersistentMessageReceiveTopic( if ( ((recMsg1 == null) || (recMsg1.getText() == null) || - !recMsg1.getText().equals("testPersistentMessage_PersistentMsgTopic")) || - (recMsg2 != null)) { + !recMsg1.getText().equals("PersistentMessage_" + testPersistentTopicMessageIdentifier)) || + (recMsg2 != null) ) { testFailed = true; } jmsConsumer1.close(); jmsConsumer2.close(); - jmsContext.unsubscribe("durPersMsg1"); - jmsContext.unsubscribe("durPersMsg2"); + jmsContext.unsubscribe(subscriber1Name); + jmsContext.unsubscribe(subscriber2Name); jmsContext.close(); if ( testFailed ) { @@ -1414,33 +1441,29 @@ public void testPersistentMessageReceiveTopic( } } + private String testPersistentTopicMessageTcpIdentifier = "testPersistentTopicMessageTcp"; + public void testPersistentMessageTopic_Tcp( HttpServletRequest request, HttpServletResponse response) throws Exception { - - boolean testFailed = false; - - JMSContext jmsContext = jmsTCFTCP.createContext(); - JMSConsumer jmsConsumer1 = jmsContext.createDurableConsumer(jmsTopic, "durPersMsgTcp1"); - JMSConsumer jmsConsumer2 = jmsContext.createDurableConsumer(jmsTopic1, "durPersMsgTcp2"); - JMSProducer jmsProducer = jmsContext.createProducer(); - - jmsProducer.setDeliveryMode(DeliveryMode.PERSISTENT).setDeliveryDelay(1000); - jmsProducer.send(jmsTopic, "testPersistentMessage_PersistentMsgTopicTcp"); - - jmsProducer.setDeliveryDelay(1000).setDeliveryMode(DeliveryMode.NON_PERSISTENT); - jmsProducer.send(jmsTopic1, "testPersistentMessage_NonPersistentMsgTopicTcp"); - - // First half of test .. verification in the second half. + // Originally used message text "testPersistentMessage_PersistentMsgTopicTcp" "testPersistentMessage_NonPersistentMsgTopicTcp" + // jmsTCFTCP, jmsTopic, jmsTopic1 + + testPersistentMessageSimplifiedAPI_send(jmsTCFTCP, jmsTopic, jmsTopic1, testPersistentTopicMessageTcpIdentifier); + + return; } public void testPersistentMessageReceiveTopic_Tcp( HttpServletRequest request, HttpServletResponse response) throws Exception { boolean testFailed = false; + + String subscriber1Name = "durPersMsg1_" + testPersistentTopicMessageTcpIdentifier; + String subscriber2Name = "durPersMsg2_" + testPersistentTopicMessageTcpIdentifier; JMSContext jmsContext = jmsTCFTCP.createContext(); - JMSConsumer jmsConsumer1 = jmsContext.createDurableConsumer(jmsTopic, "durPersMsgTcp1"); - JMSConsumer jmsConsumer2 = jmsContext.createDurableConsumer(jmsTopic1, "durPersMsgTcp2"); + JMSConsumer jmsConsumer1 = jmsContext.createDurableConsumer(jmsTopic, subscriber1Name); + JMSConsumer jmsConsumer2 = jmsContext.createDurableConsumer(jmsTopic1, subscriber2Name); JMSProducer jmsProducer = jmsContext.createProducer(); TextMessage recMsg1 = (TextMessage) jmsConsumer1.receive(30000); @@ -1448,15 +1471,15 @@ public void testPersistentMessageReceiveTopic_Tcp( if ( ((recMsg1 == null) || (recMsg1.getText() == null) || - !recMsg1.getText().equals("testPersistentMessage_PersistentMsgTopicTcp")) || + !recMsg1.getText().equals("PersistentMessage_" + testPersistentTopicMessageTcpIdentifier)) || (recMsg2 != null) ) { testFailed = true; } jmsConsumer1.close(); jmsConsumer2.close(); - jmsContext.unsubscribe("durPersMsgTcp1"); - jmsContext.unsubscribe("durPersMsgTcp2"); + jmsContext.unsubscribe(subscriber1Name); + jmsContext.unsubscribe(subscriber2Name); jmsContext.close(); if ( testFailed ) { @@ -1464,6 +1487,266 @@ public void testPersistentMessageReceiveTopic_Tcp( } } + + // Old tests for classic API + + public void testPersistentMessageClassicApi( + HttpServletRequest request, HttpServletResponse response) throws Exception { + + QueueConnection con = jmsQCFBindings.createQueueConnection(); + con.start(); + + QueueSession sessionSender = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); + + QueueSender producer1 = sessionSender.createSender(jmsQueue); + emptyQueue(jmsQCFBindings, jmsQueue); + + QueueSender producer2 = sessionSender.createSender(jmsQueue1); + emptyQueue(jmsQCFBindings, jmsQueue1); + + producer1.setDeliveryMode(DeliveryMode.PERSISTENT); + producer1.setDeliveryDelay(1000); + TextMessage msg1 = sessionSender.createTextMessage("testPersistentMessage_PersistentMsgClassicApi"); + producer1.send(msg1); + + producer2.setDeliveryDelay(1000); + producer2.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + TextMessage msg2 = sessionSender.createTextMessage("testPersistentMessage_NonPersistentMsgClassicApi"); + producer2.send(msg2); + + sessionSender.close(); + con.close(); + } + + public void testPersistentMessageReceiveClassicApi( + HttpServletRequest request, HttpServletResponse response) throws Exception { + + boolean testFailed = false; + + QueueConnection con = jmsQCFBindings.createQueueConnection(); + con.start(); + + QueueSession sessionSender = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); + + QueueReceiver jmsConsumer1 = sessionSender.createReceiver(jmsQueue); + QueueReceiver jmsConsumer2 = sessionSender.createReceiver(jmsQueue); + + QueueSender producer = sessionSender.createSender(jmsQueue1); + + TextMessage msg1 = (TextMessage) jmsConsumer1.receive(30000); + TextMessage msg2 = (TextMessage) jmsConsumer2.receive(30000); + + if ( ((msg1 == null) || + (msg1.getText() == null) || + !msg1.getText().equals("testPersistentMessage_PersistentMsgClassicApi")) || + (msg2 != null) ) { + testFailed = true; + } + + sessionSender.close(); + con.close(); + + if ( testFailed ) { + throw new Exception("testPersistentMessageReceiveClassicApi failed"); + } + } + + public void testPersistentMessageClassicApi_Tcp( + HttpServletRequest request, HttpServletResponse response) throws Exception { + + QueueConnection con = jmsQCFTCP.createQueueConnection(); + con.start(); + + QueueSession sessionSender = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); + + QueueSender producer1 = sessionSender.createSender(jmsQueue); + emptyQueue(jmsQCFBindings, jmsQueue); + + QueueSender producer2 = sessionSender.createSender(jmsQueue1); + emptyQueue(jmsQCFBindings, jmsQueue1); + + producer1.setDeliveryMode(DeliveryMode.PERSISTENT); + producer1.setDeliveryDelay(1000); + TextMessage msg1 = sessionSender.createTextMessage("testPersistentMessage_PersistentMsgClassicApi"); + producer1.send(msg1); + + producer2.setDeliveryDelay(1000); + producer2.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + TextMessage msg2 = sessionSender.createTextMessage("testPersistentMessage_NonPersistentMsgClassicApi"); + producer2.send(msg2); + + sessionSender.close(); + con.close(); + } + + public void testPersistentMessageReceiveClassicApi_Tcp( + HttpServletRequest request, HttpServletResponse response) throws Exception { + + boolean testFailed = false; + + QueueConnection con = jmsQCFTCP.createQueueConnection(); + con.start(); + + QueueSession sessionSender = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); + + MessageConsumer jmsConsumer1 = sessionSender.createConsumer(jmsQueue); + MessageConsumer jmsConsumer2 = sessionSender.createConsumer(jmsQueue); + + QueueSender producer = sessionSender.createSender(jmsQueue1); + + TextMessage msg1 = (TextMessage) jmsConsumer1.receive(30000); + TextMessage msg2 = (TextMessage) jmsConsumer2.receive(30000); + + if ( ((msg1 == null) || + (msg1.getText() == null) || + !msg1.getText().equals("testPersistentMessage_PersistentMsgClassicApi")) || + (msg2 != null) ) { + testFailed = true; + } + + sessionSender.close(); + con.close(); + + if ( testFailed ) { + throw new Exception("testPersistentMessageReceiveClassicApi failed"); + } + } + + public void testPersistentMessageTopicClassicApi( + HttpServletRequest request, HttpServletResponse response) throws Exception { + + TopicConnection con = jmsTCFBindings.createTopicConnection(); + con.start(); + + TopicSession sessionSender = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + + TopicSubscriber jmsConsumer1 = sessionSender.createDurableSubscriber(jmsTopic, "durPersMsgCA1"); + TopicSubscriber jmsConsumer2 = sessionSender.createDurableSubscriber(jmsTopic1, "durPersMsgCA2"); + + TopicPublisher jmsProducer1 = sessionSender.createPublisher(jmsTopic); + TopicPublisher jmsProducer2 = sessionSender.createPublisher(jmsTopic1); + + jmsProducer1.setDeliveryMode(DeliveryMode.PERSISTENT); + jmsProducer1.setDeliveryDelay(1000); + TextMessage msg1 = sessionSender.createTextMessage("testPersistentMessage_PersistentMsgTopicClassicApi"); + jmsProducer1.send(msg1); + + jmsProducer2.setDeliveryDelay(1000); + jmsProducer2.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + TextMessage msg2 = sessionSender.createTextMessage("testPersistentMessage_NonPersistentMsgTopicClassicApi"); + jmsProducer2.send(msg2); + + con.close(); + } + + public void testPersistentMessageReceiveTopicClassicApi( + HttpServletRequest request, HttpServletResponse response) throws Exception { + + boolean testFailed = false; + + TopicConnection con = jmsTCFBindings.createTopicConnection(); + con.start(); + + TopicSession sessionSender = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + + TopicSubscriber jmsConsumer1 = sessionSender.createDurableSubscriber(jmsTopic, "durPersMsgCA1"); + TopicSubscriber jmsConsumer2 = sessionSender.createDurableSubscriber(jmsTopic1, "durPersMsgCA2"); + + TopicPublisher jmsProducer = sessionSender.createPublisher(jmsTopic); + + TextMessage msg1 = (TextMessage) jmsConsumer1.receive(30000); + TextMessage msg2 = (TextMessage) jmsConsumer2.receive(30000); + + if ( ((msg1 == null) || + (msg1.getText() == null) || + !msg1.getText().equals("testPersistentMessage_PersistentMsgTopicClassicApi")) || + (msg2 != null) ) { + testFailed = true; + } + + jmsConsumer1.close(); + jmsConsumer2.close(); + + sessionSender.unsubscribe("durPersMsgCA1"); + sessionSender.unsubscribe("durPersMsgCA2"); + sessionSender.close(); + + con.close(); + + if ( testFailed ) { + throw new Exception("testPersistentMessageReceiveTopicClassicApi failed"); + } + } + + public void testPersistentMessageTopicClassicApi_Tcp( + HttpServletRequest request, HttpServletResponse response) throws Exception { + + boolean testFailed = false; + + TopicConnection con = jmsTCFTCP.createTopicConnection(); + con.start(); + + TopicSession sessionSender = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + + TopicSubscriber jmsConsumer1 = sessionSender.createDurableSubscriber(jmsTopic, "durPersMsgCATcp1"); + TopicSubscriber jmsConsumer2 = sessionSender.createDurableSubscriber(jmsTopic1, "durPersMsgCATcp2"); + + TopicPublisher jmsProducer1 = sessionSender.createPublisher(jmsTopic); + TopicPublisher jmsProducer2 = sessionSender.createPublisher(jmsTopic1); + + jmsProducer1.setDeliveryMode(DeliveryMode.PERSISTENT); + jmsProducer1.setDeliveryDelay(1000); + TextMessage msg1 = sessionSender.createTextMessage("testPersistentMessage_PersistentMsgTopicClassicApiTcp"); + jmsProducer1.send(msg1); + + jmsProducer2.setDeliveryDelay(1000); + jmsProducer2.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + TextMessage msg2 = sessionSender.createTextMessage("testPersistentMessage_NonPersistentMsgTopicClassicApiTcp"); + jmsProducer2.send(msg2); + + con.close(); + } + + public void testPersistentMessageReceiveTopicClassicApi_Tcp( + HttpServletRequest request, HttpServletResponse response) throws Exception { + + boolean testFailed = false; + + TopicConnection con = jmsTCFTCP.createTopicConnection(); + con.start(); + + TopicSession sessionSender = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + + TopicSubscriber jmsConsumer1 = sessionSender.createDurableSubscriber(jmsTopic, "durPersMsgCATcp1"); + TopicSubscriber jmsConsumer2 = sessionSender.createDurableSubscriber(jmsTopic1, "durPersMsgCATcp2"); + + TopicPublisher jmsProducer = sessionSender.createPublisher(jmsTopic); + + TextMessage msg1 = (TextMessage) jmsConsumer1.receive(30000); + TextMessage msg2 = (TextMessage) jmsConsumer2.receive(30000); + + if ( ((msg1 == null) || + (msg1.getText() == null) || + !msg1.getText().equals("testPersistentMessage_PersistentMsgTopicClassicApiTcp")) || + (msg2 != null) ) { + testFailed = true; + } + + jmsConsumer1.close(); + jmsConsumer2.close(); + + sessionSender.unsubscribe("durPersMsgCATcp1"); + sessionSender.unsubscribe("durPersMsgCATcp2"); + sessionSender.close(); + + con.close(); + + if ( testFailed ) { + throw new Exception("testPersistentMessageStoreReceiveTopicClassicApi_Tcp failed"); + } + } + + public void testTimeToLiveWithDeliveryDelay( HttpServletRequest request, HttpServletResponse response) throws Exception { @@ -3697,261 +3980,6 @@ public void testGetDeliveryDelayClassicApiTopic_Tcp( } } - public void testPersistentMessageClassicApi( - HttpServletRequest request, HttpServletResponse response) throws Exception { - - QueueConnection con = jmsQCFBindings.createQueueConnection(); - con.start(); - - QueueSession sessionSender = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); - - QueueSender producer1 = sessionSender.createSender(jmsQueue); - emptyQueue(jmsQCFBindings, jmsQueue); - - QueueSender producer2 = sessionSender.createSender(jmsQueue1); - emptyQueue(jmsQCFBindings, jmsQueue1); - - producer1.setDeliveryMode(DeliveryMode.PERSISTENT); - producer1.setDeliveryDelay(1000); - TextMessage msg1 = sessionSender.createTextMessage("testPersistentMessage_PersistentMsgClassicApi"); - producer1.send(msg1); - - producer2.setDeliveryDelay(1000); - producer2.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - TextMessage msg2 = sessionSender.createTextMessage("testPersistentMessage_NonPersistentMsgClassicApi"); - producer2.send(msg2); - - sessionSender.close(); - con.close(); - } - - public void testPersistentMessageReceiveClassicApi( - HttpServletRequest request, HttpServletResponse response) throws Exception { - - boolean testFailed = false; - - QueueConnection con = jmsQCFBindings.createQueueConnection(); - con.start(); - - QueueSession sessionSender = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); - - QueueReceiver jmsConsumer1 = sessionSender.createReceiver(jmsQueue); - QueueReceiver jmsConsumer2 = sessionSender.createReceiver(jmsQueue); - - QueueSender producer = sessionSender.createSender(jmsQueue1); - - TextMessage msg1 = (TextMessage) jmsConsumer1.receive(30000); - TextMessage msg2 = (TextMessage) jmsConsumer2.receive(30000); - - if ( ((msg1 == null) || - (msg1.getText() == null) || - !msg1.getText().equals("testPersistentMessage_PersistentMsgClassicApi")) || - (msg2 != null) ) { - testFailed = true; - } - - sessionSender.close(); - con.close(); - - if ( testFailed ) { - throw new Exception("testPersistentMessageReceiveClassicApi failed"); - } - } - - public void testPersistentMessageClassicApi_Tcp( - HttpServletRequest request, HttpServletResponse response) throws Exception { - - QueueConnection con = jmsQCFTCP.createQueueConnection(); - con.start(); - - QueueSession sessionSender = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); - - QueueSender producer1 = sessionSender.createSender(jmsQueue); - emptyQueue(jmsQCFBindings, jmsQueue); - - QueueSender producer2 = sessionSender.createSender(jmsQueue1); - emptyQueue(jmsQCFBindings, jmsQueue1); - - producer1.setDeliveryMode(DeliveryMode.PERSISTENT); - producer1.setDeliveryDelay(1000); - TextMessage msg1 = sessionSender.createTextMessage("testPersistentMessage_PersistentMsgClassicApi"); - producer1.send(msg1); - - producer2.setDeliveryDelay(1000); - producer2.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - TextMessage msg2 = sessionSender.createTextMessage("testPersistentMessage_NonPersistentMsgClassicApi"); - producer2.send(msg2); - - sessionSender.close(); - con.close(); - } - - public void testPersistentMessageReceiveClassicApi_Tcp( - HttpServletRequest request, HttpServletResponse response) throws Exception { - - boolean testFailed = false; - - QueueConnection con = jmsQCFTCP.createQueueConnection(); - con.start(); - - QueueSession sessionSender = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); - - MessageConsumer jmsConsumer1 = sessionSender.createConsumer(jmsQueue); - MessageConsumer jmsConsumer2 = sessionSender.createConsumer(jmsQueue); - - QueueSender producer = sessionSender.createSender(jmsQueue1); - - TextMessage msg1 = (TextMessage) jmsConsumer1.receive(30000); - TextMessage msg2 = (TextMessage) jmsConsumer2.receive(30000); - - if ( ((msg1 == null) || - (msg1.getText() == null) || - !msg1.getText().equals("testPersistentMessage_PersistentMsgClassicApi")) || - (msg2 != null) ) { - testFailed = true; - } - - sessionSender.close(); - con.close(); - - if ( testFailed ) { - throw new Exception("testPersistentMessageReceiveClassicApi failed"); - } - } - - public void testPersistentMessageTopicClassicApi( - HttpServletRequest request, HttpServletResponse response) throws Exception { - - TopicConnection con = jmsTCFBindings.createTopicConnection(); - con.start(); - - TopicSession sessionSender = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - - TopicSubscriber jmsConsumer1 = sessionSender.createDurableSubscriber(jmsTopic, "durPersMsgCA1"); - TopicSubscriber jmsConsumer2 = sessionSender.createDurableSubscriber(jmsTopic1, "durPersMsgCA2"); - - TopicPublisher jmsProducer1 = sessionSender.createPublisher(jmsTopic); - TopicPublisher jmsProducer2 = sessionSender.createPublisher(jmsTopic1); - - jmsProducer1.setDeliveryMode(DeliveryMode.PERSISTENT); - jmsProducer1.setDeliveryDelay(1000); - TextMessage msg1 = sessionSender.createTextMessage("testPersistentMessage_PersistentMsgTopicClassicApi"); - jmsProducer1.send(msg1); - - jmsProducer2.setDeliveryDelay(1000); - jmsProducer2.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - TextMessage msg2 = sessionSender.createTextMessage("testPersistentMessage_NonPersistentMsgTopicClassicApi"); - jmsProducer2.send(msg2); - - con.close(); - } - - public void testPersistentMessageReceiveTopicClassicApi( - HttpServletRequest request, HttpServletResponse response) throws Exception { - - boolean testFailed = false; - - TopicConnection con = jmsTCFBindings.createTopicConnection(); - con.start(); - - TopicSession sessionSender = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - - TopicSubscriber jmsConsumer1 = sessionSender.createDurableSubscriber(jmsTopic, "durPersMsgCA1"); - TopicSubscriber jmsConsumer2 = sessionSender.createDurableSubscriber(jmsTopic1, "durPersMsgCA2"); - - TopicPublisher jmsProducer = sessionSender.createPublisher(jmsTopic); - - TextMessage msg1 = (TextMessage) jmsConsumer1.receive(30000); - TextMessage msg2 = (TextMessage) jmsConsumer2.receive(30000); - - if ( ((msg1 == null) || - (msg1.getText() == null) || - !msg1.getText().equals("testPersistentMessage_PersistentMsgTopicClassicApi")) || - (msg2 != null) ) { - testFailed = true; - } - - jmsConsumer1.close(); - jmsConsumer2.close(); - - sessionSender.unsubscribe("durPersMsgCA1"); - sessionSender.unsubscribe("durPersMsgCA2"); - sessionSender.close(); - - con.close(); - - if ( testFailed ) { - throw new Exception("testPersistentMessageReceiveTopicClassicApi failed"); - } - } - - public void testPersistentMessageTopicClassicApi_Tcp( - HttpServletRequest request, HttpServletResponse response) throws Exception { - - boolean testFailed = false; - - TopicConnection con = jmsTCFTCP.createTopicConnection(); - con.start(); - - TopicSession sessionSender = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - - TopicSubscriber jmsConsumer1 = sessionSender.createDurableSubscriber(jmsTopic, "durPersMsgCATcp1"); - TopicSubscriber jmsConsumer2 = sessionSender.createDurableSubscriber(jmsTopic1, "durPersMsgCATcp2"); - - TopicPublisher jmsProducer1 = sessionSender.createPublisher(jmsTopic); - TopicPublisher jmsProducer2 = sessionSender.createPublisher(jmsTopic1); - - jmsProducer1.setDeliveryMode(DeliveryMode.PERSISTENT); - jmsProducer1.setDeliveryDelay(1000); - TextMessage msg1 = sessionSender.createTextMessage("testPersistentMessage_PersistentMsgTopicClassicApiTcp"); - jmsProducer1.send(msg1); - - jmsProducer2.setDeliveryDelay(1000); - jmsProducer2.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - TextMessage msg2 = sessionSender.createTextMessage("testPersistentMessage_NonPersistentMsgTopicClassicApiTcp"); - jmsProducer2.send(msg2); - - con.close(); - } - - public void testPersistentMessageReceiveTopicClassicApi_Tcp( - HttpServletRequest request, HttpServletResponse response) throws Exception { - - boolean testFailed = false; - - TopicConnection con = jmsTCFTCP.createTopicConnection(); - con.start(); - - TopicSession sessionSender = con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - - TopicSubscriber jmsConsumer1 = sessionSender.createDurableSubscriber(jmsTopic, "durPersMsgCATcp1"); - TopicSubscriber jmsConsumer2 = sessionSender.createDurableSubscriber(jmsTopic1, "durPersMsgCATcp2"); - - TopicPublisher jmsProducer = sessionSender.createPublisher(jmsTopic); - - TextMessage msg1 = (TextMessage) jmsConsumer1.receive(30000); - TextMessage msg2 = (TextMessage) jmsConsumer2.receive(30000); - - if ( ((msg1 == null) || - (msg1.getText() == null) || - !msg1.getText().equals("testPersistentMessage_PersistentMsgTopicClassicApiTcp")) || - (msg2 != null) ) { - testFailed = true; - } - - jmsConsumer1.close(); - jmsConsumer2.close(); - - sessionSender.unsubscribe("durPersMsgCATcp1"); - sessionSender.unsubscribe("durPersMsgCATcp2"); - sessionSender.close(); - - con.close(); - - if ( testFailed ) { - throw new Exception("testPersistentMessageStoreReceiveTopicClassicApi_Tcp failed"); - } - } public void testJSAD_Send_Message_P2PTest( HttpServletRequest request, HttpServletResponse response) throws Exception { diff --git a/dev/com.ibm.ws.messaging.runtime/src/com/ibm/ws/sib/processor/proxyhandler/NeighbourProxyListener.java b/dev/com.ibm.ws.messaging.runtime/src/com/ibm/ws/sib/processor/proxyhandler/NeighbourProxyListener.java index d7f496838fa..c7ca885286b 100644 --- a/dev/com.ibm.ws.messaging.runtime/src/com/ibm/ws/sib/processor/proxyhandler/NeighbourProxyListener.java +++ b/dev/com.ibm.ws.messaging.runtime/src/com/ibm/ws/sib/processor/proxyhandler/NeighbourProxyListener.java @@ -1,5 +1,5 @@ -/******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. +/* ============================================================================= + * Copyright (c) 2012,2024 IBM Corporation and others. * All rights reserved. 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 @@ -9,7 +9,8 @@ * * Contributors: * IBM Corporation - initial API and implementation - *******************************************************************************/ + * ============================================================================= + */ package com.ibm.ws.sib.processor.proxyhandler; import java.util.ArrayList; @@ -198,43 +199,28 @@ public void consumeMessages(LockedMessageEnumeration messages) throws Exception // Get a transaction to operate under transaction = iProxyHandler.getTransactionManager().createLocalTransaction(true); - switch (subMessage.getSubscriptionMessageType().toInt()) - { - case SubscriptionMessageType.CREATE_INT : - + switch (subMessage.getSubscriptionMessageType()) { + case CREATE: // Create a new Proxy subscription handleCreateProxySubscription(subMessage, (Transaction) transaction); - break; - - case SubscriptionMessageType.DELETE_INT : - + case DELETE: // Delete a proxy subscription handleDeleteProxySubscription(subMessage, (Transaction) transaction); - break; - - case SubscriptionMessageType.RESET_INT : - + case RESET: // Reset the subscription state. handleResetState(subMessage, (Transaction) transaction, false); - break; - - case SubscriptionMessageType.REQUEST_INT : - + case REQUEST: // Reset the subscription state. handleResetState(subMessage, (Transaction) transaction, true); - break; - - case SubscriptionMessageType.REPLY_INT : - + case REPLY: // Reset the subscription state. handleResetState(subMessage, (Transaction) transaction, false); - break; - default : + default : // Log Message break; } @@ -317,50 +303,39 @@ void handleRollback(SubscriptionMessage subMessage, } Transaction msTran = iProxyHandler.getMessageProcessor().resolveAndEnlistMsgStoreTransaction(transaction); - - switch (subMessage.getSubscriptionMessageType().toInt()) - { - case SubscriptionMessageType.CREATE_INT : - + switch (subMessage.getSubscriptionMessageType()) { + case CREATE: // Remove any created Proxy subscriptions - iProxyHandler.remoteUnsubscribeEvent(iAddTopicSpaces, - iAddTopics, - subMessage.getBus(), - msTran, - false); - + iProxyHandler.remoteUnsubscribeEvent(iAddTopicSpaces, + iAddTopics, + subMessage.getBus(), + msTran, + false); break; - - case SubscriptionMessageType.DELETE_INT : - - // Create any removed Proxy subscriptions - iProxyHandler.remoteSubscribeEvent(iDeleteTopicSpaces, - iDeleteTopics, - subMessage.getBus(), - msTran, - false); - + case DELETE: + // Create any removed Proxy subscriptions + iProxyHandler.remoteSubscribeEvent(iDeleteTopicSpaces, + iDeleteTopics, + subMessage.getBus(), + msTran, + false); break; - - case SubscriptionMessageType.RESET_INT : - - // Remove any created Proxy subscriptions - iProxyHandler.remoteUnsubscribeEvent(iAddTopicSpaces, - iAddTopics, - subMessage.getBus(), - msTran, - false); - - // Create any removed Proxy subscriptions - iProxyHandler.remoteSubscribeEvent(iDeleteTopicSpaces, - iDeleteTopics, - subMessage.getBus(), - msTran, - false); - + case RESET: + // Remove any created Proxy subscriptions + iProxyHandler.remoteUnsubscribeEvent(iAddTopicSpaces, + iAddTopics, + subMessage.getBus(), + msTran, + false); + + // Create any removed Proxy subscriptions + iProxyHandler.remoteSubscribeEvent(iDeleteTopicSpaces, + iDeleteTopics, + subMessage.getBus(), + msTran, + false); break; - - default : + default : // Log Message break; } diff --git a/dev/com.ibm.ws.openapi.ui_fat/fat/src/com/ibm/ws/openapi/ui/fat/tests/UIBasicTest.java b/dev/com.ibm.ws.openapi.ui_fat/fat/src/com/ibm/ws/openapi/ui/fat/tests/UIBasicTest.java index 77e6630111e..810aa410848 100644 --- a/dev/com.ibm.ws.openapi.ui_fat/fat/src/com/ibm/ws/openapi/ui/fat/tests/UIBasicTest.java +++ b/dev/com.ibm.ws.openapi.ui_fat/fat/src/com/ibm/ws/openapi/ui/fat/tests/UIBasicTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 IBM Corporation and others. + * Copyright (c) 2023, 2024 IBM Corporation and others. * All rights reserved. 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 @@ -65,7 +65,7 @@ public class UIBasicTest { @Rule public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>().withCapabilities(new ChromeOptions()) .withAccessToHost(true) - .withRecordingMode(VncRecordingMode.RECORD_FAILING, + .withRecordingMode(VncRecordingMode.SKIP, Props.getInstance().getFileProperty(Props.DIR_LOG), VncRecordingFormat.MP4) .withLogConsumer(new SimpleLogConsumer(UIBasicTest.class, "selenium-driver")); diff --git a/dev/com.ibm.ws.wsat.recovery_fat.multi.1/fat/src/tests/MultiRecoveryTest1.java b/dev/com.ibm.ws.wsat.recovery_fat.multi.1/fat/src/tests/MultiRecoveryTest1.java index 755e17c204f..01ffbfb0924 100644 --- a/dev/com.ibm.ws.wsat.recovery_fat.multi.1/fat/src/tests/MultiRecoveryTest1.java +++ b/dev/com.ibm.ws.wsat.recovery_fat.multi.1/fat/src/tests/MultiRecoveryTest1.java @@ -44,6 +44,7 @@ public void WSTXMPR001CFVT() throws Exception { } @Test + @AllowedFFDC(value = { "com.ibm.ws.rsadapter.exceptions.DataStoreAdapterException", "javax.resource.spi.ResourceAllocationException"}) public void WSTXMPR002AFVT() throws Exception { recoveryTest(server1, server2, "201","server1"); } diff --git a/dev/com.ibm.ws.wsat.recovery_fat.multi.8.ee10/fat/src/tests/DBRerouteRecoveryTest.java b/dev/com.ibm.ws.wsat.recovery_fat.multi.8.ee10/fat/src/tests/DBRerouteRecoveryTest.java deleted file mode 100644 index 2a56a4c20f2..00000000000 --- a/dev/com.ibm.ws.wsat.recovery_fat.multi.8.ee10/fat/src/tests/DBRerouteRecoveryTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020, 2024 IBM Corporation and others. - * All rights reserved. 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 - * http://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package tests; - -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; - -import com.ibm.websphere.simplicity.ShrinkHelper; -import com.ibm.websphere.simplicity.log.Log; -import com.ibm.ws.transaction.fat.util.FATUtils; -import com.ibm.ws.transaction.fat.util.SetupRunner; -import com.ibm.ws.transaction.fat.util.TxTestContainerSuite; -import com.ibm.ws.wsat.fat.util.DBTestBase; - -import componenttest.annotation.AllowedFFDC; -import componenttest.annotation.Server; -import componenttest.containers.SimpleLogConsumer; -import componenttest.custom.junit.runner.FATRunner; -import componenttest.topology.database.container.DatabaseContainerType; -import componenttest.topology.database.container.DatabaseContainerUtil; -import componenttest.topology.database.container.PostgreSQLContainer; -import componenttest.topology.impl.LibertyServer; - -@AllowedFFDC(value = { "com.ibm.tx.jta.ut.util.AlreadyDumpedException", "javax.transaction.SystemException", "javax.transaction.xa.XAException", "java.io.IOException", "java.io.EOFException" }) -@RunWith(FATRunner.class) -public class DBRerouteRecoveryTest extends MultiRecoveryTest1 { - - @Server("WSATRecovery3") - public static LibertyServer server3; - - public static String[] serverNames = new String[] {"WSATRecoveryClient1", "WSATRecoveryServer1", "WSATRecovery3"}; - - @BeforeClass - public static void beforeClass() throws Exception { - Log.info(DBRerouteRecoveryTest.class, "beforeClass", ""); - - runner = new SetupRunner() { - @Override - public void run(LibertyServer s) throws Exception { - Log.info(DBRerouteRecoveryTest.class, "setupRunner.run", "Setting up "+s.getServerName()+" for testcontainers"); - - //Get driver name - s.addEnvVar("DB_DRIVER", DatabaseContainerType.valueOf(TxTestContainerSuite.testContainer).getDriverName()); - - //Setup server DataSource properties - DatabaseContainerUtil.setupDataSourceDatabaseProperties(s, TxTestContainerSuite.testContainer); - - s.setServerStartTimeout(FATUtils.LOG_SEARCH_TIMEOUT); - } - }; - -// System.getProperties().entrySet().stream().forEach(e -> Log.info(RerouteTest.class, "Properties", e.getKey() + " -> " + e.getValue())); -// System.getenv().entrySet().stream().forEach(e -> Log.info(RerouteTest.class, "Environment", e.getKey() + " -> " + e.getValue())); - - BASE_URL = "http://" + server1.getHostname() + ":" + server1.getHttpDefaultPort(); - - server2.setHttpDefaultPort(Integer.parseInt(System.getProperty("HTTP_secondary"))); - BASE_URL2 = "http://" + server2.getHostname() + ":" + server2.getHttpDefaultPort(); - - server3.setHttpDefaultPort(Integer.parseInt(System.getProperty("HTTP_tertiary"))); - - DBTestBase.initWSATTest(server1); - DBTestBase.initWSATTest(server2); - - final WebArchive clientApp = ShrinkHelper.buildDefaultApp("recoveryClient", "client.*"); - ShrinkHelper.exportDropinAppToServer(server1, clientApp); - ShrinkHelper.exportDropinAppToServer(server2, clientApp); - - final WebArchive serverApp = ShrinkHelper.buildDefaultApp("recoveryServer", "server.*"); - ShrinkHelper.exportDropinAppToServer(server1, serverApp); - ShrinkHelper.exportDropinAppToServer(server2, serverApp); - } - - @AfterClass - public static void afterClass() throws Exception { - Log.info(DBRerouteRecoveryTest.class, "afterClass", ""); - - DBTestBase.cleanupWSATTest(server1); - DBTestBase.cleanupWSATTest(server2); - } - - @Before - public void before() throws Exception { - Log.info(DBRerouteRecoveryTest.class, "before", ""); - FATUtils.startServers(runner, server1, server2, server3); - } - - @After - public void after() throws Exception { - Log.info(DBRerouteRecoveryTest.class, "after", ""); - FATUtils.stopServers(server1, server2, server3); - } -} diff --git a/dev/com.ibm.wsspi.thirdparty.equinox/bnd.bnd b/dev/com.ibm.wsspi.thirdparty.equinox/bnd.bnd index a33253762bb..e46a10fbfb0 100644 --- a/dev/com.ibm.wsspi.thirdparty.equinox/bnd.bnd +++ b/dev/com.ibm.wsspi.thirdparty.equinox/bnd.bnd @@ -11,7 +11,7 @@ # IBM Corporation - initial API and implementation #******************************************************************************* -include= ~../cnf/resources/bnd/bundle.props -bVersion=1.3 +bVersion=1.4 Bundle-SymbolicName: com.ibm.wsspi.thirdparty.equinox Bundle-Name: WebSphere Equinox Third-Party SPI diff --git a/dev/fattest.simplicity/src/componenttest/rules/repeater/JakartaEE10Action.java b/dev/fattest.simplicity/src/componenttest/rules/repeater/JakartaEE10Action.java index eb934b940fb..c41de4045a3 100644 --- a/dev/fattest.simplicity/src/componenttest/rules/repeater/JakartaEE10Action.java +++ b/dev/fattest.simplicity/src/componenttest/rules/repeater/JakartaEE10Action.java @@ -120,7 +120,7 @@ public JakartaEE10Action() { @Override public String toString() { - return "JakartaEE10 FAT repeat action"; + return "JakartaEE10 FAT repeat action (" + getID() + ")"; } // diff --git a/dev/fattest.simplicity/src/componenttest/rules/repeater/JakartaEE11Action.java b/dev/fattest.simplicity/src/componenttest/rules/repeater/JakartaEE11Action.java index 70b3e3c5797..60e06cb61ba 100644 --- a/dev/fattest.simplicity/src/componenttest/rules/repeater/JakartaEE11Action.java +++ b/dev/fattest.simplicity/src/componenttest/rules/repeater/JakartaEE11Action.java @@ -150,7 +150,7 @@ protected JakartaEE11Action() { @Override public String toString() { - return "JakartaEE11 FAT repeat action"; + return "JakartaEE11 FAT repeat action (" + getID() + ")"; } // diff --git a/dev/io.openliberty.cdi.4.1.thirdparty/bnd.bnd b/dev/io.openliberty.cdi.4.1.thirdparty/bnd.bnd index 143f1fef9c1..e864adbd74b 100644 --- a/dev/io.openliberty.cdi.4.1.thirdparty/bnd.bnd +++ b/dev/io.openliberty.cdi.4.1.thirdparty/bnd.bnd @@ -20,8 +20,8 @@ Bundle-SymbolicName: io.openliberty.cdi.4.1.thirdparty Bundle-Description: WebSphere CDI 4.1 Weld Third Party API Export-Package:\ - org.jboss.weld.context;version=6.0.0.Beta1, \ - org.jboss.weld.context.*;version=6.0.0.Beta1 + org.jboss.weld.context;version=6.0.0.CR1, \ + org.jboss.weld.context.*;version=6.0.0.CR1 Import-Package:* diff --git a/dev/io.openliberty.concurrent.internal.cdi/resources/io/openliberty/concurrent/internal/cdi/resources/CWWKCMessages.nlsprops b/dev/io.openliberty.concurrent.internal.cdi/resources/io/openliberty/concurrent/internal/cdi/resources/CWWKCMessages.nlsprops index 577da15a041..8ea6fa9f8f8 100644 --- a/dev/io.openliberty.concurrent.internal.cdi/resources/io/openliberty/concurrent/internal/cdi/resources/CWWKCMessages.nlsprops +++ b/dev/io.openliberty.concurrent.internal.cdi/resources/io/openliberty/concurrent/internal/cdi/resources/CWWKCMessages.nlsprops @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2022,2023 IBM Corporation and others. +# Copyright (c) 2022,2024 IBM Corporation and others. # All rights reserved. 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 @@ -24,5 +24,34 @@ # which do NOT contain replacement variables are NOT processed by the MessageFormat class # (single quote must be coded as one single quote '). -# All messages must use the range CWWCK1410 to CWWCK1499 +# All messages must use the range CWWKC1410 to CWWKC1499 +CWWKC1410.schedule.lacks.seconds=CWWKC1410E: The Schedule annotation, {0}, \ + specifies an empty value for the seconds at which the task runs. \ + Specify a nonempty value for the seconds field, or omit the seconds field \ + from the Schedule annotation. Omitting the seconds field schedules the task \ + to run at the start of the minute. +CWWKC1410.schedule.lacks.seconds.explanation=The empty array value indicates that \ + the seconds field must be disregarded when scheduled times are computed. \ + Omitting the seconds field schedules the task to run at the start of the minute. +CWWKC1410.schedule.lacks.seconds.useraction=Modify the seconds field of the \ + Schedule annotation to specify a nonempty value, or omit the seconds field \ + from the Schedule annotation. + +CWWKC1411.qualified.res.err=CWWKC1411E: The server did not create a {0} bean \ + for the {1} annotation or {2} deployment descriptor element. \ + The annotation or deployment descriptor element has the \ + {3} name and {4} qualifiers and is defined in the {5} application artifact. \ + The error is {6} +CWWKC1411.qualified.res.err.explanation=The code did not create the resource \ + or did not register the resource as a bean. +CWWKC1411.qualified.res.err.useraction=Ensure that the resource is configured \ + correctly. + +CWWKC1412.qualifier.conflict=CWWKC1412E: The {0} application artifact includes \ + multiple {1} resource definitions that have the {2} qualifiers. The names of \ + the conflicting {1} resource definitions are {3}. +CWWKC1412.qualifier.conflict.explanation=Each resource definition of the \ + same type that has a qualifier must have a different qualifier. +CWWKC1412.qualifier.conflict.useraction=Ensure that each resource definition \ + of the same type has a different qualifier or does not have any qualifiers. diff --git a/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/ConcurrencyExtension.java b/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/ConcurrencyExtension.java index 6fa5842b720..b0c8079bac2 100644 --- a/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/ConcurrencyExtension.java +++ b/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/ConcurrencyExtension.java @@ -12,6 +12,8 @@ *******************************************************************************/ package io.openliberty.concurrent.internal.cdi; +import java.io.PrintWriter; +import java.io.StringWriter; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; @@ -24,8 +26,14 @@ import org.osgi.framework.ServiceReference; import com.ibm.websphere.csi.J2EEName; +import com.ibm.websphere.ras.Tr; +import com.ibm.websphere.ras.TraceComponent; +import com.ibm.websphere.ras.annotation.Trivial; import com.ibm.ws.cdi.CDIServiceUtils; +import com.ibm.ws.runtime.metadata.ApplicationMetaData; import com.ibm.ws.runtime.metadata.ComponentMetaData; +import com.ibm.ws.runtime.metadata.MetaData; +import com.ibm.ws.runtime.metadata.ModuleMetaData; import com.ibm.ws.threadContext.ComponentMetaDataAccessorImpl; import io.openliberty.concurrent.internal.cdi.interceptor.AsyncInterceptor; @@ -33,9 +41,13 @@ import io.openliberty.concurrent.internal.qualified.QualifiedResourceFactory; import jakarta.enterprise.concurrent.Asynchronous; import jakarta.enterprise.concurrent.ContextService; +import jakarta.enterprise.concurrent.ContextServiceDefinition; +import jakarta.enterprise.concurrent.ManagedExecutorDefinition; import jakarta.enterprise.concurrent.ManagedExecutorService; +import jakarta.enterprise.concurrent.ManagedScheduledExecutorDefinition; import jakarta.enterprise.concurrent.ManagedScheduledExecutorService; import jakarta.enterprise.concurrent.ManagedThreadFactory; +import jakarta.enterprise.concurrent.ManagedThreadFactoryDefinition; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Instance; @@ -51,6 +63,8 @@ * CDI Extension for Jakarta Concurrency 3.1+ in Jakarta EE 11+, which corresponds to CDI 4.1+ */ public class ConcurrencyExtension implements Extension { + private static final TraceComponent tc = Tr.register(ConcurrencyExtension.class); + private static final Annotation[] DEFAULT_QUALIFIER_ARRAY = new Annotation[] { Default.Literal.INSTANCE }; private static final Set DEFAULT_QUALIFIER_SET = Set.of(Default.Literal.INSTANCE); @@ -149,11 +163,14 @@ private void addBeans(AfterBeanDiscovery event, List, Qualified try { event.addBean(new ContextServiceBean(factory)); } catch (Throwable x) { - // TODO NLS - System.out.println(" E Unable to create a bean for the " + - factory + " ContextServiceDefinition with the " + factory.getQualifiers() + " qualifiers" + - " due to the following error: "); - x.printStackTrace(); + Tr.error(tc, "CWWKC1411.qualified.res.err", + ContextService.class.getSimpleName(), + ContextServiceDefinition.class.getSimpleName(), + "context-service", + factory.getName(), + factory.getQualifiers(), + toArtifactName(factory.getDeclaringMetadata()), + toStackTrace(x)); } } @@ -164,11 +181,14 @@ private void addBeans(AfterBeanDiscovery event, List, Qualified try { event.addBean(new ManagedExecutorBean(factory)); } catch (Throwable x) { - // TODO NLS - System.out.println(" E Unable to create a bean for the " + - factory + " ManagedExecutorDefinition with the " + factory.getQualifiers() + " qualifiers" + - " due to the following error: "); - x.printStackTrace(); + Tr.error(tc, "CWWKC1411.qualified.res.err", + ManagedExecutorService.class.getSimpleName(), + ManagedExecutorDefinition.class.getSimpleName(), + "managed-executor", + factory.getName(), + factory.getQualifiers(), + toArtifactName(factory.getDeclaringMetadata()), + toStackTrace(x)); } } @@ -179,11 +199,14 @@ private void addBeans(AfterBeanDiscovery event, List, Qualified try { event.addBean(new ManagedScheduledExecutorBean(factory)); } catch (Throwable x) { - // TODO NLS - System.out.println(" E Unable to create a bean for the " + - factory + " ManagedScheduledExecutorDefinition with the " + factory.getQualifiers() + " qualifiers" + - " due to the following error: "); - x.printStackTrace(); + Tr.error(tc, "CWWKC1411.qualified.res.err", + ManagedScheduledExecutorService.class.getSimpleName(), + ManagedScheduledExecutorDefinition.class.getSimpleName(), + "managed-scheduled-executor", + factory.getName(), + factory.getQualifiers(), + toArtifactName(factory.getDeclaringMetadata()), + toStackTrace(x)); } } @@ -194,11 +217,14 @@ private void addBeans(AfterBeanDiscovery event, List, Qualified try { event.addBean(new ManagedThreadFactoryBean(factory, extSvc)); } catch (Throwable x) { - // TODO NLS - System.out.println(" E Unable to create a bean for the " + - factory + " ManagedThreadFactoryDefinition with the " + factory.getQualifiers() + " qualifiers" + - " due to the following error: "); - x.printStackTrace(); + Tr.error(tc, "CWWKC1411.qualified.res.err", + ManagedThreadFactory.class.getSimpleName(), + ManagedThreadFactoryDefinition.class.getSimpleName(), + "managed-thread-factory", + factory.getName(), + factory.getQualifiers(), + toArtifactName(factory.getDeclaringMetadata()), + toStackTrace(x)); } } } @@ -223,4 +249,36 @@ public void afterDeploymentValidation(@Observes AfterDeploymentValidation event, qualifierSetsPerMTF = null; } } + + /** + * Utility method to obtain the JEE name for a MetaData instance if possible, + * and otherwise the name. + * + * @param metadata ComponentMetaData, ModuleMetaData, or ApplicationMetaData. + * @return the artifact name, preferably as a JEE name string. + */ + @Trivial + private static String toArtifactName(MetaData metadata) { + if (metadata instanceof ComponentMetaData) + return ((ComponentMetaData) metadata).getJ2EEName().toString(); + else if (metadata instanceof ModuleMetaData) + return ((ModuleMetaData) metadata).getJ2EEName().toString(); + else if (metadata instanceof ApplicationMetaData) + return ((ApplicationMetaData) metadata).getJ2EEName().toString(); + else + return metadata.getName(); + } + + /** + * Utility method that converts an exception to a stack trace string. + * + * @param x exception. + * @return stack trace string. + */ + @Trivial + private static String toStackTrace(Throwable x) { + StringWriter s = new StringWriter(); + x.printStackTrace(new PrintWriter(s)); + return s.toString(); + } } \ No newline at end of file diff --git a/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/ConcurrencyExtensionMetadata.java b/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/ConcurrencyExtensionMetadata.java index 99d75a561f1..07f408356e8 100644 --- a/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/ConcurrencyExtensionMetadata.java +++ b/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/ConcurrencyExtensionMetadata.java @@ -28,6 +28,8 @@ import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.component.annotations.ReferencePolicyOption; +import com.ibm.websphere.ras.Tr; +import com.ibm.websphere.ras.TraceComponent; import com.ibm.ws.cdi.extension.CDIExtensionMetadataInternal; import com.ibm.ws.container.service.metadata.extended.DeferredMetaDataFactory; import com.ibm.ws.javaee.version.JavaEEVersion; @@ -45,6 +47,8 @@ @Component(configurationPolicy = ConfigurationPolicy.IGNORE, service = { CDIExtensionMetadata.class, QualifiedResourceFactories.class }) public class ConcurrencyExtensionMetadata implements CDIExtensionMetadata, CDIExtensionMetadataInternal, QualifiedResourceFactories { + private static final TraceComponent tc = Tr.register(ConcurrencyExtensionMetadata.class); + private static final Set> beanClasses = Set.of(ContextService.class, ManagedExecutorService.class, ManagedScheduledExecutorService.class, @@ -121,20 +125,37 @@ public class ConcurrencyExtensionMetadata implements CDIExtensionMetadata, CDIEx * @param resourceFactory the resource factory */ @Override - public void add(String jeeName, QualifiedResourceFactory.Type resourceType, - List qualifierNames, QualifiedResourceFactory resourceFactory) { + public void add(String jeeName, + QualifiedResourceFactory.Type resourceType, + List qualifierNames, + QualifiedResourceFactory resourceFactory) { List, QualifiedResourceFactory>> list = resourceFactories.get(jeeName); if (list == null) { list = List.of(new HashMap<>(), new HashMap<>(), new HashMap<>(), new HashMap<>()); resourceFactories.put(jeeName, list); } - Map, QualifiedResourceFactory> qualifiersToResourceFactory = list.get(resourceType.ordinal()); - QualifiedResourceFactory conflict = qualifiersToResourceFactory.put(qualifierNames, resourceFactory); - - if (conflict != null) - throw new IllegalStateException("The " + jeeName + " application artifact defines multiple " + // - resourceType + " resources with the " + qualifierNames + " qualifiers."); // TODO NLS and Tr.error + Map, QualifiedResourceFactory> qualifiersToResourceFactory = // + list.get(resourceType.ordinal()); + QualifiedResourceFactory conflict = // + qualifiersToResourceFactory.put(qualifierNames, resourceFactory); + + if (conflict != null) { + Set names = Set.of(resourceFactory.getName(), conflict.getName()); + + Tr.error(tc, "CWWKC1412.qualifier.conflict", + jeeName, + resourceType, + resourceFactory.getQualifiers(), + names); + + throw new IllegalStateException(Tr // + .formatMessage(tc, "CWWKC1412.qualifier.conflict", + jeeName, + resourceType, + resourceFactory.getQualifiers(), + names)); + } } @Override diff --git a/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/interceptor/ScheduleCronTrigger.java b/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/interceptor/ScheduleCronTrigger.java index 90f15057d04..612259d6832 100644 --- a/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/interceptor/ScheduleCronTrigger.java +++ b/dev/io.openliberty.concurrent.internal.cdi/src/io/openliberty/concurrent/internal/cdi/interceptor/ScheduleCronTrigger.java @@ -17,6 +17,8 @@ import java.time.ZoneId; import java.time.ZonedDateTime; +import com.ibm.websphere.ras.Tr; +import com.ibm.websphere.ras.TraceComponent; import com.ibm.websphere.ras.annotation.Trivial; import jakarta.enterprise.concurrent.CronTrigger; @@ -27,6 +29,7 @@ * so that multiple triggers can compute from the same time. */ class ScheduleCronTrigger extends CronTrigger { + private static final TraceComponent tc = Tr.register(ScheduleCronTrigger.class); private static final Month[] ALL_MONTHS = Month.values(); @@ -105,7 +108,12 @@ static ScheduleCronTrigger create(Schedule schedule) { int[] seconds = schedule.seconds(); if (seconds.length == 0) - throw new IllegalArgumentException("seconds: {}"); // TODO NLS The seconds field cannot be ignored because no other units of Schedule are more granular. + // The seconds field cannot be ignored because no other + // units of Schedule are more granular. + throw new IllegalArgumentException(Tr // + .formatMessage(tc, + "CWWKC1410.schedule.lacks.seconds", + schedule)); trigger.months(months) // .daysOfMonth(daysOfMonth) // diff --git a/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/AppDefinedResourceFactory.java b/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/AppDefinedResourceFactory.java index c90b8805ecc..386cf0c214d 100644 --- a/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/AppDefinedResourceFactory.java +++ b/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/AppDefinedResourceFactory.java @@ -307,6 +307,12 @@ public MetaData getDeclaringMetadata() { return declaringMetadata; } + @Override + @Trivial + public String getName() { + return jndiName; + } + /** * Returns text showing an example of a valid qualifier with the specified * class name. diff --git a/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/qualified/QualifiedResourceFactory.java b/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/qualified/QualifiedResourceFactory.java index e30657e759b..7c5e94eb6d3 100644 --- a/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/qualified/QualifiedResourceFactory.java +++ b/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/qualified/QualifiedResourceFactory.java @@ -47,6 +47,14 @@ enum Type { */ MetaData getDeclaringMetadata(); + /** + * Returns the name of the resource definition, which is typically a + * JNDI name in java:comp, java:module, java:app, or java:global + * + * @return the name. + */ + String getName(); + /** * Returns instances of the qualifier annotations for this resource factory. * diff --git a/dev/io.openliberty.data.internal.persistence/resources/io/openliberty/data/internal/persistence/resources/CWWKDMessages.nlsprops b/dev/io.openliberty.data.internal.persistence/resources/io/openliberty/data/internal/persistence/resources/CWWKDMessages.nlsprops index 8dbac31d740..b368720c1c9 100644 --- a/dev/io.openliberty.data.internal.persistence/resources/io/openliberty/data/internal/persistence/resources/CWWKDMessages.nlsprops +++ b/dev/io.openliberty.data.internal.persistence/resources/io/openliberty/data/internal/persistence/resources/CWWKDMessages.nlsprops @@ -125,9 +125,9 @@ CWWKD1009.lifecycle.param.err.explanation=Lifecycle methods must have a single \ CWWKD1009.lifecycle.param.err.useraction=Update the repository method to have a \ single parameter that is an entity or an array of List of the entity. -CWWKD1010.unknown.entity.prop=CWWKD1010E: The {0} method of the {1} repository \ - interface expects an entity property named {2} that is not found on the \ - {3} entity class. Valid property names for the entity are: {4}. +CWWKD1010.unknown.entity.prop=CWWKD1010E: An entity property named {0} is \ + not found on the {1} entity class for the {2} method of the {3} repository \ + interface. Valid property names for the entity are: {4}. CWWKD1010.unknown.entity.prop.explanation=The repository method is attempting \ to use an entity property that does not exist. CWWKD1010.unknown.entity.prop.useraction=Update the repository method to match \ @@ -908,3 +908,32 @@ CWWKD1090.orderby.conflict.explanation=The OrderBy annotation is not compatible with the OrderBy keyword. CWWKD1090.orderby.conflict.useraction=Use only the OrderBy annotation or the \ OrderBy keyword. + +CWWKD1091.method.name.parse.err=CWWKD1091E: An entity property named {0} is \ + not found on the {1} entity class for the {2} method of the {3} repository \ + interface. Confirm that the repository method either has a name that conforms \ + to the Query by Method Name pattern or is annotated with one of: {4}. \ + Valid property names for the entity are: {5}. +CWWKD1091.method.name.parse.err.explanation=The repository method name was parsed \ + according to the Query by Method Name pattern because the repository method \ + does not have a Jakarta Data annotation that indicates the type of operation. +CWWKD1091.method.name.parse.err.useraction=Correct the repository method name \ + or annotate the repository method to indicate a Jakarta Data operation such as \ + Query, Find, or Save. + +CWWKD1092.lifecycle.arg.empty=CWWKD1092E: The {0} method of the {1} repository \ + does not accept an empty {2} parameter. The parameter value must contain at \ + least one entity. +CWWKD1092.lifecycle.arg.empty.explanation=Insert, Update, Save, and Delete methods + require at least one entity. +CWWKD1092.lifecycle.arg.empty.useraction=Ensure that the array, List, or Stream \ + that is supplied to the method contains at least one entity. + +CWWKD1093.fn.not.applicable=CWWKD1093E: The {0} function cannot be evaluated \ + for the {1} entity that is used by the {2} method of the {3} repository \ + interface. The entity does not have a property that is annotated with {4} \ + or from which {0} can be inferred. +CWWKD1093.fn.not.applicable.explanation=The function cannot be used on the entity \ + because the entity lacks an ID or version property. +CWWKD1093.fn.not.applicable.useraction=Do not use the function in query language \ + or parameters for the repository method. diff --git a/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/QueryInfo.java b/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/QueryInfo.java index e2be4a18121..cf33d7abc11 100644 --- a/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/QueryInfo.java +++ b/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/QueryInfo.java @@ -1163,6 +1163,14 @@ Object findAndUpdate(Object arg, EntityManager em) throws Exception { results.add(findAndUpdateOne(arg, em)); } } + + if (results.isEmpty()) + throw exc(IllegalArgumentException.class, + "CWWKD1092.lifecycle.arg.empty", + method.getName(), + repositoryInterface.getName(), + method.getGenericParameterTypes()[0].getTypeName()); + em.flush(); Class returnType = method.getReturnType(); @@ -2456,15 +2464,23 @@ String getAttributeName(String name, boolean failIfNotFound) { // id(this) attributeName = entityInfo.attributeNames.get(By.ID); if (attributeName == null && failIfNotFound) - throw new MappingException("Entity class " + entityInfo.getType().getName() + - " does not have a property named " + name + - " or which is designated as the @Id."); // TODO NLS + throw exc(UnsupportedOperationException.class, + "CWWKD1093.fn.not.applicable", + name, + entityInfo.getType().getName(), + method.getName(), + repositoryInterface.getName(), + "@Id"); } else if (len == 13 && name.regionMatches(true, 0, "version", 0, 7)) { // version(this) if (entityInfo.versionAttributeName == null && failIfNotFound) - throw new MappingException("Entity class " + entityInfo.getType().getName() + - " does not have a property named " + name + - " or which is designated as the @Version."); // TODO NLS + throw exc(UnsupportedOperationException.class, + "CWWKD1093.fn.not.applicable", + name, + entityInfo.getType().getName(), + method.getName(), + repositoryInterface.getName(), + "@Version"); else attributeName = entityInfo.versionAttributeName; } else { @@ -2479,10 +2495,10 @@ String getAttributeName(String name, boolean failIfNotFound) { else throw exc(MappingException.class, "CWWKD1010.unknown.entity.prop", - method.getName(), - repositoryInterface.getName(), name, entityInfo.getType().getName(), + method.getName(), + repositoryInterface.getName(), entityInfo.attributeTypes.keySet()); } else { String lowerName = name.toLowerCase(); @@ -2504,15 +2520,23 @@ String getAttributeName(String name, boolean failIfNotFound) { lowerName = lowerName.replace("_", ""); attributeName = entityInfo.attributeNames.get(lowerName); if (attributeName == null && failIfNotFound) { - // TODO If attempting to parse Query by Method Name without a By keyword, then the message - // should also include the possibility that repository method is missing an annotation. - throw exc(MappingException.class, - "CWWKD1010.unknown.entity.prop", - method.getName(), - repositoryInterface.getName(), - name, - entityInfo.getType().getName(), - entityInfo.attributeTypes.keySet()); + if (Util.hasOperationAnno(method)) + throw exc(MappingException.class, + "CWWKD1010.unknown.entity.prop", + name, + entityInfo.getType().getName(), + method.getName(), + repositoryInterface.getName(), + entityInfo.attributeTypes.keySet()); + else + throw exc(MappingException.class, + "CWWKD1091.method.name.parse.err", + name, + entityInfo.getType().getName(), + method.getName(), + repositoryInterface.getName(), + Util.OP_ANNOS, + entityInfo.attributeTypes.keySet()); } } } @@ -3501,11 +3525,12 @@ Object insert(Object arg, EntityManager em) throws Exception { ArrayList results; boolean hasSingularEntityParam = false; + int entityCount = 0; if (entityParamType.isArray()) { int length = Array.getLength(arg); results = resultVoid ? null : new ArrayList<>(length); - for (int i = 0; i < length; i++) { - Object entity = toEntity(Array.get(arg, i)); + for (; entityCount < length; entityCount++) { + Object entity = toEntity(Array.get(arg, entityCount)); em.persist(entity); if (results != null) results.add(entity); @@ -3519,6 +3544,7 @@ Object insert(Object arg, EntityManager em) throws Exception { if (arg instanceof Iterable) { results = resultVoid ? null : new ArrayList<>(); for (Object e : ((Iterable) arg)) { + entityCount++; Object entity = toEntity(e); em.persist(entity); if (results != null) @@ -3526,6 +3552,7 @@ Object insert(Object arg, EntityManager em) throws Exception { } em.flush(); } else { + entityCount = 1; hasSingularEntityParam = true; results = resultVoid ? null : new ArrayList<>(1); Object entity = toEntity(arg); @@ -3536,6 +3563,13 @@ Object insert(Object arg, EntityManager em) throws Exception { } } + if (entityCount == 0) + throw exc(IllegalArgumentException.class, + "CWWKD1092.lifecycle.arg.empty", + method.getName(), + repositoryInterface.getName(), + method.getGenericParameterTypes()[0].getTypeName()); + Class returnType = method.getReturnType(); Object returnValue; if (resultVoid) { @@ -3998,11 +4032,12 @@ Object save(Object arg, EntityManager em) throws Exception { List results; boolean hasSingularEntityParam = false; + int entityCount = 0; if (entityParamType.isArray()) { results = new ArrayList<>(); int length = Array.getLength(arg); - for (int i = 0; i < length; i++) - results.add(em.merge(toEntity(Array.get(arg, i)))); + for (; entityCount < length; entityCount++) + results.add(em.merge(toEntity(Array.get(arg, entityCount)))); em.flush(); } else { arg = arg instanceof Stream // @@ -4011,10 +4046,13 @@ Object save(Object arg, EntityManager em) throws Exception { if (Iterable.class.isAssignableFrom(entityParamType)) { results = new ArrayList<>(); - for (Object e : ((Iterable) arg)) + for (Object e : ((Iterable) arg)) { + entityCount++; results.add(em.merge(toEntity(e))); + } em.flush(); } else { + entityCount = 1; hasSingularEntityParam = true; results = resultVoid ? null : new ArrayList<>(1); Object entity = em.merge(toEntity(arg)); @@ -4024,6 +4062,13 @@ Object save(Object arg, EntityManager em) throws Exception { } } + if (entityCount == 0) + throw exc(IllegalArgumentException.class, + "CWWKD1092.lifecycle.arg.empty", + method.getName(), + repositoryInterface.getName(), + method.getGenericParameterTypes()[0].getTypeName()); + Class returnType = method.getReturnType(); Object returnValue; if (resultVoid) { diff --git a/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/RepositoryImpl.java b/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/RepositoryImpl.java index b41f05a0491..304a3820fda 100644 --- a/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/RepositoryImpl.java +++ b/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/RepositoryImpl.java @@ -847,7 +847,7 @@ else if (DoubleStream.class.equals(multiType)) queryInfo.returnArrayType.isInstance(firstNonNullResult) || queryInfo.returnArrayType.isPrimitive() && Util.isWrapperClassFor(queryInfo.returnArrayType, - firstNonNullResult.getClass())) { + firstNonNullResult.getClass())) { returnValue = Array.newInstance(queryInfo.returnArrayType, size); int i = 0; for (Object result : results) @@ -972,6 +972,13 @@ else if (DoubleStream.class.equals(multiType)) updateCount = queryInfo.remove(arg, em); } + if (numExpected == 0) + throw exc(IllegalArgumentException.class, + "CWWKD1092.lifecycle.arg.empty", + method.getName(), + repositoryInterface.getName(), + method.getGenericParameterTypes()[0].getTypeName()); + if (updateCount < numExpected) if (numExpected == 1) throw exc(OptimisticLockingFailureException.class, @@ -1016,6 +1023,13 @@ else if (DoubleStream.class.equals(multiType)) updateCount = queryInfo.update(arg, em); } + if (numExpected == 0) + throw exc(IllegalArgumentException.class, + "CWWKD1092.lifecycle.arg.empty", + method.getName(), + repositoryInterface.getName(), + method.getGenericParameterTypes()[0].getTypeName()); + if (updateCount < numExpected) if (numExpected == 1) throw exc(OptimisticLockingFailureException.class, diff --git a/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/Util.java b/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/Util.java index 55a7b56b194..b052a9a1c2c 100644 --- a/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/Util.java +++ b/dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/Util.java @@ -9,6 +9,8 @@ *******************************************************************************/ package io.openliberty.data.internal.persistence; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; @@ -27,6 +29,12 @@ import jakarta.data.Order; import jakarta.data.Sort; import jakarta.data.page.PageRequest; +import jakarta.data.repository.Delete; +import jakarta.data.repository.Find; +import jakarta.data.repository.Insert; +import jakarta.data.repository.Query; +import jakarta.data.repository.Save; +import jakarta.data.repository.Update; /** * A location for helper methods that do not require any state. @@ -44,6 +52,11 @@ public class Util { Set.of(long.class, int.class, short.class, byte.class, double.class, float.class); + /** + * List of Jakarta Data operation annotations for use in NLS messages. + */ + static final String OP_ANNOS = "Delete, Find, Insert, Query, Save, Update"; + /** * Return types for deleteBy that distinguish delete-only from find-and-delete. */ @@ -120,6 +133,31 @@ public static boolean cannotBeEntity(Class c) { Modifier.isAbstract(modifiers); } + /** + * Identifies whether a method is annotated with a Jakarta Data annotation + * that performs and operation, such as Query, Find, or Save. This method is + * for use by error reporting only, so it does not need to be very efficient. + * + * @param method repository method. + * @return if the repository method has an annotation indicating an operation. + */ + @Trivial + static final boolean hasOperationAnno(Method method) { + Set> operationAnnos = // + Set.of(Delete.class, + Insert.class, + Find.class, + Query.class, + Save.class, + Update.class); + + for (Annotation anno : method.getAnnotations()) + if (operationAnnos.contains(anno.annotationType())) + return true; + + return false; + } + /** * Indicates if the specified class is a wrapper for the primitive class. * diff --git a/dev/io.openliberty.data.internal_fat/test-applications/DataTestApp/src/test/jakarta/data/web/DataTestServlet.java b/dev/io.openliberty.data.internal_fat/test-applications/DataTestApp/src/test/jakarta/data/web/DataTestServlet.java index e55fb5407b5..402484a6cc1 100644 --- a/dev/io.openliberty.data.internal_fat/test-applications/DataTestApp/src/test/jakarta/data/web/DataTestServlet.java +++ b/dev/io.openliberty.data.internal_fat/test-applications/DataTestApp/src/test/jakarta/data/web/DataTestServlet.java @@ -5940,8 +5940,6 @@ public void testUpdateWithEntityParameter() { assertEquals(3, persons.updateSome(ulysses, ursula, uriah)); - assertEquals(0, persons.updateSome()); - assertEquals(4, people.deleteBySSN_IdBetween(0L, 999999999L)); } diff --git a/dev/io.openliberty.data.internal_fat_errorpaths/test-applications/DataErrPathsTestApp/src/test/jakarta/data/errpaths/web/DataErrPathsTestServlet.java b/dev/io.openliberty.data.internal_fat_errorpaths/test-applications/DataErrPathsTestApp/src/test/jakarta/data/errpaths/web/DataErrPathsTestServlet.java index 3aaa01f56f9..a418454e180 100644 --- a/dev/io.openliberty.data.internal_fat_errorpaths/test-applications/DataErrPathsTestApp/src/test/jakarta/data/errpaths/web/DataErrPathsTestServlet.java +++ b/dev/io.openliberty.data.internal_fat_errorpaths/test-applications/DataErrPathsTestApp/src/test/jakarta/data/errpaths/web/DataErrPathsTestServlet.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.CompletionException; +import java.util.stream.Stream; import jakarta.annotation.Resource; import jakarta.annotation.sql.DataSourceDefinition; @@ -177,6 +178,74 @@ public void testDuplicateNamedParam() { } } + /** + * Verify IllegalArgumentException is raised if you attempt to delete an + * empty list of entities. + */ + @Test + public void testEmptyDelete() { + try { + voters.deleteAll(List.of()); + fail("Deleted an empty list of entities."); + } catch (IllegalArgumentException x) { + if (x.getMessage() == null || + !x.getMessage().startsWith("CWWKD1092E:") || + !x.getMessage().contains("deleteAll")) + throw x; + } + } + + /** + * Verify IllegalArgumentException is raised if you attempt to delete an + * empty array of entities. + */ + @Test + public void testEmptyInsert() { + try { + voters.register(new Voter[] {}); + fail("Inserted an empty array of entities."); + } catch (IllegalArgumentException x) { + if (x.getMessage() == null || + !x.getMessage().startsWith("CWWKD1092E:") || + !x.getMessage().contains("register")) + throw x; + } + } + + /** + * Verify IllegalArgumentException is raised if you attempt to save an + * empty list of entities. + */ + @Test + public void testEmptySave() { + try { + List saved = voters.saveAll(List.of()); + fail("Saved an empty list of entities. Result: " + saved); + } catch (IllegalArgumentException x) { + if (x.getMessage() == null || + !x.getMessage().startsWith("CWWKD1092E:") || + !x.getMessage().contains("saveAll")) + throw x; + } + } + + /** + * Verify IllegalArgumentException is raised if you attempt to update an + * empty stream of entities. + */ + @Test + public void testEmptyUpdate() { + try { + List updated = voters.changeAll(Stream.of()); + fail("Updated an empty stream of entities. Result: " + updated); + } catch (IllegalArgumentException x) { + if (x.getMessage() == null || + !x.getMessage().startsWith("CWWKD1092E:") || + !x.getMessage().contains("changeAll")) + throw x; + } + } + /** * Verify an error is raised for a repository method that has extra Param * annotations that do not correspond to any named parameters in the query. diff --git a/dev/io.openliberty.data.internal_fat_errorpaths/test-applications/DataErrPathsTestApp/src/test/jakarta/data/errpaths/web/Voters.java b/dev/io.openliberty.data.internal_fat_errorpaths/test-applications/DataErrPathsTestApp/src/test/jakarta/data/errpaths/web/Voters.java index 9e656840e5e..b25c4e0bd93 100644 --- a/dev/io.openliberty.data.internal_fat_errorpaths/test-applications/DataErrPathsTestApp/src/test/jakarta/data/errpaths/web/Voters.java +++ b/dev/io.openliberty.data.internal_fat_errorpaths/test-applications/DataErrPathsTestApp/src/test/jakarta/data/errpaths/web/Voters.java @@ -14,6 +14,7 @@ import java.time.Month; import java.util.List; +import java.util.stream.Stream; import jakarta.data.Sort; import jakarta.data.repository.BasicRepository; @@ -22,6 +23,7 @@ import jakarta.data.repository.Param; import jakarta.data.repository.Query; import jakarta.data.repository.Repository; +import jakarta.data.repository.Update; /** * Repository with a valid entity. @@ -60,6 +62,9 @@ List bornOn(@Param("year") int yearBorn, @Param("month") int monthNum, // duplicate parameter name @Param("day") int dayBorn); + @Update + List changeAll(Stream v); + /** * This invalid method has a conflict between its OrderBy annotation and * method name keyword. diff --git a/dev/io.openliberty.data.internal_fat_jpa/fat/src/test/jakarta/data/jpa/DataJPATest.java b/dev/io.openliberty.data.internal_fat_jpa/fat/src/test/jakarta/data/jpa/DataJPATest.java index 64496236569..860443566a4 100644 --- a/dev/io.openliberty.data.internal_fat_jpa/fat/src/test/jakarta/data/jpa/DataJPATest.java +++ b/dev/io.openliberty.data.internal_fat_jpa/fat/src/test/jakarta/data/jpa/DataJPATest.java @@ -42,7 +42,6 @@ public class DataJPATest extends FATServletClient { */ static final String[] EXPECTED_ERROR_MESSAGES = // new String[] { - "CWWKD1010E.*countBySurgePriceGreaterThanEqual", "CWWKD1026E.*allSorted", "CWWKD1046E.*publicDebtAsByte", "CWWKD1046E.*publicDebtAsDouble", @@ -55,7 +54,8 @@ public class DataJPATest extends FATServletClient { "CWWKD1046E.*numFullTimeWorkersAsShort", "CWWKD1054E.*findByIsControlTrueAndNumericValueBetween", "CWWKD1075E.*Apartment2", - "CWWKD1075E.*Apartment3" + "CWWKD1075E.*Apartment3", + "CWWKD1091E.*countBySurgePriceGreaterThanEqual" }; @ClassRule diff --git a/dev/io.openliberty.http.monitor_fat/publish/resources/META-INF/microprofile-config.properties b/dev/io.openliberty.http.monitor_fat/publish/resources/META-INF/microprofile-config.properties index 12f1f142cfb..b7fc1502df7 100644 --- a/dev/io.openliberty.http.monitor_fat/publish/resources/META-INF/microprofile-config.properties +++ b/dev/io.openliberty.http.monitor_fat/publish/resources/META-INF/microprofile-config.properties @@ -2,4 +2,4 @@ otel.metrics.exporter=otlp otel.sdk.disabled=false otel.traces.exporter=none otel.logs.exporter=none -otel.metric.export.interval=200 \ No newline at end of file +otel.metric.export.interval=1000 \ No newline at end of file diff --git a/dev/io.openliberty.http.monitor_fat/publish/servers/ContainerJustServer/jvm.options b/dev/io.openliberty.http.monitor_fat/publish/servers/ContainerJustServer/jvm.options index c2be5c22952..9cdd659ae36 100644 --- a/dev/io.openliberty.http.monitor_fat/publish/servers/ContainerJustServer/jvm.options +++ b/dev/io.openliberty.http.monitor_fat/publish/servers/ContainerJustServer/jvm.options @@ -2,4 +2,4 @@ -Dotel.traces.exporter=none -Dotel.logs.exporter=none -Dotel.sdk.disabled=false --Dotel.metric.export.interval=500 \ No newline at end of file +-Dotel.metric.export.interval=1000 \ No newline at end of file diff --git a/dev/io.openliberty.microprofile.openapi.2.0.internal_fat/fat/src/io/openliberty/microprofile/openapi20/fat/cache/CacheTest.java b/dev/io.openliberty.microprofile.openapi.2.0.internal_fat/fat/src/io/openliberty/microprofile/openapi20/fat/cache/CacheTest.java index 48ad6024129..27a694df515 100644 --- a/dev/io.openliberty.microprofile.openapi.2.0.internal_fat/fat/src/io/openliberty/microprofile/openapi20/fat/cache/CacheTest.java +++ b/dev/io.openliberty.microprofile.openapi.2.0.internal_fat/fat/src/io/openliberty/microprofile/openapi20/fat/cache/CacheTest.java @@ -44,7 +44,7 @@ @RunWith(FATRunner.class) public class CacheTest { - private static final String SERVER_NAME = "ApplicationProcessorServer"; + private static final String SERVER_NAME = "OpenAPITestServer"; @Server(SERVER_NAME) public static LibertyServer server; diff --git a/dev/io.openliberty.microprofile.openapi.2.0.internal_fat/fat/src/io/openliberty/microprofile/openapi20/fat/deployments/MergeConfigServerXMLTest.java b/dev/io.openliberty.microprofile.openapi.2.0.internal_fat/fat/src/io/openliberty/microprofile/openapi20/fat/deployments/MergeConfigServerXMLTest.java index 25d2fa798ad..988630223f5 100644 --- a/dev/io.openliberty.microprofile.openapi.2.0.internal_fat/fat/src/io/openliberty/microprofile/openapi20/fat/deployments/MergeConfigServerXMLTest.java +++ b/dev/io.openliberty.microprofile.openapi.2.0.internal_fat/fat/src/io/openliberty/microprofile/openapi20/fat/deployments/MergeConfigServerXMLTest.java @@ -120,7 +120,7 @@ public void testDefaultInclusion() throws Exception { OpenAPITestUtil.checkPaths(openapiNode, 1, "/test"); // Test that merging disabled message was output (at some point) - assertThat(server.findStringsInLogs(" I CWWKO1663I:.*Combining OpenAPI documentation from multiple modules is disabled."), + assertThat(server.findStringsInLogsUsingMark(" I CWWKO1663I:.*Combining OpenAPI documentation from multiple modules is disabled.", server.getDefaultLogFile()), hasSize(1)); // remove app 1 @@ -136,7 +136,7 @@ public void testDefaultInclusion() throws Exception { OpenAPITestUtil.checkPaths(openapiNode, 2, "/test1/test", "/test2/test"); // Check there's no "first module only" message - assertThat(server.findStringsInLogs("CWWKO1663I"), + assertThat(server.findStringsInLogsUsingMark("CWWKO1663I", server.getDefaultLogFile()), hasSize(0)); } } diff --git a/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UIBasicTest.java b/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UIBasicTest.java index cf85026b961..1a3b88c9fe3 100644 --- a/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UIBasicTest.java +++ b/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UIBasicTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 IBM Corporation and others. + * Copyright (c) 2023, 2024 IBM Corporation and others. * All rights reserved. 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 @@ -67,7 +67,7 @@ public class UIBasicTest { @Rule public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>().withCapabilities(new ChromeOptions()) .withAccessToHost(true) - .withRecordingMode(VncRecordingMode.RECORD_FAILING, + .withRecordingMode(VncRecordingMode.SKIP, Props.getInstance().getFileProperty(Props.DIR_LOG), VncRecordingFormat.MP4) .withLogConsumer(new SimpleLogConsumer(UIBasicTest.class, "selenium-driver")); diff --git a/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UICustomPathTest.java b/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UICustomPathTest.java index 7fd567df483..3b52357fb1b 100644 --- a/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UICustomPathTest.java +++ b/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UICustomPathTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 IBM Corporation and others. + * Copyright (c) 2023, 2024 IBM Corporation and others. * All rights reserved. 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 @@ -17,7 +17,6 @@ import static org.junit.Assert.assertNotNull; import java.time.Duration; -import java.util.Arrays; import org.hamcrest.Matchers; import org.jboss.shrinkwrap.api.ShrinkWrap; @@ -69,7 +68,7 @@ public class UICustomPathTest { @Rule public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>().withCapabilities(new ChromeOptions()).withAccessToHost(true) - .withRecordingMode(VncRecordingMode.RECORD_FAILING, + .withRecordingMode(VncRecordingMode.SKIP, Props.getInstance().getFileProperty(Props.DIR_LOG), VncRecordingFormat.MP4) .withLogConsumer(new SimpleLogConsumer(UICustomPathTest.class, "selenium-driver")); diff --git a/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UIOauthTest.java b/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UIOauthTest.java index ece5326f789..19f633cfa3e 100644 --- a/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UIOauthTest.java +++ b/dev/io.openliberty.microprofile.openapi.ui.internal_fat/fat/src/io/openliberty/microprofile/openapi/ui/internal/fat/tests/UIOauthTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 IBM Corporation and others. + * Copyright (c) 2023, 2024 IBM Corporation and others. * All rights reserved. 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 @@ -83,7 +83,7 @@ public class UIOauthTest { @Rule public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>().withCapabilities(new ChromeOptions()) .withAccessToHost(true) - .withRecordingMode(BrowserWebDriverContainer.VncRecordingMode.RECORD_FAILING, + .withRecordingMode(BrowserWebDriverContainer.VncRecordingMode.SKIP, Props.getInstance().getFileProperty(Props.DIR_LOG), VncRecordingFormat.MP4) .withLogConsumer(new SimpleLogConsumer(UIBasicTest.class, "selenium-driver")); diff --git a/dev/io.openliberty.microprofile.rest.client.4.0.internal_fat_tck/publish/tckRunner/tck/tck-suite.xml b/dev/io.openliberty.microprofile.rest.client.4.0.internal_fat_tck/publish/tckRunner/tck/tck-suite.xml index 56ea4d6f8cb..1b48dc5ff55 100644 --- a/dev/io.openliberty.microprofile.rest.client.4.0.internal_fat_tck/publish/tckRunner/tck/tck-suite.xml +++ b/dev/io.openliberty.microprofile.rest.client.4.0.internal_fat_tck/publish/tckRunner/tck/tck-suite.xml @@ -16,17 +16,5 @@ - - \ No newline at end of file + diff --git a/dev/io.openliberty.microprofile.telemetry.internal.monitor_fat/fat/src/io/openliberty/microprofile/telemetry/internal/monitor_fat/BaseTestClass.java b/dev/io.openliberty.microprofile.telemetry.internal.monitor_fat/fat/src/io/openliberty/microprofile/telemetry/internal/monitor_fat/BaseTestClass.java index bb47d3a0c18..780b33d046b 100644 --- a/dev/io.openliberty.microprofile.telemetry.internal.monitor_fat/fat/src/io/openliberty/microprofile/telemetry/internal/monitor_fat/BaseTestClass.java +++ b/dev/io.openliberty.microprofile.telemetry.internal.monitor_fat/fat/src/io/openliberty/microprofile/telemetry/internal/monitor_fat/BaseTestClass.java @@ -133,7 +133,7 @@ protected void matchStringsWithRetries(Supplier metricsOutput, String[] } - + private static BiFunction doMatching = (metricsText, expectedString) -> { for (String m : expectedString) { diff --git a/dev/io.openliberty.microprofile.telemetry.internal.monitor_fat/fat/src/io/openliberty/microprofile/telemetry/internal/monitor_fat/ConnectionPoolMetricsTest.java b/dev/io.openliberty.microprofile.telemetry.internal.monitor_fat/fat/src/io/openliberty/microprofile/telemetry/internal/monitor_fat/ConnectionPoolMetricsTest.java index 0494d531ac9..63cad61abea 100644 --- a/dev/io.openliberty.microprofile.telemetry.internal.monitor_fat/fat/src/io/openliberty/microprofile/telemetry/internal/monitor_fat/ConnectionPoolMetricsTest.java +++ b/dev/io.openliberty.microprofile.telemetry.internal.monitor_fat/fat/src/io/openliberty/microprofile/telemetry/internal/monitor_fat/ConnectionPoolMetricsTest.java @@ -94,7 +94,7 @@ public void connectionPoolTest() throws Exception { checkStrings(requestHttpServlet("/testJDBCApp/testJDBCServlet?operation=create", server), new String[] { "sql: create table cities" }); Log.info(c, testName, "------- connectionpool metrics should be available ------"); - + // Allow time for the collector to receive and expose metrics matchStringsWithRetries(() -> getContainerCollectorMetrics(container), new String[] { "io_openliberty_connection_pool_handle_count\\{instance=\"[a-zA-Z0-9-]*\",io_openliberty_datasource_name=\"jdbc/exampleDS1\",job=\"unknown_service\"\\}.*", diff --git a/dev/io.openliberty.org.jboss.weld6/bnd.bnd b/dev/io.openliberty.org.jboss.weld6/bnd.bnd index e832585a99d..b534ee5c70b 100644 --- a/dev/io.openliberty.org.jboss.weld6/bnd.bnd +++ b/dev/io.openliberty.org.jboss.weld6/bnd.bnd @@ -32,4 +32,4 @@ instrument.disabled: true ../build.sharedResources/lib/junit/old/junit.jar;version=file, \ com.ibm.ws.junit.extensions;version=latest,\ io.openliberty.jakarta.cdi.4.1;version=latest,\ - io.openliberty.org.jboss.logging35;version=latest + io.openliberty.org.jboss.logging36;version=latest diff --git a/dev/io.openliberty.org.jboss.weld6/build.gradle b/dev/io.openliberty.org.jboss.weld6/build.gradle index 47faddfaf14..8c299799470 100644 --- a/dev/io.openliberty.org.jboss.weld6/build.gradle +++ b/dev/io.openliberty.org.jboss.weld6/build.gradle @@ -11,7 +11,7 @@ import java.util.List; import java.util.stream.Collectors; ////// Update me when updating weld //// -def weldVersion = "6.0.0.Beta1" //// +def weldVersion = "6.0.0.CR1" //// //////////////////////////////////////// def unzippDir = "${buildDir}/unzip" @@ -35,9 +35,7 @@ def additionalExports = """\ """ def additionalImports = """\ - javax.security.auth,\\\\ jakarta.xml.ws;version="[4.0,5)",\\\\ - jakarta.servlet.descriptor,\\\\ """ // Key is a property, value is an addition. diff --git a/dev/io.openliberty.org.jboss.weld6/check-me-in-if-i-change.bnd b/dev/io.openliberty.org.jboss.weld6/check-me-in-if-i-change.bnd index 0ca8d36fa26..4e268128099 100644 --- a/dev/io.openliberty.org.jboss.weld6/check-me-in-if-i-change.bnd +++ b/dev/io.openliberty.org.jboss.weld6/check-me-in-if-i-change.bnd @@ -51,99 +51,98 @@ Service-Component: \ # Automatically filled in by build.gradle Export-Package: \ - org.jboss.weldx.transaction;version="6.0.0.Beta1",\ - org.jboss.weld.bean.proxy.util;version="6.0.0.Beta1",\ - org.jboss.weld.annotated.enhanced;version="6.0.0.Beta1",\ - org.jboss.weld.executor;version="6.0.0.Beta1",\ - org.jboss.weld.metadata;version="6.0.0.Beta1",\ - org.jboss.weld.resolution;version="6.0.0.Beta1",\ - org.jboss.weld.resources;version="6.0.0.Beta1",\ - org.jboss.weld.util.collections;version="6.0.0.Beta1",\ - org.jboss.weld.bootstrap.api;version="6.0.0.Beta1";uses:="jakarta.enterprise.inject.spi,org.jboss.weld.bootstrap.spi,org.jboss.weld.manager.api",\ - org.jboss.weld.bootstrap.api.helpers;version="6.0.0.Beta1";uses:="org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.manager.api",\ - org.jboss.weld.construction.api;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi",\ - org.jboss.weld.context.api;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi",\ - org.jboss.weld.ejb.api;version="6.0.0.Beta1",\ - org.jboss.weld.manager.api;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.el,org.jboss.weld.bootstrap.api,org.jboss.weld.construction.api,org.jboss.weld.context,org.jboss.weld.ejb.spi,org.jboss.weld.serialization.spi",\ - org.jboss.weld.servlet.api;version="6.0.0.Beta1";uses:="jakarta.servlet,jakarta.servlet.http",\ - org.jboss.weld.servlet.api.helpers;version="6.0.0.Beta1";uses:="jakarta.servlet,jakarta.servlet.http,org.jboss.weld.servlet.api",\ - org.jboss.weld.bootstrap.spi;version="6.0.0.Beta1";uses:="jakarta.enterprise.inject.spi,org.jboss.weld.bootstrap.api,org.jboss.weld.ejb.spi",\ - org.jboss.weld.bootstrap.spi.helpers;version="6.0.0.Beta1";uses:="org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.ejb.spi",\ - org.jboss.weld.configuration.spi;version="6.0.0.Beta1";uses:="org.jboss.weld.bootstrap.api",\ - org.jboss.weld.configuration.spi.helpers;version="6.0.0.Beta1";uses:="org.jboss.weld.configuration.spi",\ - org.jboss.weld.ejb.spi;version="6.0.0.Beta1";uses:="jakarta.enterprise.inject.spi,org.jboss.weld.bootstrap.api,org.jboss.weld.ejb.api",\ - org.jboss.weld.ejb.spi.helpers;version="6.0.0.Beta1";uses:="org.jboss.weld.ejb.api,org.jboss.weld.ejb.spi",\ - org.jboss.weld.injection.spi;version="6.0.0.Beta1";uses:="jakarta.enterprise.inject.spi,jakarta.persistence,org.jboss.weld.bootstrap.api",\ - org.jboss.weld.injection.spi.helpers;version="6.0.0.Beta1";uses:="jakarta.annotation,jakarta.enterprise.inject.spi,jakarta.persistence,javax.naming,org.jboss.weld.bootstrap.api,org.jboss.weld.injection.spi",\ - org.jboss.weld.interceptor.spi.metadata;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,org.jboss.weld.interceptor.proxy,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager",\ - org.jboss.weld.interceptor.spi.model;version="6.0.0.Beta1";uses:="jakarta.enterprise.inject.spi,org.jboss.weld.interceptor.spi.metadata",\ - org.jboss.weld.resources.spi;version="6.0.0.Beta1";uses:="org.jboss.weld.bootstrap.api",\ - org.jboss.weld.resources.spi.helpers;version="6.0.0.Beta1";uses:="org.jboss.weld.resources.spi",\ - org.jboss.weld.security.spi;version="6.0.0.Beta1";uses:="org.jboss.weld.bootstrap.api",\ - org.jboss.weld.serialization.spi;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,org.jboss.weld.bootstrap.api,org.jboss.weld.serialization.spi.helpers",\ - org.jboss.weld.serialization.spi.helpers;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,org.jboss.weld.context.api",\ - org.jboss.weld.servlet.spi;version="6.0.0.Beta1";uses:="jakarta.servlet.http,org.jboss.weld.bootstrap.api",\ - org.jboss.weld.servlet.spi.helpers;version="6.0.0.Beta1";uses:="jakarta.servlet.http,org.jboss.weld.servlet.spi",\ - org.jboss.weld.transaction.spi;version="6.0.0.Beta1";uses:="jakarta.transaction,org.jboss.weld.bootstrap.api",\ - org.jboss.weld.bootstrap.event;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.configurator,jakarta.enterprise.util,jakarta.interceptor",\ - org.jboss.weld.context;version="6.0.0.Beta1";uses:="jakarta.enterprise.context,jakarta.enterprise.context.spi,org.jboss.weld.context.api",\ - org.jboss.weld.context.activator;version="6.0.0.Beta1";uses:="jakarta.enterprise.util,jakarta.interceptor",\ - org.jboss.weld.context.bound;version="6.0.0.Beta1";uses:="jakarta.enterprise.util,jakarta.inject,org.jboss.weld.context",\ - org.jboss.weld.context.ejb;version="6.0.0.Beta1";uses:="jakarta.enterprise.util,jakarta.inject,jakarta.interceptor,org.jboss.weld.context",\ - org.jboss.weld.context.http;version="6.0.0.Beta1";uses:="jakarta.enterprise.util,jakarta.inject,jakarta.servlet.http,org.jboss.weld.context",\ - org.jboss.weld.context.unbound;version="6.0.0.Beta1";uses:="jakarta.enterprise.util,jakarta.inject",\ - org.jboss.weld.events;version="6.0.0.Beta1";uses:="jakarta.enterprise.event,jakarta.enterprise.util",\ - org.jboss.weld.inject;version="6.0.0.Beta1";uses:="jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.util",\ - org.jboss.weld.interceptor;version="6.0.0.Beta1";uses:="jakarta.interceptor",\ - org.jboss.weld.proxy;version="6.0.0.Beta1";uses:="jakarta.enterprise.inject.spi",\ - org.jboss.weld.lite.extension.translator;version="6.0.0.Beta1";uses:="jakarta.annotation,jakarta.enterprise.event,jakarta.enterprise.inject.build.compatible.spi,jakarta.enterprise.inject.spi,jakarta.enterprise.lang.model,jakarta.enterprise.lang.model.declarations",\ - org.jboss.weld.lite.extension.translator.logging;version="6.0.0.Beta1";uses:="org.jboss.logging,org.jboss.weld.exceptions",\ - org.jboss.weld.lite.extension.translator.util;version="6.0.0.Beta1",\ - org.jboss.weld.lite.extension.translator.util.reflection;version="6.0.0.Beta1",\ - org.jboss.weld.module.ejb;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.interceptor,org.jboss.weld.bean,org.jboss.weld.bean.proxy,org.jboss.weld.context.ejb,org.jboss.weld.manager,org.jboss.weld.module",\ - org.jboss.weld.module.ejb.context;version="6.0.0.Beta1";uses:="jakarta.interceptor,org.jboss.weld.context.ejb,org.jboss.weld.contexts",\ - org.jboss.weld.module.ejb.context.beanstore;version="6.0.0.Beta1";uses:="jakarta.interceptor,org.jboss.weld.contexts.beanstore",\ - org.jboss.weld.module.jsf;version="6.0.0.Beta1";uses:="jakarta.faces.application,jakarta.faces.context,org.jboss.weld.bootstrap.api,org.jboss.weld.module,org.jboss.weld.resources.spi,org.jboss.weld.util",\ - org.jboss.weld.module.jsf.servlet;version="6.0.0.Beta1";uses:="jakarta.servlet",\ - org.jboss.weld.module.jta;version="6.0.0.Beta1";uses:="org.jboss.weld.module",\ - org.jboss.weld.module.web;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,jakarta.servlet,jakarta.servlet.http,org.jboss.weld.bean.builtin,org.jboss.weld.manager,org.jboss.weld.module",\ - org.jboss.weld.module.web.context.beanstore.http;version="6.0.0.Beta1";uses:="jakarta.servlet.http,org.jboss.weld.bootstrap.api,org.jboss.weld.context.api,org.jboss.weld.contexts.beanstore,org.jboss.weld.serialization.spi",\ - org.jboss.weld.module.web.context.http;version="6.0.0.Beta1";uses:="jakarta.enterprise.context,jakarta.servlet.http,org.jboss.weld.bootstrap.api,org.jboss.weld.context.http,org.jboss.weld.contexts,org.jboss.weld.contexts.beanstore",\ - org.jboss.weld.module.web.el;version="6.0.0.Beta1";uses:="jakarta.el,org.jboss.weld.manager,org.jboss.weld.module.web.util.el",\ - org.jboss.weld.module.web.logging;version="6.0.0.Beta1";uses:="org.jboss.logging,org.jboss.weld.exceptions,org.jboss.weld.logging,org.jboss.weld.module.web.servlet",\ - org.jboss.weld.module.web.servlet;version="6.0.0.Beta1";uses:="jakarta.servlet,jakarta.servlet.http,org.jboss.weld.bootstrap.api,org.jboss.weld.context.http,org.jboss.weld.manager,org.jboss.weld.resources.spi,org.jboss.weld.servlet.api.helpers,org.jboss.weld.servlet.spi,org.jboss.weld.util",\ - org.jboss.weld.module.web.util.el;version="6.0.0.Beta1";uses:="jakarta.el",\ - org.jboss.weld.module.web.util.servlet;version="6.0.0.Beta1";uses:="jakarta.servlet,org.jboss.weld.manager,org.jboss.weld.servlet.spi",\ - org.jboss.weld;version="6.0.0.Beta1";uses:="jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.util,org.jboss.weld.bean.builtin,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.inject,org.jboss.weld.manager",\ - org.jboss.weld.bean;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,jakarta.interceptor,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.ejb.spi,org.jboss.weld.interceptor.spi.metadata,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager,org.jboss.weld.serialization.spi",\ - org.jboss.weld.bean.builtin;version="6.0.0.Beta1";uses:="jakarta.enterprise.context,jakarta.enterprise.context.control,jakarta.enterprise.context.spi,jakarta.enterprise.event,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.util,org.jboss.weld.bean,org.jboss.weld.bean.proxy,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.construction.api,org.jboss.weld.contexts,org.jboss.weld.ejb.spi,org.jboss.weld.inject,org.jboss.weld.injection,org.jboss.weld.manager,org.jboss.weld.manager.api,org.jboss.weld.serialization.spi,org.jboss.weld.util",\ - org.jboss.weld.bean.proxy;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,org.jboss.classfilewriter,org.jboss.classfilewriter.code,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.api.helpers,org.jboss.weld.config,org.jboss.weld.contexts.cache,org.jboss.weld.exceptions,org.jboss.weld.interceptor.proxy,org.jboss.weld.interceptor.spi.model,org.jboss.weld.interceptor.util.proxy,org.jboss.weld.manager,org.jboss.weld.proxy,org.jboss.weld.serialization.spi,org.jboss.weld.serialization.spi.helpers",\ - org.jboss.weld.bootstrap;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,org.jboss.weld.bean,org.jboss.weld.bean.builtin,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.api.helpers,org.jboss.weld.bootstrap.spi,org.jboss.weld.event,org.jboss.weld.exceptions,org.jboss.weld.logging,org.jboss.weld.manager,org.jboss.weld.manager.api,org.jboss.weld.module,org.jboss.weld.resources.spi",\ - org.jboss.weld.config;version="6.0.0.Beta1";uses:="org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi",\ - org.jboss.weld.contexts;version="6.0.0.Beta1";uses:="jakarta.enterprise.context,jakarta.enterprise.context.spi,org.jboss.weld.bootstrap.api,org.jboss.weld.construction.api,org.jboss.weld.context,org.jboss.weld.context.api,org.jboss.weld.contexts.beanstore,org.jboss.weld.contexts.conversation,org.jboss.weld.injection.spi,org.jboss.weld.interceptor.proxy,org.jboss.weld.serialization.spi,org.jboss.weld.serialization.spi.helpers",\ - org.jboss.weld.contexts.activator;version="6.0.0.Beta1";uses:="jakarta.annotation,jakarta.enterprise.context.control,jakarta.enterprise.inject,jakarta.inject,jakarta.interceptor,org.jboss.weld.context,org.jboss.weld.context.activator,org.jboss.weld.context.unbound,org.jboss.weld.event,org.jboss.weld.manager",\ - org.jboss.weld.contexts.beanstore;version="6.0.0.Beta1";uses:="org.jboss.weld.context.api,org.jboss.weld.serialization.spi",\ - org.jboss.weld.contexts.bound;version="6.0.0.Beta1";uses:="org.jboss.weld.bootstrap.api,org.jboss.weld.context.bound,org.jboss.weld.contexts,org.jboss.weld.contexts.beanstore",\ - org.jboss.weld.contexts.cache;version="6.0.0.Beta1",\ - org.jboss.weld.contexts.conversation;version="6.0.0.Beta1";uses:="jakarta.inject,org.jboss.weld.context,org.jboss.weld.manager",\ - org.jboss.weld.contexts.unbound;version="6.0.0.Beta1";uses:="jakarta.enterprise.context,jakarta.enterprise.context.spi,org.jboss.weld.context,org.jboss.weld.context.api,org.jboss.weld.contexts,org.jboss.weld.serialization.spi",\ - org.jboss.weld.event;thread-context=true;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.event,jakarta.enterprise.inject.spi,jakarta.enterprise.util,org.jboss.weld.bean,org.jboss.weld.bean.builtin,org.jboss.weld.bootstrap.api,org.jboss.weld.events,org.jboss.weld.injection,org.jboss.weld.manager,org.jboss.weld.module,org.jboss.weld.util",\ - org.jboss.weld.exceptions;version="6.0.0.Beta1";uses:="jakarta.enterprise.inject,jakarta.enterprise.inject.spi",\ - org.jboss.weld.injection;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.configurator,org.jboss.weld.bootstrap.api,org.jboss.weld.injection.spi,org.jboss.weld.manager",\ - org.jboss.weld.interceptor.proxy;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,jakarta.interceptor,org.jboss.weld.bean.proxy,org.jboss.weld.interceptor,org.jboss.weld.interceptor.spi.metadata,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager,org.jboss.weld.util",\ - org.jboss.weld.interceptor.util.proxy;version="6.0.0.Beta1";uses:="org.jboss.weld.bean.proxy",\ - org.jboss.weld.logging;version="6.0.0.Beta1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,javax.naming,org.jboss.logging,org.jboss.weld.contexts,org.jboss.weld.exceptions",\ - org.jboss.weld.manager;version="6.0.0.Beta1";uses:="jakarta.el,jakarta.enterprise.context.spi,jakarta.enterprise.event,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.configurator,org.jboss.weld.bean,org.jboss.weld.bean.proxy,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.construction.api,org.jboss.weld.contexts,org.jboss.weld.ejb.spi,org.jboss.weld.event,org.jboss.weld.events,org.jboss.weld.inject,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager.api,org.jboss.weld.serialization.spi",\ - org.jboss.weld.module;version="6.0.0.Beta1";uses:="jakarta.el,jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,org.jboss.weld.bean,org.jboss.weld.bean.builtin,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.ejb.spi,org.jboss.weld.event,org.jboss.weld.manager",\ - org.jboss.weld.security;version="6.0.0.Beta1";uses:="org.jboss.weld.security.spi",\ - org.jboss.weld.util;version="6.0.0.Beta1";uses:="jakarta.el,jakarta.enterprise.context.spi,jakarta.enterprise.event,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.el,jakarta.enterprise.util,jakarta.interceptor,org.jboss.weld.bean,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.exceptions,org.jboss.weld.inject,org.jboss.weld.injection,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager,org.jboss.weld.resources.spi,org.jboss.weld.serialization.spi",\ - org.jboss.weld.xml;version="6.0.0.Beta1";uses:="org.jboss.weld.bootstrap.spi,org.xml.sax,org.xml.sax.helpers" + org.jboss.weldx.transaction;version="6.0.0.CR1",\ + org.jboss.weld.bean.proxy.util;version="6.0.0.CR1",\ + org.jboss.weld.annotated.enhanced;version="6.0.0.CR1",\ + org.jboss.weld.executor;version="6.0.0.CR1",\ + org.jboss.weld.metadata;version="6.0.0.CR1",\ + org.jboss.weld.resolution;version="6.0.0.CR1",\ + org.jboss.weld.resources;version="6.0.0.CR1",\ + org.jboss.weld.util.collections;version="6.0.0.CR1",\ + org.jboss.weld.bootstrap.api;version="6.0.0.CR1";uses:="jakarta.enterprise.inject.spi,org.jboss.weld.bootstrap.spi,org.jboss.weld.manager.api",\ + org.jboss.weld.bootstrap.api.helpers;version="6.0.0.CR1";uses:="org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.manager.api",\ + org.jboss.weld.construction.api;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi",\ + org.jboss.weld.context.api;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi",\ + org.jboss.weld.ejb.api;version="6.0.0.CR1",\ + org.jboss.weld.manager.api;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.el,org.jboss.weld.bootstrap.api,org.jboss.weld.construction.api,org.jboss.weld.context,org.jboss.weld.ejb.spi,org.jboss.weld.serialization.spi",\ + org.jboss.weld.servlet.api;version="6.0.0.CR1";uses:="jakarta.servlet,jakarta.servlet.http",\ + org.jboss.weld.servlet.api.helpers;version="6.0.0.CR1";uses:="jakarta.servlet,jakarta.servlet.http,org.jboss.weld.servlet.api",\ + org.jboss.weld.bootstrap.spi;version="6.0.0.CR1";uses:="jakarta.enterprise.inject.spi,org.jboss.weld.bootstrap.api,org.jboss.weld.ejb.spi",\ + org.jboss.weld.bootstrap.spi.helpers;version="6.0.0.CR1";uses:="org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.ejb.spi",\ + org.jboss.weld.configuration.spi;version="6.0.0.CR1";uses:="org.jboss.weld.bootstrap.api",\ + org.jboss.weld.configuration.spi.helpers;version="6.0.0.CR1";uses:="org.jboss.weld.configuration.spi",\ + org.jboss.weld.ejb.spi;version="6.0.0.CR1";uses:="jakarta.enterprise.inject.spi,org.jboss.weld.bootstrap.api,org.jboss.weld.ejb.api",\ + org.jboss.weld.ejb.spi.helpers;version="6.0.0.CR1";uses:="org.jboss.weld.ejb.api,org.jboss.weld.ejb.spi",\ + org.jboss.weld.injection.spi;version="6.0.0.CR1";uses:="jakarta.enterprise.inject.spi,jakarta.persistence,org.jboss.weld.bootstrap.api",\ + org.jboss.weld.injection.spi.helpers;version="6.0.0.CR1";uses:="jakarta.annotation,jakarta.enterprise.inject.spi,jakarta.persistence,javax.naming,org.jboss.weld.bootstrap.api,org.jboss.weld.injection.spi",\ + org.jboss.weld.interceptor.spi.metadata;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,org.jboss.weld.interceptor.proxy,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager",\ + org.jboss.weld.interceptor.spi.model;version="6.0.0.CR1";uses:="jakarta.enterprise.inject.spi,org.jboss.weld.interceptor.spi.metadata",\ + org.jboss.weld.resources.spi;version="6.0.0.CR1";uses:="org.jboss.weld.bootstrap.api",\ + org.jboss.weld.resources.spi.helpers;version="6.0.0.CR1";uses:="org.jboss.weld.resources.spi",\ + org.jboss.weld.security.spi;version="6.0.0.CR1";uses:="org.jboss.weld.bootstrap.api",\ + org.jboss.weld.serialization.spi;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,org.jboss.weld.bootstrap.api,org.jboss.weld.serialization.spi.helpers",\ + org.jboss.weld.serialization.spi.helpers;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,org.jboss.weld.context.api",\ + org.jboss.weld.servlet.spi;version="6.0.0.CR1";uses:="jakarta.servlet.http,org.jboss.weld.bootstrap.api",\ + org.jboss.weld.servlet.spi.helpers;version="6.0.0.CR1";uses:="jakarta.servlet.http,org.jboss.weld.servlet.spi",\ + org.jboss.weld.transaction.spi;version="6.0.0.CR1";uses:="jakarta.transaction,org.jboss.weld.bootstrap.api",\ + org.jboss.weld.bootstrap.event;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.configurator,jakarta.enterprise.invoke,jakarta.enterprise.util,jakarta.interceptor",\ + org.jboss.weld.context;version="6.0.0.CR1";uses:="jakarta.enterprise.context,jakarta.enterprise.context.spi,org.jboss.weld.context.api",\ + org.jboss.weld.context.activator;version="6.0.0.CR1";uses:="jakarta.enterprise.util,jakarta.interceptor",\ + org.jboss.weld.context.bound;version="6.0.0.CR1";uses:="jakarta.enterprise.util,jakarta.inject,org.jboss.weld.context",\ + org.jboss.weld.context.ejb;version="6.0.0.CR1";uses:="jakarta.enterprise.util,jakarta.inject,jakarta.interceptor,org.jboss.weld.context",\ + org.jboss.weld.context.http;version="6.0.0.CR1";uses:="jakarta.enterprise.util,jakarta.inject,jakarta.servlet.http,org.jboss.weld.context",\ + org.jboss.weld.context.unbound;version="6.0.0.CR1";uses:="jakarta.enterprise.util,jakarta.inject",\ + org.jboss.weld.events;version="6.0.0.CR1";uses:="jakarta.enterprise.event,jakarta.enterprise.util",\ + org.jboss.weld.inject;version="6.0.0.CR1";uses:="jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.util",\ + org.jboss.weld.interceptor;version="6.0.0.CR1";uses:="jakarta.interceptor",\ + org.jboss.weld.proxy;version="6.0.0.CR1";uses:="jakarta.enterprise.inject.spi",\ + org.jboss.weld.lite.extension.translator;version="6.0.0.CR1";uses:="jakarta.annotation,jakarta.enterprise.event,jakarta.enterprise.inject.build.compatible.spi,jakarta.enterprise.inject.spi,jakarta.enterprise.lang.model,jakarta.enterprise.lang.model.declarations",\ + org.jboss.weld.lite.extension.translator.logging;version="6.0.0.CR1";uses:="org.jboss.logging,org.jboss.weld.exceptions",\ + org.jboss.weld.lite.extension.translator.util;version="6.0.0.CR1",\ + org.jboss.weld.lite.extension.translator.util.reflection;version="6.0.0.CR1",\ + org.jboss.weld.module.ejb;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.interceptor,org.jboss.weld.bean,org.jboss.weld.bean.proxy,org.jboss.weld.context.ejb,org.jboss.weld.manager,org.jboss.weld.module",\ + org.jboss.weld.module.ejb.context;version="6.0.0.CR1";uses:="jakarta.interceptor,org.jboss.weld.context.ejb,org.jboss.weld.contexts",\ + org.jboss.weld.module.ejb.context.beanstore;version="6.0.0.CR1";uses:="jakarta.interceptor,org.jboss.weld.contexts.beanstore",\ + org.jboss.weld.module.jsf;version="6.0.0.CR1";uses:="jakarta.faces.application,jakarta.faces.context,org.jboss.weld.bootstrap.api,org.jboss.weld.module,org.jboss.weld.resources.spi,org.jboss.weld.util",\ + org.jboss.weld.module.jsf.servlet;version="6.0.0.CR1";uses:="jakarta.servlet",\ + org.jboss.weld.module.jta;version="6.0.0.CR1";uses:="org.jboss.weld.module",\ + org.jboss.weld.module.web;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,jakarta.servlet,jakarta.servlet.http,org.jboss.weld.bean.builtin,org.jboss.weld.manager,org.jboss.weld.module",\ + org.jboss.weld.module.web.context.beanstore.http;version="6.0.0.CR1";uses:="jakarta.servlet.http,org.jboss.weld.bootstrap.api,org.jboss.weld.context.api,org.jboss.weld.contexts.beanstore,org.jboss.weld.serialization.spi",\ + org.jboss.weld.module.web.context.http;version="6.0.0.CR1";uses:="jakarta.enterprise.context,jakarta.servlet.http,org.jboss.weld.bootstrap.api,org.jboss.weld.context.http,org.jboss.weld.contexts,org.jboss.weld.contexts.beanstore",\ + org.jboss.weld.module.web.el;version="6.0.0.CR1";uses:="jakarta.el,org.jboss.weld.manager,org.jboss.weld.module.web.util.el",\ + org.jboss.weld.module.web.logging;version="6.0.0.CR1";uses:="org.jboss.logging,org.jboss.weld.exceptions,org.jboss.weld.logging,org.jboss.weld.module.web.servlet",\ + org.jboss.weld.module.web.servlet;version="6.0.0.CR1";uses:="jakarta.servlet,jakarta.servlet.http,org.jboss.weld.bootstrap.api,org.jboss.weld.context.http,org.jboss.weld.manager,org.jboss.weld.resources.spi,org.jboss.weld.servlet.api.helpers,org.jboss.weld.servlet.spi,org.jboss.weld.util",\ + org.jboss.weld.module.web.util.el;version="6.0.0.CR1";uses:="jakarta.el",\ + org.jboss.weld.module.web.util.servlet;version="6.0.0.CR1";uses:="jakarta.servlet,org.jboss.weld.manager,org.jboss.weld.servlet.spi",\ + org.jboss.weld;version="6.0.0.CR1";uses:="jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.util,org.jboss.weld.bean.builtin,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.inject,org.jboss.weld.manager",\ + org.jboss.weld.bean;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,jakarta.interceptor,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.ejb.spi,org.jboss.weld.interceptor.spi.metadata,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager,org.jboss.weld.serialization.spi",\ + org.jboss.weld.bean.builtin;version="6.0.0.CR1";uses:="jakarta.enterprise.context,jakarta.enterprise.context.control,jakarta.enterprise.context.spi,jakarta.enterprise.event,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.util,org.jboss.weld.bean,org.jboss.weld.bean.proxy,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.construction.api,org.jboss.weld.contexts,org.jboss.weld.ejb.spi,org.jboss.weld.inject,org.jboss.weld.injection,org.jboss.weld.manager,org.jboss.weld.manager.api,org.jboss.weld.serialization.spi,org.jboss.weld.util",\ + org.jboss.weld.bean.proxy;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,org.jboss.classfilewriter,org.jboss.classfilewriter.code,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.api.helpers,org.jboss.weld.config,org.jboss.weld.contexts.cache,org.jboss.weld.exceptions,org.jboss.weld.interceptor.proxy,org.jboss.weld.interceptor.spi.model,org.jboss.weld.interceptor.util.proxy,org.jboss.weld.manager,org.jboss.weld.proxy,org.jboss.weld.serialization.spi,org.jboss.weld.serialization.spi.helpers",\ + org.jboss.weld.bootstrap;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,org.jboss.weld.bean,org.jboss.weld.bean.builtin,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.api.helpers,org.jboss.weld.bootstrap.spi,org.jboss.weld.event,org.jboss.weld.exceptions,org.jboss.weld.logging,org.jboss.weld.manager,org.jboss.weld.manager.api,org.jboss.weld.module,org.jboss.weld.resources.spi",\ + org.jboss.weld.config;version="6.0.0.CR1";uses:="org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi",\ + org.jboss.weld.contexts;version="6.0.0.CR1";uses:="jakarta.enterprise.context,jakarta.enterprise.context.spi,org.jboss.weld.bootstrap.api,org.jboss.weld.construction.api,org.jboss.weld.context,org.jboss.weld.context.api,org.jboss.weld.contexts.beanstore,org.jboss.weld.contexts.conversation,org.jboss.weld.injection.spi,org.jboss.weld.interceptor.proxy,org.jboss.weld.serialization.spi,org.jboss.weld.serialization.spi.helpers",\ + org.jboss.weld.contexts.activator;version="6.0.0.CR1";uses:="jakarta.annotation,jakarta.enterprise.context.control,jakarta.enterprise.inject,jakarta.inject,jakarta.interceptor,org.jboss.weld.context,org.jboss.weld.context.activator,org.jboss.weld.context.unbound,org.jboss.weld.event,org.jboss.weld.manager",\ + org.jboss.weld.contexts.beanstore;version="6.0.0.CR1";uses:="org.jboss.weld.context.api,org.jboss.weld.serialization.spi",\ + org.jboss.weld.contexts.bound;version="6.0.0.CR1";uses:="org.jboss.weld.bootstrap.api,org.jboss.weld.context.bound,org.jboss.weld.contexts,org.jboss.weld.contexts.beanstore",\ + org.jboss.weld.contexts.cache;version="6.0.0.CR1",\ + org.jboss.weld.contexts.conversation;version="6.0.0.CR1";uses:="jakarta.inject,org.jboss.weld.context,org.jboss.weld.manager",\ + org.jboss.weld.contexts.unbound;version="6.0.0.CR1";uses:="jakarta.enterprise.context,jakarta.enterprise.context.spi,org.jboss.weld.context,org.jboss.weld.context.api,org.jboss.weld.contexts,org.jboss.weld.serialization.spi",\ + org.jboss.weld.event;thread-context=true;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.event,jakarta.enterprise.inject.spi,jakarta.enterprise.util,org.jboss.weld.bean,org.jboss.weld.bean.builtin,org.jboss.weld.bootstrap.api,org.jboss.weld.events,org.jboss.weld.injection,org.jboss.weld.manager,org.jboss.weld.module,org.jboss.weld.util",\ + org.jboss.weld.exceptions;version="6.0.0.CR1";uses:="jakarta.enterprise.inject,jakarta.enterprise.inject.spi",\ + org.jboss.weld.injection;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.configurator,org.jboss.weld.bootstrap.api,org.jboss.weld.injection.spi,org.jboss.weld.manager",\ + org.jboss.weld.interceptor.proxy;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,jakarta.interceptor,org.jboss.weld.bean.proxy,org.jboss.weld.interceptor,org.jboss.weld.interceptor.spi.metadata,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager,org.jboss.weld.util",\ + org.jboss.weld.interceptor.util.proxy;version="6.0.0.CR1";uses:="org.jboss.weld.bean.proxy",\ + org.jboss.weld.logging;version="6.0.0.CR1";uses:="jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,javax.naming,org.jboss.logging,org.jboss.weld.contexts,org.jboss.weld.exceptions",\ + org.jboss.weld.manager;version="6.0.0.CR1";uses:="jakarta.el,jakarta.enterprise.context.spi,jakarta.enterprise.event,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.configurator,org.jboss.weld.bean,org.jboss.weld.bean.proxy,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.construction.api,org.jboss.weld.contexts,org.jboss.weld.ejb.spi,org.jboss.weld.event,org.jboss.weld.events,org.jboss.weld.inject,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager.api,org.jboss.weld.serialization.spi",\ + org.jboss.weld.module;version="6.0.0.CR1";uses:="jakarta.el,jakarta.enterprise.context.spi,jakarta.enterprise.inject.spi,org.jboss.weld.bean,org.jboss.weld.bean.builtin,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.ejb.spi,org.jboss.weld.event,org.jboss.weld.manager",\ + org.jboss.weld.security;version="6.0.0.CR1";uses:="org.jboss.weld.security.spi",\ + org.jboss.weld.util;version="6.0.0.CR1";uses:="jakarta.el,jakarta.enterprise.context.spi,jakarta.enterprise.event,jakarta.enterprise.inject,jakarta.enterprise.inject.spi,jakarta.enterprise.inject.spi.el,jakarta.enterprise.util,jakarta.interceptor,org.jboss.weld.bean,org.jboss.weld.bootstrap,org.jboss.weld.bootstrap.api,org.jboss.weld.bootstrap.spi,org.jboss.weld.exceptions,org.jboss.weld.inject,org.jboss.weld.injection,org.jboss.weld.interceptor.spi.model,org.jboss.weld.manager,org.jboss.weld.resources.spi,org.jboss.weld.serialization.spi",\ + org.jboss.weld.util.reflection;version="6.0.0.CR1";uses:="jakarta.enterprise.inject.spi,org.jboss.weld.ejb.spi,org.jboss.weld.resources.spi",\ + org.jboss.weld.xml;version="6.0.0.CR1";uses:="org.jboss.weld.bootstrap.spi,org.xml.sax,org.xml.sax.helpers" # Automatically filled in by build.gradle Import-Package: \ - javax.security.auth,\ jakarta.xml.ws;version="[4.0,5)",\ - jakarta.servlet.descriptor,\ jakarta.annotation,\ jakarta.ejb;resolution:=optional,\ jakarta.el;resolution:=optional,\ @@ -185,10 +184,9 @@ Import-Package: \ org.jboss.classfilewriter;version="[1.3,2)",\ org.jboss.classfilewriter.code;version="[1.3,2)",\ org.jboss.classfilewriter.util;version="[1.3,2)",\ - org.jboss.logging;version="[3.5,4)",\ + org.jboss.logging;version="[3.6,4)",\ org.jboss.weld.bootstrap.api;version="[6.0,7)",\ org.jboss.weld.bootstrap.api.helpers;version="[6.0,7)",\ - org.jboss.weld.bootstrap.event;version="[6.0,7)",\ org.jboss.weld.bootstrap.spi;version="[6.0,7)",\ org.jboss.weld.bootstrap.spi.helpers;version="[6.0,7)",\ org.jboss.weld.configuration.spi;version="[6.0,7)",\ @@ -222,6 +220,7 @@ Import-Package: \ org.jboss.weld.module.jsf;version="[6.0,7)",\ org.jboss.weld.module.web.el;version="[6.0,7)",\ org.jboss.weld.module.web.logging;version="[6.0,7)",\ + org.jboss.weld.module.web.servlet;version="[6.0,7)",\ org.jboss.weld.module.web.util.el;version="[6.0,7)",\ org.jboss.weld.module.web.util.servlet;version="[6.0,7)",\ org.jboss.weld.proxy;version="[6.0,7)",\ @@ -237,4 +236,6 @@ Import-Package: \ org.jboss.weld.transaction.spi;version="[6.0,7)",\ org.xml.sax,\ org.xml.sax.helpers,\ + jakarta.servlet.descriptor;resolution:=optional,\ + javax.security.auth;resolution:=optional,\ org.jboss.logging.annotations;resolution:=optional diff --git a/dev/org.eclipse.osgi/bnd.bnd b/dev/org.eclipse.osgi/bnd.bnd index d69def37e6b..a5521d57a7d 100644 --- a/dev/org.eclipse.osgi/bnd.bnd +++ b/dev/org.eclipse.osgi/bnd.bnd @@ -10,16 +10,15 @@ # Contributors: # IBM Corporation - initial API and implementation #******************************************************************************* --include= jar:${fileuri;${repo;org.eclipse.platform:org.eclipse.osgi;3.18.600}}!/META-INF/MANIFEST.MF,bnd.overrides +-include= jar:${fileuri;${repo;org.eclipse.platform:org.eclipse.osgi;3.21.0}}!/META-INF/MANIFEST.MF,bnd.overrides -nouses: true -nodefaultversion: true instrument.disabled: true -includeresource: \ - @${repo;org.eclipse.platform:org.eclipse.osgi;3.18.600}!/!module-info.class, \ + @${repo;org.eclipse.platform:org.eclipse.osgi;3.21.0}!/!module-info.class, \ org/eclipse=${bin}/org/eclipse -buildpath: \ - org.eclipse.platform:org.eclipse.osgi;version=3.18.600, \ - io.openliberty.com.ibm.oti.shared;version=latest + org.eclipse.platform:org.eclipse.osgi;version=3.21.0 diff --git a/dev/org.eclipse.osgi/bnd.overrides b/dev/org.eclipse.osgi/bnd.overrides index 591a6bd26c7..c63ed98b695 100644 --- a/dev/org.eclipse.osgi/bnd.overrides +++ b/dev/org.eclipse.osgi/bnd.overrides @@ -1,6 +1,6 @@ -include= ~../cnf/resources/bnd/rejar.props -bVersion=3.18.600 -bFullVersion=3.18.600 +bVersion=3.21.0 +bFullVersion=3.21.0 Bundle-SymbolicName: org.eclipse.osgi; singleton:=true diff --git a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/cds/CDSBundleFile.java b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/cds/CDSBundleFile.java deleted file mode 100644 index 312f85b9bef..00000000000 --- a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/cds/CDSBundleFile.java +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2018 IBM Corp. 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/ - * or the Apache License, Version 2.0 which accompanies this distribution and - * is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * This Source Code may also be made available under the following - * Secondary Licenses when the conditions for such availability set - * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU - * General Public License, version 2 with the GNU Classpath - * Exception [1] and GNU General Public License, version 2 with the - * OpenJDK Assembly Exception [2]. - * - * [1] https://www.gnu.org/software/classpath/license.html - * [2] http://openjdk.java.net/legal/assembly-exception.html - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception - *******************************************************************************/ - -package org.eclipse.osgi.internal.cds; - -import static org.eclipse.osgi.internal.cds.CDSHookConfigurator.print; - -import java.net.MalformedURLException; -import java.net.URL; - -import org.eclipse.osgi.internal.debug.Debug; -import org.eclipse.osgi.storage.bundlefile.BundleEntry; -import org.eclipse.osgi.storage.bundlefile.BundleFile; -import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper; - -import com.ibm.oti.shared.SharedClassURLHelper; - -/** - * Wraps an actual BundleFile object for purposes of loading classes from the - * shared classes cache. - */ -public class CDSBundleFile extends BundleFileWrapper { - private final static String classFileExt = ".class"; //$NON-NLS-1$ - private final URL url; // the URL to the content of the real bundle file - private SharedClassURLHelper urlHelper; // the url helper set by the classloader - private boolean primed = false; - private final Debug debug; - - /** - * The constructor - * - * @param wrapped the real bundle file - */ - public CDSBundleFile(BundleFile wrapped, Debug debug) { - super(wrapped); - this.debug = debug; - // get the url to the content of the real bundle file - URL content = null; - try { - content = new URL("file", "", wrapped.getBaseFile().getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (MalformedURLException e) { - // do nothing - } - this.url = content; - } - - public CDSBundleFile(BundleFile bundleFile, Debug debug, SharedClassURLHelper urlHelper) { - this(bundleFile, debug); - this.urlHelper = urlHelper; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.osgi.storage.bundlefile.BundleFile#getEntry(java.lang.String) - * - * If path is not for a class then just use the wrapped bundle file to answer - * the call. If the path is for a class, it returns a CDSBundleEntry object. If - * the path is for a class, it will look for the magic cookie in the shared - * classes cache. If found, the bytes representing the magic cookie are stored - * in CDSBundleEntry object. - */ - @Override - public BundleEntry getEntry(String path) { - if (!primed || !path.endsWith(classFileExt)) { - return super.getEntry(path); - } - byte[] classbytes = getClassBytes(path.substring(0, path.length() - classFileExt.length())); - if (classbytes == null) { - BundleEntry fromSuper = super.getEntry(path); - if (fromSuper != null) { - print(debug, () -> "Defining class from original bytes: " + url + ' ' + fromSuper.getName()); //$NON-NLS-1$ - } - return fromSuper; - } - - BundleEntry be = new CDSBundleEntry(path, classbytes, this); - return be; - } - - BundleEntry getWrappedEntry(String path) { - return super.getEntry(path); - } - - /** - * Returns the file url to the content of the actual bundle file - * - * @return the file url to the content of the actual bundle file - */ - URL getURL() { - return url; - } - - /** - * Returns the url helper for this bundle file. This is set by the class loading - * hook - * - * @return the url helper for this bundle file - */ - SharedClassURLHelper getURLHelper() { - return urlHelper; - } - - /** - * Sets the url helper for this bundle file. This is called by the class loading - * hook. - * - * @param urlHelper the url helper - */ - void setURLHelper(SharedClassURLHelper urlHelper) { - this.urlHelper = urlHelper; - this.primed = false; // always unprime when a new urlHelper is set - } - - /** - * Sets the primed flag for the bundle file. This is called by the class loading - * hook after the first class has been loaded from disk for this bundle file. - * - * @param primed the primed flag - */ - void setPrimed(boolean primed) { - this.primed = primed; - } - - /** - * Searches in the shared classes cache for the specified class name. - * - * @param name the name of the class - * @return the magic cookie to the shared class or null if the class is not in - * the cache. - */ - private byte[] getClassBytes(String name) { - if (urlHelper == null || url == null) - return null; - byte[] results = urlHelper.findSharedClass(null, url, name); - print(debug, () -> results != null ? "Found shared class bytes for: " + name + ' ' + url //$NON-NLS-1$ - : "No shared class bytes found for: " + name + ' ' + url); //$NON-NLS-1$ - return results; - } - - /** - * Returns the primed flag for this bundle file. - * - * @return the primed flag - */ - public boolean getPrimed() { - return this.primed; - } -} diff --git a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/cds/CDSHookConfigurator.java b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/cds/CDSHookConfigurator.java deleted file mode 100644 index dc0f307ba92..00000000000 --- a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/cds/CDSHookConfigurator.java +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2018 IBM Corp. 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/ - * or the Apache License, Version 2.0 which accompanies this distribution and - * is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * This Source Code may also be made available under the following - * Secondary Licenses when the conditions for such availability set - * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU - * General Public License, version 2 with the GNU Classpath - * Exception [1] and GNU General Public License, version 2 with the - * OpenJDK Assembly Exception [2]. - * - * [1] https://www.gnu.org/software/classpath/license.html - * [2] http://openjdk.java.net/legal/assembly-exception.html - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception - *******************************************************************************/ - -package org.eclipse.osgi.internal.cds; - -import java.util.function.Supplier; - -import org.eclipse.osgi.framework.log.FrameworkLogEntry; -import org.eclipse.osgi.internal.debug.Debug; -import org.eclipse.osgi.internal.framework.EquinoxContainer; -import org.eclipse.osgi.internal.hookregistry.HookConfigurator; -import org.eclipse.osgi.internal.hookregistry.HookRegistry; -import org.eclipse.osgi.internal.log.EquinoxLogServices; - -public class CDSHookConfigurator implements HookConfigurator { - - private static final String REPORT_ERRORS = "j9.cds.reporterrors"; //$NON-NLS-1$ - private static final String DISABLE_CDS = "j9.cds.disable"; //$NON-NLS-1$ - private static final String OLD_CDS_CONFIGURATOR = "com.ibm.cds.CDSHookConfigurator"; //$NON-NLS-1$ - private static final String J9_SHARED_CLASS_HELPER_CLASS = "com.ibm.oti.shared.SharedClassHelperFactory"; //$NON-NLS-1$ - - static void print(Debug debug, Supplier msg) { - if (debug.DEBUG_LOADER_CDS) { - Debug.println(msg.get()); - } - } - @Override - public void addHooks(HookRegistry hookRegistry) { - Debug debug = hookRegistry.getConfiguration().getDebug(); - boolean disableCDS = Boolean.valueOf(hookRegistry.getConfiguration().getProperty(DISABLE_CDS)); - if (disableCDS) { - print(debug, () -> "Class sharing is disabled by: " + DISABLE_CDS); //$NON-NLS-1$ - return; - } - // check for the external com.ibm.cds system.bundle fragment - try { - Class.forName(OLD_CDS_CONFIGURATOR); - // the old com.ibm.cds fragment is installed; disable build-in one - print(debug, () -> "Detected old com.ibm.cds fragment."); //$NON-NLS-1$ - return; - } catch (ClassNotFoundException e) { - // expected - } - try { - Class.forName(J9_SHARED_CLASS_HELPER_CLASS); - print(debug, () -> "Found Eclipse OpenJ9 support class: " + J9_SHARED_CLASS_HELPER_CLASS); //$NON-NLS-1$ - } catch (ClassNotFoundException e) { - print(debug, () -> "Not running on Eclipse OpenJ9."); //$NON-NLS-1$ - boolean reportErrors = Boolean.valueOf(hookRegistry.getConfiguration().getProperty(REPORT_ERRORS)); - // not running on J9 - if (reportErrors) { - EquinoxContainer container = hookRegistry.getContainer(); - EquinoxLogServices logServices = container.getLogServices(); - logServices.log(EquinoxContainer.NAME, FrameworkLogEntry.WARNING, - "The J9 Class Sharing Adaptor will not work in this configuration. You are not running on a J9 Java VM.", //$NON-NLS-1$ - null); - } - return; - } - new CDSHookImpls(debug).registerHooks(hookRegistry); - } - -} diff --git a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java deleted file mode 100644 index d120023ee58..00000000000 --- a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java +++ /dev/null @@ -1,258 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2018 IBM Corp. 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/ - * or the Apache License, Version 2.0 which accompanies this distribution and - * is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * This Source Code may also be made available under the following - * Secondary Licenses when the conditions for such availability set - * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU - * General Public License, version 2 with the GNU Classpath - * Exception [1] and GNU General Public License, version 2 with the - * OpenJDK Assembly Exception [2]. - * - * [1] https://www.gnu.org/software/classpath/license.html - * [2] http://openjdk.java.net/legal/assembly-exception.html - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception - *******************************************************************************/ - -package org.eclipse.osgi.internal.cds; - -import static org.eclipse.osgi.internal.cds.CDSHookConfigurator.print; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; - -import org.eclipse.osgi.internal.debug.Debug; -import org.eclipse.osgi.internal.hookregistry.BundleFileWrapperFactoryHook; -import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook; -import org.eclipse.osgi.internal.hookregistry.HookRegistry; -import org.eclipse.osgi.internal.loader.ModuleClassLoader; -import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry; -import org.eclipse.osgi.internal.loader.classpath.ClasspathManager; -import org.eclipse.osgi.internal.loader.classpath.FragmentClasspath; -import org.eclipse.osgi.storage.BundleInfo.Generation; -import org.eclipse.osgi.storage.ContentProvider.Type; -import org.eclipse.osgi.storage.bundlefile.BundleEntry; -import org.eclipse.osgi.storage.bundlefile.BundleFile; -import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper; -import org.eclipse.osgi.storage.bundlefile.BundleFileWrapperChain; - -import com.ibm.oti.shared.HelperAlreadyDefinedException; -import com.ibm.oti.shared.Shared; -import com.ibm.oti.shared.SharedClassHelperFactory; -import com.ibm.oti.shared.SharedClassURLHelper; - -public class CDSHookImpls extends ClassLoaderHook implements BundleFileWrapperFactoryHook { - private static SharedClassHelperFactory factory = Shared.getSharedClassHelperFactory(); - - private final Debug debug; - - public CDSHookImpls(Debug debug) { - this.debug = debug; - } - - // With Equinox bug 226038 (v3.4), the framework will now pass an instance - // of BundleFileWrapperChain rather than the wrapped BundleFile. This is - // so that multiple wrapping hooks can each wrap the BundleFile and all - // wrappers are accessible. - // - // The Wrapper chain will look like below: - // WrapperChain -> Wrapper -> WrapperChain -> CDSBundleFile -> WrapperChain - // -> BundleFile - // - private static CDSBundleFile getCDSBundleFile(BundleFile bundleFile) { - if (bundleFile instanceof BundleFileWrapperChain) { - return ((BundleFileWrapperChain) bundleFile).getWrappedType(CDSBundleFile.class); - } - return null; - } - - @Override - public void recordClassDefine(String name, Class clazz, byte[] classbytes, ClasspathEntry classpathEntry, - BundleEntry entry, ClasspathManager manager) { // only attempt to record the class define if: - // 1) the class was found (clazz != null) - // 2) the class has the magic class number CAFEBABE indicating a real class - // 3) the bundle file for the classpath entry is of type CDSBundleFile - // 4) class bytes is same as passed to weaving hook i.e. weaving hook did not - // modify the class bytes - if (null == clazz) { - print(debug, () -> "No class to store: " + name); //$NON-NLS-1$ - return; - } - if ((false == hasMagicClassNumber(classbytes))) { - print(debug, () -> "Class was already stored: " + name); //$NON-NLS-1$ - return; - } - CDSBundleFile cdsFile = getCDSBundleFile(classpathEntry.getBundleFile()); - if (null == cdsFile) { - print(debug, () -> "No CDSBundleFile for class: " + name); //$NON-NLS-1$ - return; - } - try { - // check if weaving hook modified the class bytes - byte originalClassBytes[] = entry.getBytes(); - if (originalClassBytes != classbytes) { - // weaving hook has potentially modified the class bytes - boolean modified = false; - if (originalClassBytes.length == classbytes.length) { - // do a byte-by-byte comparison - modified = !Arrays.equals(classbytes, originalClassBytes); - } else { - modified = true; - } - if (modified) { - // Class bytes have been modified by weaving hooks. - // Such classes need to be stored as Orphans, so skip the call to - // storeSharedClass() - print(debug, () -> "class bytes have changed, cannot store."); //$NON-NLS-1$ - return; - } - } - } catch (IOException e) { - // this should never happen, but in case it does, its safe to return - return; - } - - if (null == cdsFile.getURL()) { - // something went wrong trying to determine the url to the real bundle file - return; - } - - // look for the urlHelper; if it does not exist then we are not sharing for this - // class loader - SharedClassURLHelper urlHelper = cdsFile.getURLHelper(); - if (urlHelper == null) { - // this should never happen but just in case get the helper from the base host - // bundle file. - CDSBundleFile hostBundleFile = getCDSBundleFile(manager.getGeneration().getBundleFile()); - if (null != hostBundleFile) { - // try getting the helper from the host base cdsFile - urlHelper = hostBundleFile.getURLHelper(); - } - - if (null != urlHelper) { - cdsFile.setURLHelper(urlHelper); - } - } - if (null != urlHelper) { - // store the class in the cache - boolean successStore = urlHelper.storeSharedClass(null, cdsFile.getURL(), clazz); - print(debug, () -> successStore ? "Stored class: " + name : "Failed to store class: " + name); //$NON-NLS-1$//$NON-NLS-2$ - cdsFile.setPrimed(true); - } else { - print(debug, () -> "No helper found to store class: " + name); //$NON-NLS-1$ - } - } - - private boolean hasMagicClassNumber(byte[] classbytes) { - if (classbytes == null || classbytes.length < 4) - return false; - // TODO maybe there is a better way to do this? I'm not sure why I had to AND - // each byte with the value I was checking ... - return (classbytes[0] & 0xCA) == 0xCA && (classbytes[1] & 0xFE) == 0xFE && (classbytes[2] & 0xBA) == 0xBA - && (classbytes[3] & 0xBE) == 0xBE; - } - - @Override - public void classLoaderCreated(ModuleClassLoader classLoader) { - // try to get the url helper for this class loader - if (factory == null) { - return; - } - try { - SharedClassURLHelper urlHelper = factory.getURLHelper(classLoader); - boolean minimizeUpdateChecks = urlHelper.setMinimizeUpdateChecks(); - // set the url helper for the host base CDSBundleFile - CDSBundleFile hostFile = getCDSBundleFile( - classLoader.getClasspathManager().getGeneration().getBundleFile()); - if (hostFile != null) { - hostFile.setURLHelper(urlHelper); - if (minimizeUpdateChecks) { - // no need to prime if we were able to setMinimizeUpdateChecks - hostFile.setPrimed(true); - } - } - // No need to prime if we were able to setMinimizeUpdateChecks. - // Mark all the BundleFiles on the classpath as primed. - ClasspathManager cpManager = classLoader.getClasspathManager(); - for (ClasspathEntry entry : cpManager.getHostClasspathEntries()) { - CDSBundleFile cdsBundleFile = getCDSBundleFile(entry.getBundleFile()); - if (cdsBundleFile != null) { - cdsBundleFile.setURLHelper(urlHelper); - if (minimizeUpdateChecks) { - cdsBundleFile.setPrimed(true); - } - } - } - for (FragmentClasspath fragCP : cpManager.getFragmentClasspaths()) { - for (ClasspathEntry entry : fragCP.getEntries()) { - CDSBundleFile cdsBundleFile = getCDSBundleFile(entry.getBundleFile()); - if (cdsBundleFile != null) { - cdsBundleFile.setURLHelper(urlHelper); - if (minimizeUpdateChecks) { - cdsBundleFile.setPrimed(true); - } - } - } - } - } catch (HelperAlreadyDefinedException e) { - // We should never get here. - // If we do, we simply won't share for this ClassLoader - } - } - - @Override - public boolean addClassPathEntry(ArrayList cpEntries, String cp, ClasspathManager hostmanager, - Generation sourceGeneration) { - CDSBundleFile hostFile = getCDSBundleFile(hostmanager.getGeneration().getBundleFile()); - CDSBundleFile sourceFile = getCDSBundleFile(sourceGeneration.getBundleFile()); - if ((hostFile != sourceFile) && (null != hostFile) && (null != sourceFile)) { - // Set the helper that got set on the host base bundle file in - // classLoaderCreated. - // This is to handle the case where fragments are dynamically attached - SharedClassURLHelper urlHelper = hostFile.getURLHelper(); - sourceFile.setURLHelper(urlHelper); - sourceFile.setPrimed(hostFile.getPrimed()); - } - - return false; - } - - //////////////// BundleFileWrapperFactoryHook ////////////// - @Override - public BundleFileWrapper wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base) { - if (generation.getContentType() == Type.CONNECT) { - return null; - } - // wrap the real bundle file for purposes of loading shared classes. - CDSBundleFile newBundleFile; - if (!base && generation.getBundleInfo().getBundleId() != 0) { - // initialize the urlHelper from the base one. - SharedClassURLHelper urlHelper = null; - BundleFile baseFile = generation.getBundleFile(); - if ((baseFile = getCDSBundleFile(baseFile)) != null) { - urlHelper = ((CDSBundleFile) baseFile).getURLHelper(); - } - newBundleFile = new CDSBundleFile(bundleFile, debug, urlHelper); - } else { - newBundleFile = new CDSBundleFile(bundleFile, debug); - } - - return newBundleFile; - } - - void registerHooks(HookRegistry hookRegistry) { - // only register if sharing is enabled - if (!Shared.isSharingEnabled()) { - return; - } - hookRegistry.addClassLoaderHook(this); - hookRegistry.addBundleFileWrapperFactoryHook(this); - } -} diff --git a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/container/KeyBasedLockStore.java b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/container/KeyBasedLockStore.java new file mode 100644 index 00000000000..e4b5e9d3828 --- /dev/null +++ b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/container/KeyBasedLockStore.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2022, 2024 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.osgi.internal.container; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; + +public final class KeyBasedLockStore { + + final ReferenceQueue refQueue = new ReferenceQueue<>(); + private final ConcurrentHashMap lockMap = new ConcurrentHashMap<>(); + private final Function lockCreator; + + public KeyBasedLockStore(Function lockCreator) { + this.lockCreator = lockCreator; + } + + private final class LockWeakRef extends WeakReference { + final Key key; + + public LockWeakRef(Lock referent, Key keyValue) { + super(referent, refQueue); + key = keyValue; + } + } + + public final Lock getLock(Key key) { + poll(); + LockWeakRef lockRef = lockMap.get(key); + Lock lock = lockRef != null ? lockRef.get() : null; + if (lock != null) { + return lock; + } + + lock = lockCreator.apply(key); + + while (true) { + LockWeakRef retVal = lockMap.putIfAbsent(key, new LockWeakRef(lock, key)); + if (retVal == null) { + return lock; + } + + Lock retLock = retVal.get(); + if (retLock != null) { + return retLock; + } + lockMap.remove(key, retVal); + } + } + + @SuppressWarnings("unchecked") + private final void poll() { + LockWeakRef lockRef; + while ((lockRef = (LockWeakRef) refQueue.poll()) != null) { + lockMap.remove(lockRef.key, lockRef); + } + } +} diff --git a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/debug/Debug.java b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/debug/Debug.java deleted file mode 100644 index f63deb75737..00000000000 --- a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/debug/Debug.java +++ /dev/null @@ -1,376 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2003, 2018 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.osgi.internal.debug; - -import java.io.PrintStream; - -import org.eclipse.osgi.internal.framework.EquinoxContainer; -import org.eclipse.osgi.internal.util.SupplementDebug; -import org.eclipse.osgi.service.debug.DebugOptions; -import org.eclipse.osgi.service.debug.DebugOptionsListener; - -/** - * This class has debug constants which can be used by the Framework - * implementation and Adaptor implementations - * - * @since 3.1 - */ -public class Debug implements DebugOptionsListener { - /** - * Base debug option key (org.eclispe.osgi). - */ - public static final String ECLIPSE_OSGI = EquinoxContainer.NAME; - /** - * General Debug option key. - */ - public static final String OPTION_DEBUG_GENERAL = ECLIPSE_OSGI + "/debug"; //$NON-NLS-1$ - /** - * Bundle time Debug option key. - */ - public static final String OPTION_DEBUG_BUNDLE_TIME = ECLIPSE_OSGI + "/debug/bundleTime"; //$NON-NLS-1$ - - /** - * Bundle start time Debug option key. - */ - public static final String OPTION_DEBUG_BUNDLE_START_TIME = ECLIPSE_OSGI + "/debug/bundleStartTime"; //$NON-NLS-1$ - /** - * Loader Debug option key. - */ - public static final String OPTION_DEBUG_LOADER = ECLIPSE_OSGI + "/debug/loader"; //$NON-NLS-1$ - - /** - * Loader Debug option key. - */ - public static final String OPTION_DEBUG_LOADER_CDS = ECLIPSE_OSGI + "/debug/loader/cds"; //$NON-NLS-1$ - - /** - * Storage Debug option key. - */ - public static final String OPTION_DEBUG_STORAGE = ECLIPSE_OSGI + "/debug/storage"; //$NON-NLS-1$ - /** - * Events Debug option key. - */ - public static final String OPTION_DEBUG_EVENTS = ECLIPSE_OSGI + "/debug/events"; //$NON-NLS-1$ - /** - * Services Debug option key. - */ - public static final String OPTION_DEBUG_SERVICES = ECLIPSE_OSGI + "/debug/services"; //$NON-NLS-1$ - /** - * Services Debug option key. - */ - public static final String OPTION_DEBUG_HOOKS = ECLIPSE_OSGI + "/debug/hooks"; //$NON-NLS-1$ - /** - * Manifest Debug option key. - */ - public static final String OPTION_DEBUG_MANIFEST = ECLIPSE_OSGI + "/debug/manifest"; //$NON-NLS-1$ - /** - * Filter Debug option key. - */ - public static final String OPTION_DEBUG_FILTER = ECLIPSE_OSGI + "/debug/filter"; //$NON-NLS-1$ - /** - * Security Debug option key. - */ - public static final String OPTION_DEBUG_SECURITY = ECLIPSE_OSGI + "/debug/security"; //$NON-NLS-1$ - /** - * Start level Debug option key. - */ - public static final String OPTION_DEBUG_STARTLEVEL = ECLIPSE_OSGI + "/debug/startlevel"; //$NON-NLS-1$ - /** - * PackageAdmin Debug option key. - */ - public static final String OPTION_DEBUG_PACKAGEADMIN = ECLIPSE_OSGI + "/debug/packageadmin"; //$NON-NLS-1$ - /** - * PackageAdmin timing Debug option key. - */ - public static final String OPTION_DEBUG_PACKAGEADMIN_TIMING = ECLIPSE_OSGI + "/debug/packageadmin/timing"; //$NON-NLS-1$ - /** - * Monitor activation Debug option key. - */ - public static final String OPTION_MONITOR_ACTIVATION = ECLIPSE_OSGI + "/monitor/activation"; //$NON-NLS-1$ - - /** - * Monitor lazy activation Debug option key - */ - public static final String OPTION_MONITOR_LAZY = ECLIPSE_OSGI + "/monitor/lazy"; //$NON-NLS-1$ - /** - * Message bundles Debug option key. - */ - public static final String OPTION_DEBUG_MESSAGE_BUNDLES = ECLIPSE_OSGI + "/debug/messageBundles"; //$NON-NLS-1$ - - public static final String OPTION_DEBUG_LOCATION = ECLIPSE_OSGI + "/debug/location"; //$NON-NLS-1$ - - public static final String OPTION_CACHED_MANIFEST = ECLIPSE_OSGI + "/debug/cachedmanifest"; //$NON-NLS-1$ - - public static final String OPTION_DEBUG_SYSTEM_BUNDLE = ECLIPSE_OSGI + "/debug/systemBundle"; //$NON-NLS-1$ - - public static final String OPTION_DEBUG_BUNDLE_FILE = ECLIPSE_OSGI + "/debug/bundleFile"; //$NON-NLS-1$ - - public static final String OPTION_DEBUG_BUNDLE_FILE_OPEN = ECLIPSE_OSGI + "/debug/bundleFile/open"; //$NON-NLS-1$ - - public static final String OPTION_DEBUG_BUNDLE_FILE_CLOSE = ECLIPSE_OSGI + "/debug/bundleFile/close"; //$NON-NLS-1$ - - /** - * General debug flag. - */ - public boolean DEBUG_GENERAL = false; // "debug" - /** - * Bundle time debug flag. - */ - public boolean DEBUG_BUNDLE_TIME = false; // "debug.bundleTime" - /** - * Loader debug flag. - */ - public boolean DEBUG_LOADER = false; // "debug.loader" - /** - * Loader debug flag. - */ - public boolean DEBUG_LOADER_CDS = false; // "debug.loader" - /** - * Storage debug flag. - */ - public boolean DEBUG_STORAGE = false; // "debug.storage" - /** - * Events debug flag. - */ - public boolean DEBUG_EVENTS = false; // "debug.events" - /** - * Services debug flag. - */ - public boolean DEBUG_SERVICES = false; // "debug.services" - - /** - * Hooks debug flag. - */ - public boolean DEBUG_HOOKS = false; // "debug.hooks" - /** - * Manifest debug flag. - */ - public boolean DEBUG_MANIFEST = false; // "debug.manifest" - /** - * Filter debug flag. - */ - public boolean DEBUG_FILTER = false; // "debug.filter" - /** - * Security debug flag. - */ - public boolean DEBUG_SECURITY = false; // "debug.security" - /** - * Start level debug flag. - */ - public boolean DEBUG_STARTLEVEL = false; // "debug.startlevel" - /** - * PackageAdmin debug flag. - */ - public boolean DEBUG_PACKAGEADMIN = false; // "debug.packageadmin" - /** - * PackageAdmin timing debug flag. - */ - // TODO remove this or use it somewhere - public boolean DEBUG_PACKAGEADMIN_TIMING = false; // "debug.packageadmin/timing" - /** - * Message debug flag. - */ - public boolean DEBUG_MESSAGE_BUNDLES = false; // "/debug/messageBundles" - /** - * Monitor activation debug flag. - */ - public boolean MONITOR_ACTIVATION = false; // "monitor/activation" - - public boolean DEBUG_LOCATION = false; // debug/location - - public boolean DEBUG_CACHED_MANIFEST = false; - - public boolean DEBUG_SYSTEM_BUNDLE = false; // debug/systemBundle - - public boolean DEBUG_BUNDLE_FILE = false; // debug/bundleFile - - public boolean DEBUG_BUNDLE_FILE_OPEN = false; // debug/bundleFile/open - - public boolean DEBUG_BUNDLE_FILE_CLOSE = false; // debug/bundleFile/close - - public Debug(DebugOptions dbgOptions) { - optionsChanged(dbgOptions); - } - - @Override - public void optionsChanged(DebugOptions dbgOptions) { - DEBUG_GENERAL = dbgOptions.getBooleanOption(OPTION_DEBUG_GENERAL, false); - DEBUG_BUNDLE_TIME = dbgOptions.getBooleanOption(OPTION_DEBUG_BUNDLE_TIME, false) - || dbgOptions.getBooleanOption("org.eclipse.core.runtime/timing/startup", false); //$NON-NLS-1$ - DEBUG_LOADER = dbgOptions.getBooleanOption(OPTION_DEBUG_LOADER, false); - DEBUG_LOADER_CDS = dbgOptions.getBooleanOption(OPTION_DEBUG_LOADER_CDS, false); - DEBUG_STORAGE = dbgOptions.getBooleanOption(OPTION_DEBUG_STORAGE, false); - DEBUG_EVENTS = dbgOptions.getBooleanOption(OPTION_DEBUG_EVENTS, false); - DEBUG_SERVICES = dbgOptions.getBooleanOption(OPTION_DEBUG_SERVICES, false); - DEBUG_HOOKS = dbgOptions.getBooleanOption(OPTION_DEBUG_HOOKS, false); - DEBUG_MANIFEST = dbgOptions.getBooleanOption(OPTION_DEBUG_MANIFEST, false); - SupplementDebug.STATIC_DEBUG_MANIFEST = DEBUG_MANIFEST; - DEBUG_FILTER = dbgOptions.getBooleanOption(OPTION_DEBUG_FILTER, false); - DEBUG_SECURITY = dbgOptions.getBooleanOption(OPTION_DEBUG_SECURITY, false); - DEBUG_STARTLEVEL = dbgOptions.getBooleanOption(OPTION_DEBUG_STARTLEVEL, false); - DEBUG_PACKAGEADMIN = dbgOptions.getBooleanOption(OPTION_DEBUG_PACKAGEADMIN, false); - DEBUG_PACKAGEADMIN_TIMING = dbgOptions.getBooleanOption(OPTION_DEBUG_PACKAGEADMIN_TIMING, false) - || dbgOptions.getBooleanOption("org.eclipse.core.runtime/debug", false); //$NON-NLS-1$ - DEBUG_MESSAGE_BUNDLES = dbgOptions.getBooleanOption(OPTION_DEBUG_MESSAGE_BUNDLES, false); - SupplementDebug.STATIC_DEBUG_MESSAGE_BUNDLES = DEBUG_MESSAGE_BUNDLES; - MONITOR_ACTIVATION = dbgOptions.getBooleanOption(OPTION_MONITOR_ACTIVATION, false); - DEBUG_LOCATION = dbgOptions.getBooleanOption(OPTION_DEBUG_LOCATION, false); - DEBUG_CACHED_MANIFEST = dbgOptions.getBooleanOption(OPTION_CACHED_MANIFEST, false); - DEBUG_SYSTEM_BUNDLE = dbgOptions.getBooleanOption(OPTION_DEBUG_SYSTEM_BUNDLE, false); - DEBUG_BUNDLE_FILE = dbgOptions.getBooleanOption(OPTION_DEBUG_BUNDLE_FILE, false); - DEBUG_BUNDLE_FILE_OPEN = dbgOptions.getBooleanOption(OPTION_DEBUG_BUNDLE_FILE_OPEN, false); - DEBUG_BUNDLE_FILE_CLOSE = dbgOptions.getBooleanOption(OPTION_DEBUG_BUNDLE_FILE_CLOSE, false); - } - - /** - * The PrintStream to print debug messages to. - */ - public static PrintStream out = System.out; - - /** - * Prints x to the PrintStream - */ - public static void print(boolean x) { - out.print(x); - } - - /** - * Prints x to the PrintStream - */ - public static void print(char x) { - out.print(x); - } - - /** - * Prints x to the PrintStream - */ - public static void print(int x) { - out.print(x); - } - - /** - * Prints x to the PrintStream - */ - public static void print(long x) { - out.print(x); - } - - /** - * Prints x to the PrintStream - */ - public static void print(float x) { - out.print(x); - } - - /** - * Prints x to the PrintStream - */ - public static void print(double x) { - out.print(x); - } - - /** - * Prints x to the PrintStream - */ - public static void print(char x[]) { - out.print(x); - } - - /** - * Prints x to the PrintStream - */ - public static void print(String x) { - out.print(x); - } - - /** - * Prints x to the PrintStream - */ - public static void print(Object x) { - out.print(x); - } - - /** - * Prints x to the PrintStream - */ - public static void println(boolean x) { - out.println(x); - } - - /** - * Prints x to the PrintStream - */ - public static void println(char x) { - out.println(x); - } - - /** - * Prints x to the PrintStream - */ - public static void println(int x) { - out.println(x); - } - - /** - * Prints x to the PrintStream - */ - public static void println(long x) { - out.println(x); - } - - /** - * Prints x to the PrintStream - */ - public static void println(float x) { - out.println(x); - } - - /** - * Prints x to the PrintStream - */ - public static void println(double x) { - out.println(x); - } - - /** - * Prints x to the PrintStream - */ - public static void println(char x[]) { - out.println(x); - } - - /** - * Prints x to the PrintStream - */ - public static void println(String x) { - out.println(x); - } - - /** - * Prints x to the PrintStream - */ - public static void println(Object x) { - out.println(x); - } - - /** - * Prints t to the PrintStream - */ - public static void printStackTrace(Throwable t) { - if (t == null) - return; - t.printStackTrace(out); - } -} diff --git a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/loader/EquinoxClassLoader.java b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/loader/EquinoxClassLoader.java new file mode 100644 index 00000000000..b7defd1509a --- /dev/null +++ b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/loader/EquinoxClassLoader.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2005, 2016 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.osgi.internal.loader; + +import org.eclipse.osgi.internal.debug.Debug; +import org.eclipse.osgi.internal.framework.EquinoxConfiguration; +import org.eclipse.osgi.internal.loader.classpath.ClasspathManager; +import org.eclipse.osgi.storage.BundleInfo.Generation; + +public class EquinoxClassLoader extends ModuleClassLoader { + static { + try { + ClassLoader.registerAsParallelCapable(); + } catch (Throwable t) { + // ignore all exceptions; substrate native image fails here + } + } + private final EquinoxConfiguration configuration; + private final Debug debug; + private final BundleLoader delegate; + private final Generation generation; + // TODO Note that PDE has internal dependency on this field type/name (bug + // 267238) + private final ClasspathManager manager; + + /** + * Constructs a new DefaultClassLoader. + * + * @param parent the parent classloader + * @param configuration the equinox configuration + * @param delegate the delegate for this classloader + * @param generation the generation for this class loader + */ + public EquinoxClassLoader(ClassLoader parent, EquinoxConfiguration configuration, BundleLoader delegate, + Generation generation) { + super(parent); + this.configuration = configuration; + this.debug = configuration.getDebug(); + this.delegate = delegate; + this.generation = generation; + this.manager = new ClasspathManager(generation, this); + } + + @Override + protected final Generation getGeneration() { + return this.generation; + } + + @Override + public final ClasspathManager getClasspathManager() { + return manager; + } + + @Override + public final BundleLoader getBundleLoader() { + return delegate; + } + + @Override + protected final Debug getDebug() { + return debug; + } + + @Override + protected final EquinoxConfiguration getConfiguration() { + return configuration; + } +} diff --git a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/loader/ModuleClassLoader.java b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/loader/ModuleClassLoader.java new file mode 100644 index 00000000000..0d6e7e7ba18 --- /dev/null +++ b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/loader/ModuleClassLoader.java @@ -0,0 +1,437 @@ +/******************************************************************************* + * Copyright (c) 2005, 2016 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.osgi.internal.loader; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.AllPermission; +import java.security.CodeSource; +import java.security.PermissionCollection; +import java.security.ProtectionDomain; +import java.security.cert.Certificate; +import java.util.Collection; +import java.util.Enumeration; +import java.util.List; +import java.util.function.Function; +import org.eclipse.osgi.container.ModuleRevision; +import org.eclipse.osgi.internal.container.KeyBasedLockStore; +import org.eclipse.osgi.internal.debug.Debug; +import org.eclipse.osgi.internal.framework.EquinoxConfiguration; +import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry; +import org.eclipse.osgi.internal.loader.classpath.ClasspathManager; +import org.eclipse.osgi.signedcontent.SignedContent; +import org.eclipse.osgi.signedcontent.SignerInfo; +import org.eclipse.osgi.storage.BundleInfo.Generation; +import org.eclipse.osgi.storage.bundlefile.BundleFile; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleReference; + +public abstract class ModuleClassLoader extends ClassLoader implements BundleReference { + public static class GenerationProtectionDomain extends ProtectionDomain implements BundleReference { + private final Generation generation; + + public GenerationProtectionDomain(CodeSource codesource, PermissionCollection permissions, + Generation generation) { + super(codesource, permissions); + this.generation = generation; + } + + @Override + public Bundle getBundle() { + return generation.getRevision().getBundle(); + } + } + + /** + * A PermissionCollection for AllPermissions; shared across all + * ProtectionDomains when security is disabled + */ + protected static final PermissionCollection ALLPERMISSIONS; + static { + try { + ClassLoader.registerAsParallelCapable(); + } catch (Throwable t) { + // ignore all exceptions; substrate native image fails here + } + } + + static { + AllPermission allPerm = new AllPermission(); + ALLPERMISSIONS = allPerm.newPermissionCollection(); + if (ALLPERMISSIONS != null) + ALLPERMISSIONS.add(allPerm); + } + + /** + * Holds the result of a defining a class. + */ + public static class DefineClassResult { + /** + * The class object that either got defined or was found as previously loaded. + */ + public final Class clazz; + /** + * Set to true if the class object got defined; set to false if the class did + * not get defined correctly or the class was found as a previously loaded + * class. + */ + public final boolean defined; + + public DefineClassResult(Class clazz, boolean defined) { + this.clazz = clazz; + this.defined = defined; + } + } + + private static final class ClassNameLock { + static final Function SUPPLIER = new Function() { + public ClassNameLock apply(String className) { + return new ClassNameLock(className); + } + }; + final String name; + + ClassNameLock(String name) { + this.name = name; + } + + @Override + public String toString() { + return "ClassNameLock: " + name; //$NON-NLS-1$ + } + } + + private final KeyBasedLockStore classNameLocks = new KeyBasedLockStore<>( + ClassNameLock.SUPPLIER); + private final Object pkgLock = new Object(); + + /** + * Constructs a new ModuleClassLoader. + * + * @param parent the parent classloader + */ + public ModuleClassLoader(ClassLoader parent) { + super(parent); + } + + /** + * Returns the generation of the host revision associated with this class loader + * + * @return the generation for this class loader + */ + protected abstract Generation getGeneration(); + + /** + * Returns the Debug object for the Framework instance + * + * @return the Debug object for the Framework instance + */ + protected abstract Debug getDebug(); + + /** + * Returns the classpath manager for this class loader + * + * @return the classpath manager for this class loader + */ + public abstract ClasspathManager getClasspathManager(); + + /** + * Returns the configuration for the Framework instance + * + * @return the configuration for the Framework instance + */ + protected abstract EquinoxConfiguration getConfiguration(); + + /** + * Returns the bundle loader for this class loader + * + * @return the bundle loader for this class loader + */ + public abstract BundleLoader getBundleLoader(); + + /** + * Returns true if this class loader implementation has been registered with the + * JVM as a parallel class loader. This requires Java 7 or later. This always + * returns true now that Java 8 is required. + * + * @return true if this class loader implementation has been registered with the + * JVM as a parallel class loader; otherwise false is returned. + */ + public boolean isRegisteredAsParallel() { + return true; + } + + /** + * Loads a class for the bundle. First delegate.findClass(name) is called. The + * delegate will query the system class loader, bundle imports, bundle local + * classes, bundle hosts and fragments. The delegate will call + * BundleClassLoader.findLocalClass(name) to find a class local to this bundle. + * + * @param name the name of the class to load. + * @param resolve indicates whether to resolve the loaded class or not. + * @return The Class object. + * @throws ClassNotFoundException if the class is not found. + */ + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + // Just ask the delegate. This could result in findLocalClass(name) being + // called. + Class clazz = getBundleLoader().findClass(name); + // resolve the class if asked to. + if (resolve) { + resolveClass(clazz); + } + return (clazz); + } + + // preparing for Java 9 + protected Class findClass(String moduleName, String name) { + try { + return findLocalClass(name); + } catch (ClassNotFoundException e) { + return null; + } + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + return findLocalClass(name); + } + + /** + * Gets a resource for the bundle. First delegate.findResource(name) is called. + * The delegate will query the system class loader, bundle imports, bundle local + * resources, bundle hosts and fragments. The delegate will call + * BundleClassLoader.findLocalResource(name) to find a resource local to this + * bundle. + * + * @param name The resource path to get. + * @return The URL of the resource or null if it does not exist. + */ + @Override + public URL getResource(String name) { + if (getDebug().DEBUG_LOADER) { + Debug.println("ModuleClassLoader[" + getBundleLoader() + "].getResource(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + URL url = getBundleLoader().findResource(name); + if (url != null) + return (url); + + if (getDebug().DEBUG_LOADER) { + Debug.println("ModuleClassLoader[" + getBundleLoader() + "].getResource(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + return (null); + } + + // preparing for Java 9 + protected URL findResource(String moduleName, String name) { + return findLocalResource(name); + } + + @Override + protected URL findResource(String name) { + return findLocalResource(name); + } + + /** + * Gets resources for the bundle. First delegate.findResources(name) is called. + * The delegate will query the system class loader, bundle imports, bundle local + * resources, bundle hosts and fragments. The delegate will call + * BundleClassLoader.findLocalResources(name) to find a resource local to this + * bundle. + * + * @param name The resource path to get. + * @return The Enumeration of the resource URLs. + */ + @Override + public Enumeration getResources(String name) throws IOException { + if (getDebug().DEBUG_LOADER) { + Debug.println("ModuleClassLoader[" + getBundleLoader() + "].getResources(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + Enumeration result = getBundleLoader().findResources(name); + if (getDebug().DEBUG_LOADER) { + if (result == null || !result.hasMoreElements()) { + Debug.println("ModuleClassLoader[" + getBundleLoader() + "].getResources(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + return result; + } + + @Override + protected Enumeration findResources(String name) throws IOException { + return findLocalResources(name); + } + + /** + * Finds a library for this bundle. Simply calls manager.findLibrary(libname) to + * find the library. + * + * @param libname The library to find. + * @return The absolution path to the library or null if not found + */ + @Override + protected String findLibrary(String libname) { + // let the manager find the library for us + return getClasspathManager().findLibrary(libname); + } + + public ClasspathEntry createClassPathEntry(BundleFile bundlefile, Generation entryGeneration) { + return new ClasspathEntry(bundlefile, createProtectionDomain(bundlefile, entryGeneration), entryGeneration); + } + + public DefineClassResult defineClass(String name, byte[] classbytes, ClasspathEntry classpathEntry) { + // Note that we must check findLoadedClass again here since no locks are held + // between + // calling findLoadedClass the first time and defineClass. + // This is to allow weavers to get called while holding no locks. + // See ClasspathManager.findLocalClass(String) + boolean defined = false; + Class result = null; + synchronized (getClassLoadingLock(name)) { + result = findLoadedClass(name); + if (result == null) { + result = defineClass(name, classbytes, 0, classbytes.length, classpathEntry.getDomain()); + defined = true; + } + } + return new DefineClassResult(result, defined); + } + + public Class publicFindLoaded(String classname) { + synchronized (getClassLoadingLock(classname)) { + return findLoadedClass(classname); + } + } + + public Package publicGetPackage(String pkgname) { + synchronized (pkgLock) { + return getPackage(pkgname); + } + } + + public Package publicDefinePackage(String name, String specTitle, String specVersion, String specVendor, + String implTitle, String implVersion, String implVendor, URL sealBase) { + synchronized (pkgLock) { + Package pkg = getPackage(name); + return pkg != null ? pkg + : definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, + sealBase); + } + } + + public URL findLocalResource(String resource) { + return getClasspathManager().findLocalResource(resource); + } + + public Enumeration findLocalResources(String resource) { + return getClasspathManager().findLocalResources(resource); + } + + public Class findLocalClass(String classname) throws ClassNotFoundException { + return getClasspathManager().findLocalClass(classname); + } + + /** + * Creates a ProtectionDomain which uses specified BundleFile and the + * permissions of the baseDomain + * + * @param bundlefile The source bundlefile the domain is for. + * @param domainGeneration the source generation for the domain + * @return a ProtectionDomain which uses specified BundleFile and the + * permissions of the baseDomain + */ + @SuppressWarnings("deprecation") + protected ProtectionDomain createProtectionDomain(BundleFile bundlefile, Generation domainGeneration) { + // create a protection domain which knows about the codesource for this + // classpath entry (bug 89904) + ProtectionDomain baseDomain = domainGeneration.getDomain(); + try { + // use the permissions supplied by the domain passed in from the framework + PermissionCollection permissions; + if (baseDomain != null) { + permissions = baseDomain.getPermissions(); + } else { + // no domain specified. Better use a collection that has all permissions + // this is done just incase someone sets the security manager later + permissions = ALLPERMISSIONS; + } + Certificate[] certs = null; + if (getConfiguration().CLASS_CERTIFICATE) { + Bundle b = getBundle(); + SignedContent signedContent = b == null ? null : b.adapt(SignedContent.class); + if (signedContent != null && signedContent.isSigned()) { + SignerInfo[] signers = signedContent.getSignerInfos(); + if (signers.length > 0) { + certs = signers[0].getCertificateChain(); + } + } + } + File file = bundlefile.getBaseFile(); + // Bug 477787: file will be null when the osgi.framework configuration property + // contains an invalid value. + return new GenerationProtectionDomain(file == null ? null : new CodeSource(file.toURL(), certs), + permissions, getGeneration()); + // return new ProtectionDomain(new CodeSource(bundlefile.getBaseFile().toURL(), + // certs), permissions); + } catch (MalformedURLException e) { + // Failed to create our own domain; just return the baseDomain + return baseDomain; + } + } + + @Override + public Bundle getBundle() { + return getGeneration().getRevision().getBundle(); + } + + public List findEntries(String path, String filePattern, int options) { + return getClasspathManager().findEntries(path, filePattern, options); + } + + public Collection listResources(String path, String filePattern, int options) { + return getBundleLoader().listResources(path, filePattern, options); + } + + public Collection listLocalResources(String path, String filePattern, int options) { + return getClasspathManager().listLocalResources(path, filePattern, options); + } + + @Override + public String toString() { + Bundle b = getBundle(); + StringBuilder result = new StringBuilder(super.toString()); + if (b == null) + return result.toString(); + return result.append('[').append(b.getSymbolicName()).append(':').append(b.getVersion()).append("(id=") //$NON-NLS-1$ + .append(b.getBundleId()).append(")]").toString(); //$NON-NLS-1$ + } + + public void loadFragments(Collection fragments) { + getClasspathManager().loadFragments(fragments); + } + + @Override + public Object getClassLoadingLock(String classname) { + return classNameLocks.getLock(classname); + } + + public void close() { + getClasspathManager().close(); + } +} diff --git a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/url/URLStreamHandlerProxy.java b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/url/URLStreamHandlerProxy.java index b40c8448e66..f62fac292c4 100644 --- a/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/url/URLStreamHandlerProxy.java +++ b/dev/org.eclipse.osgi/src/org/eclipse/osgi/internal/url/URLStreamHandlerProxy.java @@ -70,7 +70,8 @@ public URLStreamHandlerProxy(String protocol, BundleContext context) { new ServiceTrackerCustomizer() { @Override - public LazyURLStreamHandlerService addingService(ServiceReference reference) { + public LazyURLStreamHandlerService addingService( + ServiceReference reference) { return new LazyURLStreamHandlerService(context, reference); } diff --git a/dev/org.eclipse.osgi/src/org/eclipse/osgi/storage/Storage.java b/dev/org.eclipse.osgi/src/org/eclipse/osgi/storage/Storage.java deleted file mode 100644 index c8e1d0654aa..00000000000 --- a/dev/org.eclipse.osgi/src/org/eclipse/osgi/storage/Storage.java +++ /dev/null @@ -1,2243 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012, 2021 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 - * Christoph Laeubrich - Bug 527175 - Storage#getSystemContent() should first make the file absolute - * Hannes Wellmann - Bug 577432 - Speed up and improve file processing in Storage - *******************************************************************************/ -package org.eclipse.osgi.storage; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Properties; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Stream; -import org.eclipse.core.runtime.adaptor.EclipseStarter; -import org.eclipse.osgi.container.Module; -import org.eclipse.osgi.container.ModuleCapability; -import org.eclipse.osgi.container.ModuleContainer; -import org.eclipse.osgi.container.ModuleContainerAdaptor; -import org.eclipse.osgi.container.ModuleDatabase; -import org.eclipse.osgi.container.ModuleRevision; -import org.eclipse.osgi.container.ModuleRevisionBuilder; -import org.eclipse.osgi.container.ModuleWire; -import org.eclipse.osgi.container.ModuleWiring; -import org.eclipse.osgi.container.builders.OSGiManifestBuilderFactory; -import org.eclipse.osgi.container.namespaces.EclipsePlatformNamespace; -import org.eclipse.osgi.framework.internal.reliablefile.ReliableFile; -import org.eclipse.osgi.framework.log.FrameworkLogEntry; -import org.eclipse.osgi.framework.util.FilePath; -import org.eclipse.osgi.framework.util.ObjectPool; -import org.eclipse.osgi.framework.util.SecureAction; -import org.eclipse.osgi.internal.container.InternalUtils; -import org.eclipse.osgi.internal.debug.Debug; -import org.eclipse.osgi.internal.framework.EquinoxConfiguration; -import org.eclipse.osgi.internal.framework.EquinoxContainer; -import org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor; -import org.eclipse.osgi.internal.framework.FilterImpl; -import org.eclipse.osgi.internal.hookregistry.BundleFileWrapperFactoryHook; -import org.eclipse.osgi.internal.hookregistry.StorageHookFactory; -import org.eclipse.osgi.internal.hookregistry.StorageHookFactory.StorageHook; -import org.eclipse.osgi.internal.location.EquinoxLocations; -import org.eclipse.osgi.internal.location.LocationHelper; -import org.eclipse.osgi.internal.log.EquinoxLogServices; -import org.eclipse.osgi.internal.messages.Msg; -import org.eclipse.osgi.internal.permadmin.SecurityAdmin; -import org.eclipse.osgi.internal.url.URLStreamHandlerFactoryImpl; -import org.eclipse.osgi.service.datalocation.Location; -import org.eclipse.osgi.storage.BundleInfo.Generation; -import org.eclipse.osgi.storage.ContentProvider.Type; -import org.eclipse.osgi.storage.bundlefile.BundleEntry; -import org.eclipse.osgi.storage.bundlefile.BundleFile; -import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper; -import org.eclipse.osgi.storage.bundlefile.BundleFileWrapperChain; -import org.eclipse.osgi.storage.bundlefile.DirBundleFile; -import org.eclipse.osgi.storage.bundlefile.MRUBundleFileList; -import org.eclipse.osgi.storage.bundlefile.NestedDirBundleFile; -import org.eclipse.osgi.storage.bundlefile.ZipBundleFile; -import org.eclipse.osgi.storage.url.reference.Handler; -import org.eclipse.osgi.storagemanager.ManagedOutputStream; -import org.eclipse.osgi.storagemanager.StorageManager; -import org.eclipse.osgi.util.ManifestElement; -import org.eclipse.osgi.util.NLS; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleException; -import org.osgi.framework.Constants; -import org.osgi.framework.Filter; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.Version; -import org.osgi.framework.connect.ConnectModule; -import org.osgi.framework.namespace.HostNamespace; -import org.osgi.framework.namespace.NativeNamespace; -import org.osgi.framework.namespace.PackageNamespace; -import org.osgi.framework.wiring.BundleCapability; -import org.osgi.framework.wiring.BundleRevision; -import org.osgi.framework.wiring.BundleWiring; -import org.osgi.resource.Namespace; -import org.osgi.resource.Requirement; - -public class Storage { - public static class StorageException extends RuntimeException { - private static final long serialVersionUID = 1L; - - public StorageException() { - super(); - } - - public StorageException(String message, Throwable cause) { - super(message, cause); - } - - public StorageException(String message) { - super(message); - } - - public StorageException(Throwable cause) { - super(cause); - } - - } - - public static final int VERSION = 6; - private static final int CONTENT_TYPE_VERSION = 6; - private static final int CACHED_SYSTEM_CAPS_VERION = 5; - private static final int MR_JAR_VERSION = 4; - private static final int LOWEST_VERSION_SUPPORTED = 3; - public static final String BUNDLE_DATA_DIR = "data"; //$NON-NLS-1$ - public static final String BUNDLE_FILE_NAME = "bundleFile"; //$NON-NLS-1$ - public static final String FRAMEWORK_INFO = "framework.info"; //$NON-NLS-1$ - public static final String ECLIPSE_SYSTEMBUNDLE = "Eclipse-SystemBundle"; //$NON-NLS-1$ - public static final String DELETE_FLAG = ".delete"; //$NON-NLS-1$ - public static final String LIB_TEMP = "libtemp"; //$NON-NLS-1$ - - private static final String JAVASE = "JavaSE"; //$NON-NLS-1$ - private static final String PROFILE_EXT = ".profile"; //$NON-NLS-1$ - private static final String NUL = new String(new byte[] {0}); - private static final String INITIAL_LOCATION = "initial@"; //$NON-NLS-1$ - - static final SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction()); - - private final EquinoxContainer equinoxContainer; - private final String installPath; - private final Location osgiLocation; - private final File childRoot; - private final File parentRoot; - private final PermissionData permissionData; - private final SecurityAdmin securityAdmin; - private final EquinoxContainerAdaptor adaptor; - private final ModuleDatabase moduleDatabase; - private final ModuleContainer moduleContainer; - private final Object saveMonitor = new Object(); - private long lastSavedTimestamp = -1; - private final MRUBundleFileList mruList; - private final FrameworkExtensionInstaller extensionInstaller; - private final List cachedHeaderKeys = Arrays.asList(Constants.BUNDLE_SYMBOLICNAME, Constants.BUNDLE_ACTIVATIONPOLICY, "Service-Component"); //$NON-NLS-1$ - private final boolean allowRestrictedProvides; - private final AtomicBoolean refreshMRBundles = new AtomicBoolean(false); - private final Version runtimeVersion; - private final String javaSpecVersion; - - public static Storage createStorage(EquinoxContainer container) throws IOException, BundleException { - String[] cachedInfo = new String[3]; - Storage storage = new Storage(container, cachedInfo); - // Do some operations that need to happen on the fully constructed Storage before returning it - storage.checkSystemBundle(cachedInfo); - storage.refreshStaleBundles(); - storage.installExtensions(); - // TODO hack to make sure all bundles are in UNINSTALLED state before system - // bundle init is called - storage.getModuleContainer().setInitialModuleStates(); - return storage; - } - - private Storage(EquinoxContainer container, String[] cachedInfo) throws IOException { - // default to Java 8 since that is our min - Version defaultVersion = Version.valueOf("1.8"); //$NON-NLS-1$ - Version javaVersion = defaultVersion; - // set the profile and EE based off of the java.specification.version - String javaSpecVersionProp = System.getProperty(EquinoxConfiguration.PROP_JVM_SPEC_VERSION); - StringTokenizer st = new StringTokenizer(javaSpecVersionProp, " _-"); //$NON-NLS-1$ - javaSpecVersionProp = st.nextToken(); - try { - String[] vComps = javaSpecVersionProp.split("\\."); //$NON-NLS-1$ - // only pay attention to the first three components of the version - int major = vComps.length > 0 ? Integer.parseInt(vComps[0]) : 0; - int minor = vComps.length > 1 ? Integer.parseInt(vComps[1]) : 0; - int micro = vComps.length > 2 ? Integer.parseInt(vComps[2]) : 0; - javaVersion = new Version(major, minor, micro); - } catch (IllegalArgumentException e) { - // do nothing - } - if (javaVersion.compareTo(defaultVersion) < 0) { - // the Java specification property is wrong, we are compiled to the - // defaultVersion - // just use it instead. - javaVersion = defaultVersion; - } - runtimeVersion = javaVersion; - javaSpecVersion = javaSpecVersionProp; - mruList = new MRUBundleFileList(getBundleFileLimit(container.getConfiguration()), container.getConfiguration().getDebug()); - equinoxContainer = container; - extensionInstaller = new FrameworkExtensionInstaller(container.getConfiguration()); - allowRestrictedProvides = Boolean.parseBoolean(container.getConfiguration().getConfiguration(EquinoxConfiguration.PROP_ALLOW_RESTRICTED_PROVIDES)); - - // we need to set the install path as soon as possible so we can determine - // the absolute location of install relative URLs - Location installLoc = container.getLocations().getInstallLocation(); - URL installURL = installLoc.getURL(); - // assume install URL is file: based - installPath = installURL.getPath(); - - Location configLocation = container.getLocations().getConfigurationLocation(); - Location parentConfigLocation = configLocation.getParentLocation(); - Location osgiParentLocation = null; - if (parentConfigLocation != null) { - osgiParentLocation = parentConfigLocation.createLocation(null, parentConfigLocation.getDataArea(EquinoxContainer.NAME), true); - } - this.osgiLocation = configLocation.createLocation(osgiParentLocation, configLocation.getDataArea(EquinoxContainer.NAME), configLocation.isReadOnly()); - this.childRoot = new File(osgiLocation.getURL().getPath()); - - if (Boolean.valueOf(container.getConfiguration().getConfiguration(EquinoxConfiguration.PROP_CLEAN)).booleanValue()) { - cleanOSGiStorage(osgiLocation, childRoot); - } - if (!this.osgiLocation.isReadOnly()) { - this.childRoot.mkdirs(); - } - Location parent = this.osgiLocation.getParentLocation(); - parentRoot = parent == null ? null : new File(parent.getURL().getPath()); - - if (container.getConfiguration().getConfiguration(Constants.FRAMEWORK_STORAGE) == null) { - // Set the derived value if not already set as part of configuration. - // Note this is the parent directory of where the framework stores data (org.eclipse.osgi/) - container.getConfiguration().setConfiguration(Constants.FRAMEWORK_STORAGE, childRoot.getParentFile().getAbsolutePath()); - } - - InputStream info = getInfoInputStream(); - DataInputStream data = info == null ? null : new DataInputStream(new BufferedInputStream(info)); - try { - Map generations; - try { - generations = loadGenerations(data, cachedInfo); - } catch (IllegalArgumentException e) { - equinoxContainer.getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.WARNING, "The persistent format for the framework data has changed. The framework will be reinitialized: " + e.getMessage(), null); //$NON-NLS-1$ - generations = new HashMap<>(0); - data = null; - cleanOSGiStorage(osgiLocation, childRoot); - } - this.permissionData = loadPermissionData(data); - this.securityAdmin = new SecurityAdmin(null, this.permissionData); - this.adaptor = new EquinoxContainerAdaptor(equinoxContainer, this, generations); - this.moduleDatabase = new ModuleDatabase(this.adaptor); - this.moduleContainer = new ModuleContainer(this.adaptor, this.moduleDatabase); - if (data != null) { - try { - moduleDatabase.load(data); - lastSavedTimestamp = moduleDatabase.getTimestamp(); - } catch (IllegalArgumentException e) { - equinoxContainer.getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.WARNING, "Incompatible version. Starting with empty framework.", e); //$NON-NLS-1$ - // Clean up the cache. - // No need to clean up the database. Nothing got loaded. - cleanOSGiStorage(osgiLocation, childRoot); - // should free up the generations map - generations.clear(); - } - } - } finally { - if (data != null) { - try { - data.close(); - } catch (IOException e) { - // just move on - } - } - } - } - - public Version getRuntimeVersion() { - return runtimeVersion; - } - - public MRUBundleFileList getMRUBundleFileList() { - return mruList; - } - - private int getBundleFileLimit(EquinoxConfiguration configuration) { - int propValue = 100; // enable to 100 open files by default - try { - String prop = configuration.getConfiguration(EquinoxConfiguration.PROP_FILE_LIMIT); - if (prop != null) - propValue = Integer.parseInt(prop); - } catch (NumberFormatException e) { - // use default of 100 - } - return propValue; - } - - private void installExtensions() { - Module systemModule = moduleContainer.getModule(0); - ModuleRevision systemRevision = systemModule == null ? null : systemModule.getCurrentRevision(); - ModuleWiring systemWiring = systemRevision == null ? null : systemRevision.getWiring(); - if (systemWiring == null) { - return; - } - Collection fragments = new ArrayList<>(); - for (ModuleWire hostWire : systemWiring.getProvidedModuleWires(HostNamespace.HOST_NAMESPACE)) { - fragments.add(hostWire.getRequirer()); - } - try { - getExtensionInstaller().addExtensionContent(fragments, null); - } catch (BundleException e) { - getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, e.getMessage(), e); - } - } - - private static PermissionData loadPermissionData(DataInputStream in) throws IOException { - PermissionData permData = new PermissionData(); - if (in != null) { - permData.readPermissionData(in); - } - return permData; - } - - private void refreshStaleBundles() throws BundleException { - Collection needsRefresh = new ArrayList<>(0); - - // First uninstall any modules that had their content changed or deleted - for (Module module : moduleContainer.getModules()) { - if (module.getId() == Constants.SYSTEM_BUNDLE_ID) - continue; - ModuleRevision revision = module.getCurrentRevision(); - Generation generation = (Generation) revision.getRevisionInfo(); - if (needsDiscarding(generation)) { - needsRefresh.add(module); - moduleContainer.uninstall(module); - generation.delete(); - } - } - // Next check if we need to refresh Multi-Release Jar bundles - // because the runtime version changed. - if (refreshMRBundles.get()) { - needsRefresh.addAll(refreshMRJarBundles()); - } - - // refresh the modules that got deleted or are Multi-Release bundles - if (!needsRefresh.isEmpty()) { - moduleContainer.refresh(needsRefresh); - } - } - - private boolean needsDiscarding(Generation generation) { - for (StorageHook hook : generation.getStorageHooks()) { - try { - hook.validate(); - } catch (IllegalStateException e) { - equinoxContainer.getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.WARNING, "Error validating installed bundle.", e); //$NON-NLS-1$ - return true; - } - } - File content = generation.getContent(); - if (content == null) { - return false; - } - if (getConfiguration().inCheckConfigurationMode()) { - if (generation.isDirectory()) { - content = new File(content, "META-INF/MANIFEST.MF"); //$NON-NLS-1$ - } - return generation.getLastModified() != secureAction.lastModified(content); - } - if (!content.exists()) { - // the content got deleted since last time! - return true; - } - return false; - } - - private void checkSystemBundle(String[] cachedInfo) { - Module systemModule = moduleContainer.getModule(0); - Generation newGeneration = null; - try { - if (systemModule == null) { - BundleInfo info = new BundleInfo(this, 0, Constants.SYSTEM_BUNDLE_LOCATION, 0); - newGeneration = info.createGeneration(); - - File contentFile = getSystemContent(); - newGeneration.setContent(contentFile, Type.DEFAULT); - - // First we must make sure the VM profile has been loaded - loadVMProfile(newGeneration); - // dealing with system bundle find the extra capabilities and exports - String extraCapabilities = getSystemExtraCapabilities(); - String extraExports = getSystemExtraPackages(); - - ModuleRevisionBuilder builder = getBuilder(newGeneration, extraCapabilities, extraExports); - systemModule = moduleContainer.install(null, Constants.SYSTEM_BUNDLE_LOCATION, builder, newGeneration); - moduleContainer.resolve(Collections.singletonList(systemModule), false); - } else { - ModuleRevision currentRevision = systemModule.getCurrentRevision(); - Generation currentGeneration = currentRevision == null ? null : (Generation) currentRevision.getRevisionInfo(); - if (currentGeneration == null) { - throw new IllegalStateException("No current revision for system bundle."); //$NON-NLS-1$ - } - try { - // First we must make sure the VM profile has been loaded - loadVMProfile(currentGeneration); - // dealing with system bundle find the extra capabilities and exports - String extraCapabilities = getSystemExtraCapabilities(); - String extraExports = getSystemExtraPackages(); - File contentFile = currentGeneration.getContent(); - if (systemNeedsUpdate(contentFile, currentRevision, currentGeneration, extraCapabilities, extraExports, cachedInfo)) { - newGeneration = currentGeneration.getBundleInfo().createGeneration(); - newGeneration.setContent(contentFile, Type.DEFAULT); - ModuleRevisionBuilder newBuilder = getBuilder(newGeneration, extraCapabilities, extraExports); - moduleContainer.update(systemModule, newBuilder, newGeneration); - moduleContainer.refresh(Collections.singleton(systemModule)); - } else { - if (currentRevision.getWiring() == null) { - // must resolve before continuing to ensure extensions get attached - moduleContainer.resolve(Collections.singleton(systemModule), true); - } - } - } catch (BundleException e) { - throw new IllegalStateException("Could not create a builder for the system bundle.", e); //$NON-NLS-1$ - } - } - ModuleRevision currentRevision = systemModule.getCurrentRevision(); - List nativeEnvironments = currentRevision.getModuleCapabilities(NativeNamespace.NATIVE_NAMESPACE); - Map configMap = equinoxContainer.getConfiguration().getInitialConfig(); - for (ModuleCapability nativeEnvironment : nativeEnvironments) { - nativeEnvironment.setTransientAttrs(configMap); - } - Version frameworkVersion = null; - if (newGeneration != null) { - frameworkVersion = findFrameworkVersion(); - } else { - String sVersion = cachedInfo[0]; - frameworkVersion = sVersion == null ? findFrameworkVersion() : Version.parseVersion(sVersion); - } - if (frameworkVersion != null) { - this.equinoxContainer.getConfiguration().setConfiguration(Constants.FRAMEWORK_VERSION, frameworkVersion.toString()); - } - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } - throw new RuntimeException("Error occurred while checking the system module.", e); //$NON-NLS-1$ - } finally { - if (newGeneration != null) { - newGeneration.getBundleInfo().unlockGeneration(newGeneration); - } - } - } - - private Version findFrameworkVersion() { - Requirement osgiPackageReq = ModuleContainer.createRequirement(PackageNamespace.PACKAGE_NAMESPACE, Collections.singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" + PackageNamespace.PACKAGE_NAMESPACE + "=org.osgi.framework)"), Collections.emptyMap()); //$NON-NLS-1$ //$NON-NLS-2$ - Collection osgiPackages = moduleContainer.getFrameworkWiring().findProviders(osgiPackageReq); - for (BundleCapability packageCapability : osgiPackages) { - if (packageCapability.getRevision().getBundle().getBundleId() == 0) { - Version v = (Version) packageCapability.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE); - if (v != null) { - return v; - } - } - } - return null; - } - - private Collection refreshMRJarBundles() throws BundleException { - Collection mrJarBundles = new ArrayList<>(); - for (Module m : moduleContainer.getModules()) { - Generation generation = (Generation) m.getCurrentRevision().getRevisionInfo(); - // Note that we check the raw headers here incase we are working off an old version of the persistent storage - if (Boolean.parseBoolean(generation.getRawHeaders().get(BundleInfo.MULTI_RELEASE_HEADER))) { - refresh(m); - mrJarBundles.add(m); - } - } - return mrJarBundles; - } - - public void close() { - try { - save(); - } catch (IOException e) { - getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, "Error saving on shutdown", e); //$NON-NLS-1$ - } - - // close all the generations - List modules = moduleContainer.getModules(); - for (Module module : modules) { - for (ModuleRevision revision : module.getRevisions().getModuleRevisions()) { - Generation generation = (Generation) revision.getRevisionInfo(); - if (generation != null) { - generation.close(); - } - } - } - for (ModuleRevision removalPending : moduleContainer.getRemovalPending()) { - Generation generation = (Generation) removalPending.getRevisionInfo(); - if (generation != null) { - generation.close(); - } - } - mruList.shutdown(); - adaptor.shutdownExecutors(); - } - - private boolean systemNeedsUpdate(File systemContent, ModuleRevision currentRevision, Generation existing, String extraCapabilities, String extraExports, String[] cachedInfo) throws BundleException { - if (!extraCapabilities.equals(cachedInfo[1])) { - return true; - } - if (!extraExports.equals(cachedInfo[2])) { - return true; - } - if (systemContent == null) { - // only do a version check in this case - ModuleRevisionBuilder newBuilder = getBuilder(existing, extraCapabilities, extraExports); - return !currentRevision.getVersion().equals(newBuilder.getVersion()); - } - if (existing.isDirectory()) { - systemContent = new File(systemContent, "META-INF/MANIFEST.MF"); //$NON-NLS-1$ - } - return existing.getLastModified() != secureAction.lastModified(systemContent); - - } - - private void cleanOSGiStorage(Location location, File root) { - if (location.isReadOnly() || !StorageUtil.rm(root, getConfiguration().getDebug().DEBUG_STORAGE)) { - equinoxContainer.getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, "The -clean (osgi.clean) option was not successful. Unable to clean the storage area: " + root.getAbsolutePath(), null); //$NON-NLS-1$ - } - if (!location.isReadOnly()) { - // make sure to recreate to root folder - root.mkdirs(); - } - } - - public ModuleDatabase getModuleDatabase() { - return moduleDatabase; - } - - public ModuleContainerAdaptor getAdaptor() { - return adaptor; - } - - public ModuleContainer getModuleContainer() { - return moduleContainer; - } - - public EquinoxConfiguration getConfiguration() { - return equinoxContainer.getConfiguration(); - } - - public EquinoxLogServices getLogServices() { - return equinoxContainer.getLogServices(); - } - - public FrameworkExtensionInstaller getExtensionInstaller() { - return extensionInstaller; - } - - public boolean isReadOnly() { - return osgiLocation.isReadOnly(); - } - - public URLConnection getContentConnection(Module module, String bundleLocation, final InputStream in) - throws BundleException { - try { - List> storageHooks = getConfiguration().getHookRegistry() - .getStorageHookFactories(); - for (StorageHookFactory storageHook : storageHooks) { - URLConnection hookContent = storageHook.handleContentConnection(module, bundleLocation, in); - if (hookContent != null) { - return hookContent; - } - } - - if (in != null) { - return new URLConnection(null) { - /** - * @throws IOException - */ - @Override - public void connect() throws IOException { - connected = true; - } - - /** - * @throws IOException - */ - @Override - public InputStream getInputStream() throws IOException { - return (in); - } - }; - } - if (module == null) { - if (bundleLocation == null) { - throw new IllegalArgumentException("Module and location cannot be null"); //$NON-NLS-1$ - } - return getContentConnection(bundleLocation); - } - return getContentConnection(getUpdateLocation(module)); - } catch (IOException e) { - throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$ - } - } - - private String getUpdateLocation(final Module module) { - if (System.getSecurityManager() == null) - return getUpdateLocation0(module); - return AccessController.doPrivileged((PrivilegedAction) () -> getUpdateLocation0(module)); - } - - String getUpdateLocation0(Module module) { - ModuleRevision current = module.getCurrentRevision(); - Generation generation = (Generation) current.getRevisionInfo(); - String updateLocation = generation.getHeaders().get(Constants.BUNDLE_UPDATELOCATION); - if (updateLocation == null) { - updateLocation = module.getLocation(); - } - if (updateLocation.startsWith(INITIAL_LOCATION)) { - updateLocation = updateLocation.substring(INITIAL_LOCATION.length()); - } - return updateLocation; - } - - private URLConnection getContentConnection(final String spec) throws IOException { - if (System.getSecurityManager() == null) { - return LocationHelper.getConnection(createURL(spec)); - } - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> LocationHelper.getConnection(createURL(spec))); - } catch (PrivilegedActionException e) { - if (e.getException() instanceof IOException) - throw (IOException) e.getException(); - throw (RuntimeException) e.getException(); - } - } - - URL createURL(String spec) throws MalformedURLException { - if (spec.startsWith(URLStreamHandlerFactoryImpl.PROTOCOL_REFERENCE)) { - return new URL(null, spec, new Handler(equinoxContainer.getConfiguration().getConfiguration(EquinoxLocations.PROP_INSTALL_AREA))); - } - return new URL(spec); - } - - public Generation install(Module origin, String bundleLocation, InputStream toInstall) throws BundleException { - URLConnection content = getContentConnection(null, bundleLocation, toInstall); - if (osgiLocation.isReadOnly()) { - throw new BundleException("The framework storage area is read only.", BundleException.INVALID_OPERATION); //$NON-NLS-1$ - } - URL sourceURL = content.getURL(); - InputStream in; - try { - in = content.getInputStream(); - } catch (Throwable e) { - throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$ - } - - // Check if the bundle already exists at this location - // before doing the staging and generation creation. - // This is important since some installers seem to continually - // re-install bundles using the same location each startup - Module existingLocation = moduleContainer.getModule(bundleLocation); - if (existingLocation != null) { - // NOTE this same logic is also in the ModuleContainer - // This is necessary because the container does the location locking. - // Another thread could win the location lock and install before this thread does. - try { - in.close(); - } catch (IOException e) { - // ignore - } - if (origin != null) { - // Check that the existing location is visible from the origin module - Bundle bundle = origin.getBundle(); - BundleContext context = bundle == null ? null : bundle.getBundleContext(); - if (context != null && context.getBundle(existingLocation.getId()) == null) { - Bundle b = existingLocation.getBundle(); - throw new BundleException(NLS.bind(Msg.ModuleContainer_NameCollisionWithLocation, new Object[] {b.getSymbolicName(), b.getVersion(), bundleLocation}), BundleException.REJECTED_BY_HOOK); - } - } - return (Generation) existingLocation.getCurrentRevision().getRevisionInfo(); - } - - ContentProvider contentProvider = getContentProvider(in, sourceURL); - Type contentType = contentProvider.getType(); - File staged = contentProvider.getContent(); - - Generation generation = null; - try { - Long nextID = moduleDatabase.getAndIncrementNextId(); - BundleInfo info = new BundleInfo(this, nextID, bundleLocation, 0); - generation = info.createGeneration(); - - File contentFile = getContentFile(staged, contentType, nextID, generation.getGenerationId()); - generation.setContent(contentFile, contentType); - // Check that we can open the bundle file - generation.getBundleFile().open(); - setStorageHooks(generation); - - ModuleRevisionBuilder builder = getBuilder(generation); - builder.setId(nextID); - - Module m = moduleContainer.install(origin, bundleLocation, builder, generation); - if (!nextID.equals(m.getId())) { - // this revision is already installed. delete the generation - generation.delete(); - return (Generation) m.getCurrentRevision().getRevisionInfo(); - } - return generation; - } catch (Throwable t) { - if (contentType == Type.DEFAULT) { - try { - delete(staged); - } catch (IOException e) { - // tried our best - } - } - if (generation != null) { - generation.delete(); - generation.getBundleInfo().delete(); - } - if (t instanceof SecurityException) { - // TODO hack from ModuleContainer - // if the cause is a bundle exception then throw that - if (t.getCause() instanceof BundleException) { - throw (BundleException) t.getCause(); - } - throw (SecurityException) t; - } - if (t instanceof BundleException) { - throw (BundleException) t; - } - throw new BundleException("Error occurred installing a bundle.", t); //$NON-NLS-1$ - } finally { - if (generation != null) { - generation.getBundleInfo().unlockGeneration(generation); - } - } - } - - ContentProvider getContentProvider(final InputStream in, final URL sourceURL) { - if (in instanceof ContentProvider) { - return (ContentProvider) in; - } - return new ContentProvider() { - - @Override - public Type getType() { - return Type.DEFAULT; - } - - @Override - public File getContent() throws BundleException { - return stageContent(in, sourceURL); - } - }; - } - - private void setStorageHooks(Generation generation) throws BundleException { - if (generation.getBundleInfo().getBundleId() == 0) { - return; // ignore system bundle - } - List> factories = new ArrayList<>(getConfiguration().getHookRegistry().getStorageHookFactories()); - List> hooks = new ArrayList<>(factories.size()); - for (StorageHookFactory storageHookFactory : factories) { - @SuppressWarnings("unchecked") - StorageHookFactory> next = (StorageHookFactory>) storageHookFactory; - StorageHook hook = next.createStorageHookAndValidateFactoryClass(generation); - if (hook != null) { - hooks.add(hook); - } - } - generation.setStorageHooks(Collections.unmodifiableList(hooks), true); - for (StorageHook hook : hooks) { - hook.initialize(generation.getHeaders()); - } - } - - public ModuleRevisionBuilder getBuilder(Generation generation) throws BundleException { - return getBuilder(generation, null, null); - } - - public ModuleRevisionBuilder getBuilder(Generation generation, String extraCapabilities, String extraExports) throws BundleException { - Dictionary headers = generation.getHeaders(); - Map mapHeaders; - if (headers instanceof Map) { - @SuppressWarnings("unchecked") - Map unchecked = (Map) headers; - mapHeaders = unchecked; - } else { - mapHeaders = new HashMap<>(); - for (Enumeration eKeys = headers.keys(); eKeys.hasMoreElements();) { - String key = eKeys.nextElement(); - mapHeaders.put(key, headers.get(key)); - } - } - if (generation.getBundleInfo().getBundleId() != 0) { - ModuleRevisionBuilder builder = OSGiManifestBuilderFactory.createBuilder(mapHeaders, null, // - (generation.getContentType() == Type.CONNECT ? "" : null), //$NON-NLS-1$ - (allowRestrictedProvides ? "" : null)); //$NON-NLS-1$ - if ((builder.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) { - for (ModuleRevisionBuilder.GenericInfo reqInfo : builder.getRequirements(HostNamespace.HOST_NAMESPACE)) { - if (HostNamespace.EXTENSION_BOOTCLASSPATH.equals(reqInfo.getDirectives().get(HostNamespace.REQUIREMENT_EXTENSION_DIRECTIVE))) { - throw new BundleException("Boot classpath extensions are not supported.", //$NON-NLS-1$ - BundleException.UNSUPPORTED_OPERATION, new UnsupportedOperationException()); - } - } - } - return builder; - } - - return OSGiManifestBuilderFactory.createBuilder(mapHeaders, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, extraExports, extraCapabilities); - } - - private String getSystemExtraCapabilities() { - EquinoxConfiguration equinoxConfig = equinoxContainer.getConfiguration(); - StringBuilder result = new StringBuilder(); - - String systemCapabilities = equinoxConfig.getConfiguration(Constants.FRAMEWORK_SYSTEMCAPABILITIES); - if (systemCapabilities != null && systemCapabilities.trim().length() > 0) { - result.append(systemCapabilities).append(", "); //$NON-NLS-1$ - } - - String extraSystemCapabilities = equinoxConfig.getConfiguration(Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA); - if (extraSystemCapabilities != null && extraSystemCapabilities.trim().length() > 0) { - result.append(extraSystemCapabilities).append(", "); //$NON-NLS-1$ - } - - result.append(EclipsePlatformNamespace.ECLIPSE_PLATFORM_NAMESPACE).append("; "); //$NON-NLS-1$ - result.append(EquinoxConfiguration.PROP_OSGI_OS).append("=").append(equinoxConfig.getOS()).append("; "); //$NON-NLS-1$ //$NON-NLS-2$ - result.append(EquinoxConfiguration.PROP_OSGI_WS).append("=").append(equinoxConfig.getWS()).append("; "); //$NON-NLS-1$ //$NON-NLS-2$ - result.append(EquinoxConfiguration.PROP_OSGI_ARCH).append("=").append(equinoxConfig.getOSArch()).append("; "); //$NON-NLS-1$ //$NON-NLS-2$ - result.append(EquinoxConfiguration.PROP_OSGI_NL).append("=").append(equinoxConfig.getNL()); //$NON-NLS-1$ - - String osName = equinoxConfig.getConfiguration(Constants.FRAMEWORK_OS_NAME); - osName = osName == null ? null : osName.toLowerCase(); - String processor = equinoxConfig.getConfiguration(Constants.FRAMEWORK_PROCESSOR); - processor = processor == null ? null : processor.toLowerCase(); - String osVersion = equinoxConfig.getConfiguration(Constants.FRAMEWORK_OS_VERSION); - osVersion = osVersion == null ? null : osVersion.toLowerCase(); - String language = equinoxConfig.getConfiguration(Constants.FRAMEWORK_LANGUAGE); - language = language == null ? null : language.toLowerCase(); - - result.append(", "); //$NON-NLS-1$ - result.append(NativeNamespace.NATIVE_NAMESPACE).append("; "); //$NON-NLS-1$ - if (osName != null) { - osName = getAliasList(equinoxConfig.getAliasMapper().getOSNameAliases(osName)); - result.append(NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE).append(":List=").append(osName).append("; "); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (processor != null) { - processor = getAliasList(equinoxConfig.getAliasMapper().getProcessorAliases(processor)); - result.append(NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE).append(":List=").append(processor).append("; "); //$NON-NLS-1$ //$NON-NLS-2$ - } - result.append(NativeNamespace.CAPABILITY_OSVERSION_ATTRIBUTE).append(":Version").append("=\"").append(osVersion).append("\"; "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - result.append(NativeNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE).append("=\"").append(language).append('\"'); //$NON-NLS-1$ - return result.toString(); - } - - String getAliasList(Collection aliases) { - if (aliases.isEmpty()) { - return null; - } - StringBuilder builder = new StringBuilder(); - builder.append('"'); - for (String alias : aliases) { - builder.append(alias).append(','); - } - builder.setLength(builder.length() - 1); - builder.append('"'); - return builder.toString(); - } - - private String getSystemExtraPackages() { - EquinoxConfiguration equinoxConfig = equinoxContainer.getConfiguration(); - StringBuilder result = new StringBuilder(); - - String systemPackages = equinoxConfig.getConfiguration(Constants.FRAMEWORK_SYSTEMPACKAGES); - if (systemPackages != null) { - result.append(systemPackages); - } - - String extraSystemPackages = equinoxConfig.getConfiguration(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA); - if (extraSystemPackages != null && extraSystemPackages.trim().length() > 0) { - if (result.length() > 0) { - result.append(", "); //$NON-NLS-1$ - } - result.append(extraSystemPackages); - } - - return result.toString(); - } - - private void refresh(Module module) throws BundleException { - ModuleRevision current = module.getCurrentRevision(); - Generation currentGen = (Generation) current.getRevisionInfo(); - File content = currentGen.getContent(); - if (content == null) { - // TODO Handle connect bundle - return; - } - String spec = (currentGen.getContentType() == Type.REFERENCE ? "reference:" : "") + content.toURI().toString(); //$NON-NLS-1$ //$NON-NLS-2$ - URLConnection contentConn; - try { - contentConn = getContentConnection(spec); - } catch (IOException e) { - throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$ - } - update(module, contentConn); - } - - public Generation update(Module module, InputStream updateIn) throws BundleException { - return update(module, getContentConnection(module, null, updateIn)); - } - - private Generation update(Module module, URLConnection content) throws BundleException { - - if (osgiLocation.isReadOnly()) { - throw new BundleException("The framework storage area is read only.", BundleException.INVALID_OPERATION); //$NON-NLS-1$ - } - URL sourceURL = content.getURL(); - InputStream in; - try { - in = content.getInputStream(); - } catch (Throwable e) { - throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$ - } - - ContentProvider contentProvider = getContentProvider(in, sourceURL); - Type contentType = contentProvider.getType(); - File staged = contentProvider.getContent(); - - ModuleRevision current = module.getCurrentRevision(); - Generation currentGen = (Generation) current.getRevisionInfo(); - - BundleInfo bundleInfo = currentGen.getBundleInfo(); - Generation newGen = bundleInfo.createGeneration(); - - try { - File contentFile = getContentFile(staged, contentType, bundleInfo.getBundleId(), newGen.getGenerationId()); - newGen.setContent(contentFile, contentType); - // Check that we can open the bundle file - newGen.getBundleFile().open(); - setStorageHooks(newGen); - - ModuleRevisionBuilder builder = getBuilder(newGen); - moduleContainer.update(module, builder, newGen); - } catch (Throwable t) { - if (contentType == Type.DEFAULT) { - try { - delete(staged); - } catch (IOException e) { - // tried our best - } - } - newGen.delete(); - if (t instanceof SecurityException) { - // TODO hack from ModuleContainer - // if the cause is a bundle exception then throw that - if (t.getCause() instanceof BundleException) { - throw (BundleException) t.getCause(); - } - throw (SecurityException) t; - } - if (t instanceof BundleException) { - throw (BundleException) t; - } - throw new BundleException("Error occurred updating a bundle.", t); //$NON-NLS-1$ - } finally { - bundleInfo.unlockGeneration(newGen); - } - return newGen; - } - - private File getContentFile(final File staged, Type contentType, final long bundleID, final long generationID) throws BundleException { - if (System.getSecurityManager() == null) - return getContentFile0(staged, contentType, bundleID, generationID); - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> getContentFile0(staged, contentType, bundleID, generationID)); - } catch (PrivilegedActionException e) { - if (e.getException() instanceof BundleException) - throw (BundleException) e.getException(); - throw (RuntimeException) e.getException(); - } - } - - File getContentFile0(File staged, Type contentType, long bundleID, long generationID) throws BundleException { - File contentFile = staged; - - if (contentType == Type.DEFAULT) { - File generationRoot = new File(childRoot, bundleID + "/" + generationID); //$NON-NLS-1$ - generationRoot.mkdirs(); - if (!generationRoot.isDirectory()) { - throw new BundleException("Could not create generation directory: " + generationRoot.getAbsolutePath()); //$NON-NLS-1$ - } - contentFile = new File(generationRoot, BUNDLE_FILE_NAME); - try { - StorageUtil.move(staged, contentFile, getConfiguration().getDebug().DEBUG_STORAGE); - } catch (IOException e) { - throw new BundleException("Error while renaming bundle file to final location: " + contentFile, //$NON-NLS-1$ - BundleException.READ_ERROR, e); - } - } - return contentFile; - } - - private static String getBundleFilePath(long bundleID, long generationID) { - return bundleID + "/" + generationID + "/" + BUNDLE_FILE_NAME; //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Gets a file from storage and conditionally checks the parent storage area - * if the file does not exist in the child configuration. - * Note, this method does not check for escaping of paths from the root storage area. - * @param path the path relative to the root of the storage area - * @param checkParent if true then check the parent storage (if any) when the file - * does not exist in the child storage area - * @return the file being requested. A {@code null} value is never returned. The file - * returned may not exist. - * @throws StorageException if there was an issue getting the file - */ - public File getFile(String path, boolean checkParent) throws StorageException { - return getFile(null, path, checkParent); - } - - /** - * Same as {@link #getFile(String, boolean)} except takes a base parameter which is - * appended to the root storage area before looking for the path. If base is not - * null then additional checks are done to make sure the path does not escape out - * of the base path. - * @param base the additional base path to append to the root storage area. May be - * {@code null}, in which case no check is done for escaping out of the base path. - * @param path the path relative to the root + base storage area. - * @param checkParent if true then check the parent storage (if any) when the file - * does not exist in the child storage area - * @return the file being requested. A {@code null} value is never returned. The file - * returned may not exist. - * @throws StorageException if there was an issue getting the file - */ - public File getFile(String base, String path, boolean checkParent) throws StorageException { - // first check the child location - File childPath = getFile(childRoot, base, path); - // now check the parent - if (checkParent && parentRoot != null) { - if (childPath.exists()) { - return childPath; - } - File parentPath = getFile(parentRoot, base, path); - if (parentPath.exists()) { - // only use the parent file only if it exists; - return parentPath; - } - } - // did not exist in both locations; use the child path - return childPath; - } - - private static File getFile(File root, String base, String path) { - if (base == null) { - // return quick; no need to check for path traversal - return new File(root, path); - } - - // if base is not null then move root to include the base - File rootBase = new File(root, base); - File result = new File(rootBase, path); - if (path.contains("..")) { //$NON-NLS-1$ - // do the extra check to make sure the path did not escape the root path - Path resultNormalized = result.toPath().normalize(); - Path rootBaseNormalized = rootBase.toPath().normalize(); - if (!resultNormalized.startsWith(rootBaseNormalized)) { - throw new StorageException("Invalid path: " + path); //$NON-NLS-1$ - } - } - // Additional check if it is a special device instead of a regular file. - if (StorageUtil.isReservedFileName(result)) { - throw new StorageException("Invalid filename: " + path); //$NON-NLS-1$ - } - return result; - } - - File stageContent(final InputStream in, final URL sourceURL) throws BundleException { - if (System.getSecurityManager() == null) - return stageContent0(in, sourceURL); - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> stageContent0(in, sourceURL)); - } catch (PrivilegedActionException e) { - if (e.getException() instanceof BundleException) - throw (BundleException) e.getException(); - throw (RuntimeException) e.getException(); - } - } - - File stageContent0(InputStream in, URL sourceURL) throws BundleException { - File outFile = null; - try (InputStream stream = in) { - outFile = ReliableFile.createTempFile(BUNDLE_FILE_NAME, ".tmp", childRoot); //$NON-NLS-1$ - String protocol = sourceURL == null ? null : sourceURL.getProtocol(); - - if ("file".equals(protocol)) { //$NON-NLS-1$ - File inFile = new File(sourceURL.getPath()); - inFile = LocationHelper.decodePath(inFile); - if (inFile.isDirectory()) { - // need to delete the outFile because it is not a directory - outFile.delete(); - } - StorageUtil.copy(inFile, outFile); - } else { - StorageUtil.readFile(in, outFile); - } - return outFile; - } catch (IOException e) { - if (outFile != null) { - outFile.delete(); - } - throw new BundleException(Msg.BUNDLE_READ_EXCEPTION, BundleException.READ_ERROR, e); - } - } - - /** - * Attempts to set the permissions of the file in a system dependent way. - * @param file the file to set the permissions on - */ - public void setPermissions(File file) { - String commandProp = getConfiguration().getConfiguration(EquinoxConfiguration.PROP_SETPERMS_CMD); - if (commandProp == null) - commandProp = getConfiguration().getConfiguration(Constants.FRAMEWORK_EXECPERMISSION); - if (commandProp == null) - return; - String[] commandComponents = ManifestElement.getArrayFromList(commandProp, " "); //$NON-NLS-1$ - List command = new ArrayList<>(commandComponents.length + 1); - boolean foundFullPath = false; - for (String commandComponent : commandComponents) { - if ("[fullpath]".equals(commandComponent) || "${abspath}".equals(commandComponent)) { //$NON-NLS-1$ //$NON-NLS-2$ - command.add(file.getAbsolutePath()); - foundFullPath = true; - } else { - command.add(commandComponent); - } - } - if (!foundFullPath) - command.add(file.getAbsolutePath()); - try { - Runtime.getRuntime().exec(command.toArray(new String[command.size()])).waitFor(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public BundleFile createBundleFile(File content, Generation generation, boolean isDirectory, boolean isBase) { - BundleFile result = null; - ConnectModule connectModule = null; - if (generation.getContentType() == Type.CONNECT) { - connectModule = equinoxContainer.getConnectModules().getConnectModule(generation.getBundleInfo().getLocation()); - } - try { - if (connectModule != null && isBase) { - result = equinoxContainer.getConnectModules().getConnectBundleFile(connectModule, content, generation, - mruList, getConfiguration().getDebug()); - } else if (isDirectory) { - boolean strictPath = Boolean.parseBoolean(getConfiguration().getConfiguration( - EquinoxConfiguration.PROPERTY_STRICT_BUNDLE_ENTRY_PATH, Boolean.FALSE.toString())); - result = new DirBundleFile(content, strictPath); - } else { - result = new ZipBundleFile(content, generation, mruList, getConfiguration().getDebug(), - getConfiguration().runtimeVerifySignedBundles); - } - } catch (IOException e) { - throw new RuntimeException("Could not create bundle file.", e); //$NON-NLS-1$ - } - return wrapBundleFile(result, generation, isBase); - } - - public BundleFile createNestedBundleFile(String nestedDir, BundleFile bundleFile, Generation generation) { - return createNestedBundleFile(nestedDir, bundleFile, generation, Collections.emptyList()); - } - - public BundleFile createNestedBundleFile(String nestedDir, BundleFile bundleFile, Generation generation, Collection filterPrefixes) { - // here we assume the content is a path offset into the base bundle file; create a NestedDirBundleFile - return wrapBundleFile(new NestedDirBundleFile(bundleFile, nestedDir, filterPrefixes), generation, false); - } - - public BundleFile wrapBundleFile(BundleFile bundleFile, Generation generation, boolean isBase) { - // try creating a wrapper bundlefile out of it. - List wrapperFactories = getConfiguration().getHookRegistry().getBundleFileWrapperFactoryHooks(); - BundleFileWrapperChain wrapped = wrapperFactories.isEmpty() ? null : new BundleFileWrapperChain(bundleFile, null); - for (BundleFileWrapperFactoryHook wrapperFactory : wrapperFactories) { - BundleFileWrapper wrapperBundle = wrapperFactory.wrapBundleFile(bundleFile, generation, isBase); - if (wrapperBundle != null && wrapperBundle != bundleFile) - bundleFile = wrapped = new BundleFileWrapperChain(wrapperBundle, wrapped); - } - - return bundleFile; - } - - public void compact() { - if (!osgiLocation.isReadOnly()) { - compact(childRoot); - } - } - - private void compact(File directory) { - if (getConfiguration().getDebug().DEBUG_STORAGE) - Debug.println("compact(" + directory.getPath() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - String list[] = directory.list(); - if (list == null) - return; - - int len = list.length; - for (int i = 0; i < len; i++) { - if (BUNDLE_DATA_DIR.equals(list[i])) - continue; /* do not examine the bundles data dir. */ - File target = new File(directory, list[i]); - // if the file is a directory - if (!target.isDirectory()) - continue; - File delete = new File(target, DELETE_FLAG); - // and the directory is marked for delete - if (delete.exists()) { - try { - deleteFlaggedDirectory(target); - } catch (IOException e) { - if (getConfiguration().getDebug().DEBUG_STORAGE) { - Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } else { - compact(target); /* descend into directory */ - } - } - } - - void delete(final File delete) throws IOException { - if (System.getSecurityManager() == null) { - deleteFlaggedDirectory(delete); - } else { - try { - AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - deleteFlaggedDirectory(delete); - return null; - }); - } catch (PrivilegedActionException e) { - if (e.getException() instanceof IOException) - throw (IOException) e.getException(); - throw (RuntimeException) e.getException(); - } - } - } - - private void deleteFlaggedDirectory(File delete) throws IOException { - if (!StorageUtil.rm(delete, getConfiguration().getDebug().DEBUG_STORAGE)) { - ensureDeleteFlagFileExists(delete.toPath()); - } - } - - public void save() throws IOException { - if (isReadOnly()) { - return; - } - if (System.getSecurityManager() == null) { - save0(); - } else { - try { - AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - save0(); - return null; - }); - } catch (PrivilegedActionException e) { - if (e.getException() instanceof IOException) - throw (IOException) e.getException(); - throw (RuntimeException) e.getException(); - } - } - } - - void save0() throws IOException { - StorageManager childStorageManager = null; - ManagedOutputStream mos = null; - DataOutputStream out = null; - boolean success = false; - moduleDatabase.readLock(); - synchronized (this.saveMonitor) { - try { - if (lastSavedTimestamp == moduleDatabase.getTimestamp()) - return; - childStorageManager = getChildStorageManager(); - mos = childStorageManager.getOutputStream(FRAMEWORK_INFO); - out = new DataOutputStream(new BufferedOutputStream(mos)); - saveGenerations(out); - savePermissionData(out); - moduleDatabase.store(out, true); - lastSavedTimestamp = moduleDatabase.getTimestamp(); - success = true; - } finally { - moduleDatabase.readUnlock(); - if (!success) { - if (mos != null) { - mos.abort(); - } - } - if (out != null) { - try { - out.close(); - } catch (IOException e) { - // tried our best - } - } - if (childStorageManager != null) { - childStorageManager.close(); - } - } - } - } - - private void savePermissionData(DataOutputStream out) throws IOException { - permissionData.savePermissionData(out); - } - - private void saveGenerations(DataOutputStream out) throws IOException { - List modules = moduleContainer.getModules(); - List generations = new ArrayList<>(); - for (Module module : modules) { - ModuleRevision revision = module.getCurrentRevision(); - if (revision != null) { - Generation generation = (Generation) revision.getRevisionInfo(); - if (generation != null) { - generations.add(generation); - } - } - } - out.writeInt(VERSION); - - out.writeUTF(runtimeVersion.toString()); - - Version curFrameworkVersion = findFrameworkVersion(); - out.writeUTF(curFrameworkVersion == null ? Version.emptyVersion.toString() : curFrameworkVersion.toString()); - - saveLongString(out, getSystemExtraCapabilities()); - saveLongString(out, getSystemExtraPackages()); - - out.writeInt(cachedHeaderKeys.size()); - for (String headerKey : cachedHeaderKeys) { - out.writeUTF(headerKey); - } - - out.writeInt(generations.size()); - for (Generation generation : generations) { - BundleInfo bundleInfo = generation.getBundleInfo(); - out.writeLong(bundleInfo.getBundleId()); - out.writeUTF(bundleInfo.getLocation()); - out.writeLong(bundleInfo.getNextGenerationId()); - out.writeLong(generation.getGenerationId()); - out.writeBoolean(generation.isDirectory()); - Type contentType = generation.getContentType(); - out.writeInt(contentType.ordinal()); - out.writeBoolean(generation.hasPackageInfo()); - if (bundleInfo.getBundleId() == 0 || contentType == Type.CONNECT) { - // just write empty string for system bundle content and connect content in this case - out.writeUTF(""); //$NON-NLS-1$ - } else { - if (contentType == Type.REFERENCE) { - // make reference installs relative to the install path - out.writeUTF(new FilePath(installPath).makeRelative(new FilePath(generation.getContent().getAbsolutePath()))); - } else { - // make normal installs relative to the storage area - out.writeUTF(Storage.getBundleFilePath(bundleInfo.getBundleId(), generation.getGenerationId())); - } - } - out.writeLong(generation.getLastModified()); - - Dictionary headers = generation.getHeaders(); - for (String headerKey : cachedHeaderKeys) { - String value = headers.get(headerKey); - if (value != null) { - out.writeUTF(value); - } else { - out.writeUTF(NUL); - } - } - - out.writeBoolean(generation.isMRJar()); - } - - saveStorageHookData(out, generations); - } - - private void saveLongString(DataOutputStream out, String value) throws IOException { - if (value == null) { - out.writeInt(0); - } else { - // don't use out.writeUTF because it has a hard string limit - byte[] data = value.getBytes(StandardCharsets.UTF_8); - out.writeInt(data.length); - out.write(data); - } - } - - private String readLongString(DataInputStream in) throws IOException { - int length = in.readInt(); - byte[] data = new byte[length]; - in.readFully(data); - return new String(data, StandardCharsets.UTF_8); - } - - private void saveStorageHookData(DataOutputStream out, List generations) throws IOException { - List> factories = getConfiguration().getHookRegistry().getStorageHookFactories(); - out.writeInt(factories.size()); - for (StorageHookFactory factory : factories) { - out.writeUTF(factory.getKey()); - out.writeInt(factory.getStorageVersion()); - - // create a temporary in memory stream so we can figure out the length - ByteArrayOutputStream tempBytes = new ByteArrayOutputStream(); - try (DataOutputStream temp = new DataOutputStream(tempBytes)) { - Object saveContext = factory.createSaveContext(); - for (Generation generation : generations) { - if (generation.getBundleInfo().getBundleId() == 0) { - continue; // ignore system bundle - } - @SuppressWarnings({"rawtypes", "unchecked"}) - StorageHook hook = generation.getStorageHook((Class) factory.getClass()); - if (hook != null) { - hook.save(saveContext, temp); - } - } - } - out.writeInt(tempBytes.size()); - out.write(tempBytes.toByteArray()); - } - } - - private Map loadGenerations(DataInputStream in, String[] cachedInfo) throws IOException { - if (in == null) { - return new HashMap<>(0); - } - int version = in.readInt(); - if (version > VERSION || version < LOWEST_VERSION_SUPPORTED) { - throw new IllegalArgumentException("Found persistent version \"" + version + "\" expecting \"" + VERSION + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - Version savedRuntimeVersion = (version >= MR_JAR_VERSION) ? Version.parseVersion(in.readUTF()) : null; - if (savedRuntimeVersion == null || !savedRuntimeVersion.equals(runtimeVersion)) { - refreshMRBundles.set(true); - } - - cachedInfo[0] = (version >= CACHED_SYSTEM_CAPS_VERION) ? in.readUTF() : null; - cachedInfo[1] = (version >= CACHED_SYSTEM_CAPS_VERION) ? readLongString(in) : null; - cachedInfo[2] = (version >= CACHED_SYSTEM_CAPS_VERION) ? readLongString(in) : null; - - int numCachedHeaders = in.readInt(); - List storedCachedHeaderKeys = new ArrayList<>(numCachedHeaders); - for (int i = 0; i < numCachedHeaders; i++) { - storedCachedHeaderKeys.add(ObjectPool.intern(in.readUTF())); - } - - int numInfos = in.readInt(); - Map result = new HashMap<>(numInfos); - List generations = new ArrayList<>(numInfos); - Type[] contentTypes = Type.values(); - for (int i = 0; i < numInfos; i++) { - long infoId = in.readLong(); - String infoLocation = ObjectPool.intern(in.readUTF()); - long nextGenId = in.readLong(); - long generationId = in.readLong(); - boolean isDirectory = in.readBoolean(); - - Type contentType = Type.DEFAULT; - if (version >= CONTENT_TYPE_VERSION) { - contentType = contentTypes[in.readInt()]; - } else { - if (in.readBoolean()) { - contentType = Type.REFERENCE; - } - } - - boolean hasPackageInfo = in.readBoolean(); - String contentPath = in.readUTF(); - long lastModified = in.readLong(); - - Map cachedHeaders = new HashMap<>(storedCachedHeaderKeys.size()); - for (String headerKey : storedCachedHeaderKeys) { - String value = in.readUTF(); - if (NUL.equals(value)) { - value = null; - } else { - value = ObjectPool.intern(value); - } - cachedHeaders.put(headerKey, value); - } - boolean isMRJar = (version >= MR_JAR_VERSION) ? in.readBoolean() : false; - - File content = null; - if (contentType != Type.CONNECT) { - if (infoId == 0) { - content = getSystemContent(); - isDirectory = content != null ? content.isDirectory() : false; - // Note that we do not do any checking for absolute paths with - // the system bundle. We always take the content as discovered - // by getSystemContent() - } else { - content = new File(contentPath); - if (!content.isAbsolute()) { - // make sure it has the absolute location instead - switch (contentType) { - case REFERENCE: - // reference installs are relative to the installPath - content = new File(installPath, contentPath); - break; - case DEFAULT: - // normal installs are relative to the storage area - content = getFile(contentPath, true); - break; - default: - throw new IllegalArgumentException("Unknown type: " + contentType); //$NON-NLS-1$ - } - } - } - } - BundleInfo info = new BundleInfo(this, infoId, infoLocation, nextGenId); - Generation generation = info.restoreGeneration(generationId, content, isDirectory, contentType, hasPackageInfo, cachedHeaders, lastModified, isMRJar); - result.put(infoId, generation); - generations.add(generation); - } - - connectPersistentBundles(generations); - loadStorageHookData(generations, in); - return result; - } - - private void connectPersistentBundles(List generations) { - generations.forEach(g -> { - try { - if (g.getContentType() == Type.CONNECT) { - equinoxContainer.getConnectModules().connect(g.getBundleInfo().getLocation()); - } - } catch (IllegalStateException e) { - if (!(e.getCause() instanceof BundleException)) { - throw e; - } - } - }); - } - - private void loadStorageHookData(List generations, DataInputStream in) throws IOException { - List> factories = new ArrayList<>(getConfiguration().getHookRegistry().getStorageHookFactories()); - Map>> hookMap = new HashMap<>(); - int numFactories = in.readInt(); - for (int i = 0; i < numFactories; i++) { - String factoryName = in.readUTF(); - int version = in.readInt(); - StorageHookFactory> factory = null; - for (Iterator> iFactories = factories.iterator(); iFactories.hasNext();) { - @SuppressWarnings("unchecked") - StorageHookFactory> next = (StorageHookFactory>) iFactories.next(); - if (next.getKey().equals(factoryName)) { - factory = next; - iFactories.remove(); - break; - } - } - int dataSize = in.readInt(); - byte[] bytes = new byte[dataSize]; - in.readFully(bytes); - if (factory != null) { - try (DataInputStream temp = new DataInputStream(new ByteArrayInputStream(bytes))) { - if (factory.isCompatibleWith(version)) { - Object loadContext = factory.createLoadContext(version); - for (Generation generation : generations) { - if (generation.getBundleInfo().getBundleId() == 0) { - continue; // ignore system bundle - } - StorageHook hook = factory.createStorageHookAndValidateFactoryClass(generation); - if (hook != null) { - hook.load(loadContext, temp); - getHooks(hookMap, generation).add(hook); - } - } - } else { - // recover by reinitializing the hook - for (Generation generation : generations) { - if (generation.getBundleInfo().getBundleId() == 0) { - continue; // ignore system bundle - } - StorageHook hook = factory.createStorageHookAndValidateFactoryClass(generation); - if (hook != null) { - hook.initialize(generation.getHeaders()); - getHooks(hookMap, generation).add(hook); - } - } - } - } catch (BundleException e) { - throw new IOException(e); - } - } - } - // now we need to recover for any hooks that are left - for (StorageHookFactory storageHookFactory : factories) { - @SuppressWarnings("unchecked") - StorageHookFactory> next = (StorageHookFactory>) storageHookFactory; - // recover by reinitializing the hook - for (Generation generation : generations) { - if (generation.getBundleInfo().getBundleId() == 0) { - continue; // ignore system bundle - } - StorageHook hook = next.createStorageHookAndValidateFactoryClass(generation); - if (hook != null) { - try { - hook.initialize(generation.getHeaders()); - getHooks(hookMap, generation).add(hook); - } catch (BundleException e) { - throw new IOException(e); - } - } - } - } - // now set the hooks to the generations - for (Generation generation : generations) { - generation.setStorageHooks(Collections.unmodifiableList(getHooks(hookMap, generation)), false); - } - } - - private static List> getHooks(Map>> hookMap, Generation generation) { - List> result = hookMap.get(generation); - if (result == null) { - result = new ArrayList<>(); - hookMap.put(generation, result); - } - return result; - } - - private File getSystemContent() { - String frameworkValue = equinoxContainer.getConfiguration().getConfiguration(EquinoxConfiguration.PROP_FRAMEWORK); - if (frameworkValue == null || !frameworkValue.startsWith("file:")) { //$NON-NLS-1$ - return null; - } - // TODO assumes the location is a file URL - File result = new File(frameworkValue.substring(5)).getAbsoluteFile(); - if (!result.exists()) { - throw new IllegalStateException("Configured framework location does not exist: " + result.getAbsolutePath()); //$NON-NLS-1$ - } - return result; - } - - @SuppressWarnings("deprecation") - private void loadVMProfile(Generation systemGeneration) { - EquinoxConfiguration equinoxConfig = equinoxContainer.getConfiguration(); - Properties profileProps = findVMProfile(systemGeneration); - String systemExports = equinoxConfig.getConfiguration(Constants.FRAMEWORK_SYSTEMPACKAGES); - // set the system exports property using the vm profile; only if the property is not already set - if (systemExports == null) { - systemExports = profileProps.getProperty(Constants.FRAMEWORK_SYSTEMPACKAGES); - if (systemExports != null) - equinoxConfig.setConfiguration(Constants.FRAMEWORK_SYSTEMPACKAGES, systemExports); - } - - // set the org.osgi.framework.bootdelegation property according to the java profile - String type = equinoxConfig.getConfiguration(EquinoxConfiguration.PROP_OSGI_JAVA_PROFILE_BOOTDELEGATION); // a null value means ignore - String profileBootDelegation = profileProps.getProperty(Constants.FRAMEWORK_BOOTDELEGATION); - if (EquinoxConfiguration.PROP_OSGI_BOOTDELEGATION_OVERRIDE.equals(type)) { - if (profileBootDelegation == null) - equinoxConfig.clearConfiguration(Constants.FRAMEWORK_BOOTDELEGATION); // override with a null value - else - equinoxConfig.setConfiguration(Constants.FRAMEWORK_BOOTDELEGATION, profileBootDelegation); // override with the profile value - } else if (EquinoxConfiguration.PROP_OSGI_BOOTDELEGATION_NONE.equals(type)) - equinoxConfig.clearConfiguration(Constants.FRAMEWORK_BOOTDELEGATION); // remove the bootdelegation property in case it was set - // set the org.osgi.framework.executionenvironment property according to the java profile - if (equinoxConfig.getConfiguration(Constants.FRAMEWORK_EXECUTIONENVIRONMENT) == null) { - // get the ee from the java profile; if no ee is defined then try the java profile name - String ee = profileProps.getProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, profileProps.getProperty(EquinoxConfiguration.PROP_OSGI_JAVA_PROFILE_NAME)); - if (ee != null) - equinoxConfig.setConfiguration(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, ee); - } - // set the org.osgi.framework.system.capabilities property according to the java profile - if (equinoxConfig.getConfiguration(Constants.FRAMEWORK_SYSTEMCAPABILITIES) == null) { - String systemCapabilities = profileProps.getProperty(Constants.FRAMEWORK_SYSTEMCAPABILITIES); - if (systemCapabilities != null) - equinoxConfig.setConfiguration(Constants.FRAMEWORK_SYSTEMCAPABILITIES, systemCapabilities); - } - } - - private Properties findVMProfile(Generation systemGeneration) { - Properties result = readConfiguredJavaProfile(systemGeneration); - String vmProfile = null; - try { - if (result != null) { - return result; - } - - if (Version.valueOf("9").compareTo(runtimeVersion) <= 0) { //$NON-NLS-1$ - result = calculateVMProfile(runtimeVersion); - if (result != null) { - return result; - } - // could not calculate; fall back to reading profile files - } - - String embeddedProfileName = "-"; //$NON-NLS-1$ - // If javaSE 1.8 then check for release file for profile name. - if (runtimeVersion != null && Version.valueOf("1.8").compareTo(runtimeVersion) <= 0) { //$NON-NLS-1$ - String javaHome = System.getProperty("java.home"); //$NON-NLS-1$ - if (javaHome != null) { - File release = new File(javaHome, "release"); //$NON-NLS-1$ - if (release.exists()) { - Properties releaseProps = new Properties(); - try (InputStream releaseStream = new FileInputStream(release)) { - releaseProps.load(releaseStream); - String releaseName = releaseProps.getProperty("JAVA_PROFILE"); //$NON-NLS-1$ - if (releaseName != null) { - // make sure to remove extra quotes - releaseName = releaseName.replaceAll("^\\s*\"?|\"?\\s*$", ""); //$NON-NLS-1$ //$NON-NLS-2$ - embeddedProfileName = "_" + releaseName + "-"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } catch (IOException e) { - // ignore - } - } - } - } - - result = new Properties(); - vmProfile = JAVASE + embeddedProfileName + javaSpecVersion; - try (InputStream profileIn = createProfileStream(systemGeneration, vmProfile, embeddedProfileName)) { - if (profileIn != null) { - result.load(profileIn); - } - } catch (IOException e) { - // ignore - // TODO consider logging ... - } - } finally { - // set the profile name if it does not provide one - if (result != null && result.getProperty(EquinoxConfiguration.PROP_OSGI_JAVA_PROFILE_NAME) == null) { - if (vmProfile != null) { - result.put(EquinoxConfiguration.PROP_OSGI_JAVA_PROFILE_NAME, vmProfile.replace('_', '/')); - } else { - // last resort; default to the absolute minimum profile name for the framework - result.put(EquinoxConfiguration.PROP_OSGI_JAVA_PROFILE_NAME, "JavaSE-1.7"); //$NON-NLS-1$ - } - } - } - return result; - } - - private InputStream createProfileStream(Generation systemGeneration, String vmProfile, - String embeddedProfileName) { - InputStream profileIn = null; - if (vmProfile != null) { - // look for a profile in the system bundle based on the vm profile - String javaProfile = vmProfile + PROFILE_EXT; - profileIn = findInSystemBundle(systemGeneration, javaProfile); - if (profileIn == null) { - profileIn = getNextBestProfile(systemGeneration, JAVASE, runtimeVersion, embeddedProfileName); - } - } - if (profileIn == null) { - // the profile url is still null then use the min profile the framework can use - profileIn = findInSystemBundle(systemGeneration, "JavaSE-1.8.profile"); //$NON-NLS-1$ - } - return profileIn; - } - - private Properties readConfiguredJavaProfile(Generation systemGeneration) { - // check for the java profile property for a url - String propJavaProfile = equinoxContainer.getConfiguration().getConfiguration(EquinoxConfiguration.PROP_OSGI_JAVA_PROFILE); - if (propJavaProfile != null) { - try (InputStream profileIn = createPropStream(systemGeneration, propJavaProfile)){ - if (profileIn != null) { - Properties result = new Properties(); - result.load(profileIn); - return result; - } - } catch (IOException e) { - // consider logging - } - } - return null; - } - - private InputStream createPropStream(Generation systemGeneration, String propJavaProfile) { - try { - // we assume a URL - return new URL(propJavaProfile).openStream(); - } catch (IOException e) { - // try using a relative path in the system bundle - return findInSystemBundle(systemGeneration, propJavaProfile); - } - } - - @SuppressWarnings("deprecation") - private Properties calculateVMProfile(Version javaVersion) { - String systemPackages = calculateVMPackages(); - if (systemPackages == null) { - return null; - } - String executionEnvs = calculateVMExecutionEnvs(javaVersion); - String eeCapabilities = calculateEECapabilities(javaVersion); - - Properties result = new Properties(); - result.put(Constants.FRAMEWORK_SYSTEMPACKAGES, systemPackages); - result.put(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, executionEnvs); - result.put(Constants.FRAMEWORK_SYSTEMCAPABILITIES, eeCapabilities); - return result; - } - - private String calculateVMExecutionEnvs(Version javaVersion) { - StringBuilder result = new StringBuilder("OSGi/Minimum-1.0, OSGi/Minimum-1.1, OSGi/Minimum-1.2, JavaSE/compact1-1.8, JavaSE/compact2-1.8, JavaSE/compact3-1.8, JRE-1.1, J2SE-1.2, J2SE-1.3, J2SE-1.4, J2SE-1.5, JavaSE-1.6, JavaSE-1.7, JavaSE-1.8"); //$NON-NLS-1$ - Version v = new Version(9, 0, 0); - while (v.compareTo(javaVersion) <= 0) { - result.append(',').append(' ').append(JAVASE).append('-').append(v.getMajor()); - if (v.getMinor() > 0) { - result.append('.').append(v.getMinor()); - } - if (v.getMajor() == javaVersion.getMajor()) { - v = new Version(v.getMajor(), v.getMinor() + 1, 0); - } else { - v = new Version(v.getMajor() + 1, 0, 0); - } - } - return result.toString(); - } - - private String calculateEECapabilities(Version javaVersion) { - Version v = new Version(9, 0, 0); - StringBuilder versionsBulder = new StringBuilder(); - while (v.compareTo(javaVersion) <= 0) { - versionsBulder.append(',').append(' ').append(v.getMajor()).append('.').append(v.getMinor()); - if (v.getMajor() == javaVersion.getMajor()) { - v = new Version(v.getMajor(), v.getMinor() + 1, 0); - } else { - v = new Version(v.getMajor() + 1, 0, 0); - } - } - String versionsList = versionsBulder.toString(); - - StringBuilder result = new StringBuilder("osgi.ee; osgi.ee=\"OSGi/Minimum\"; version:List=\"1.0, 1.1, 1.2\", osgi.ee; osgi.ee=\"JRE\"; version:List=\"1.0, 1.1\", osgi.ee; osgi.ee=\"JavaSE\"; version:List=\"1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8"); //$NON-NLS-1$ - result.append(versionsList).append("\""); //$NON-NLS-1$ - result.append(",osgi.ee; osgi.ee=\"JavaSE/compact1\"; version:List=\"1.8"); //$NON-NLS-1$ - result.append(versionsList).append("\""); //$NON-NLS-1$ - result.append(",osgi.ee; osgi.ee=\"JavaSE/compact2\"; version:List=\"1.8"); //$NON-NLS-1$ - result.append(versionsList).append("\""); //$NON-NLS-1$ - result.append(",osgi.ee; osgi.ee=\"JavaSE/compact3\"; version:List=\"1.8"); //$NON-NLS-1$ - result.append(versionsList).append("\""); //$NON-NLS-1$ - - return result.toString(); - } - - @SuppressWarnings("unchecked") - private String calculateVMPackages() { - try { - List packages = new ArrayList<>(); - Method classGetModule = Class.class.getMethod("getModule"); //$NON-NLS-1$ - Object thisModule = classGetModule.invoke(getClass()); - Class moduleLayerClass = Class.forName("java.lang.ModuleLayer"); //$NON-NLS-1$ - Method boot = moduleLayerClass.getMethod("boot"); //$NON-NLS-1$ - Method modules = moduleLayerClass.getMethod("modules"); //$NON-NLS-1$ - Class moduleClass = Class.forName("java.lang.Module"); //$NON-NLS-1$ - Method getDescriptor = moduleClass.getMethod("getDescriptor"); //$NON-NLS-1$ - Class moduleDescriptorClass = Class.forName("java.lang.module.ModuleDescriptor"); //$NON-NLS-1$ - Method exports = moduleDescriptorClass.getMethod("exports"); //$NON-NLS-1$ - Method isAutomatic = moduleDescriptorClass.getMethod("isAutomatic"); //$NON-NLS-1$ - Method packagesMethod = moduleDescriptorClass.getMethod("packages"); //$NON-NLS-1$ - Class exportsClass = Class.forName("java.lang.module.ModuleDescriptor$Exports"); //$NON-NLS-1$ - Method isQualified = exportsClass.getMethod("isQualified"); //$NON-NLS-1$ - Method source = exportsClass.getMethod("source"); //$NON-NLS-1$ - - Object bootLayer = boot.invoke(null); - Set bootModules = (Set) modules.invoke(bootLayer); - for (Object m : bootModules) { - if (m.equals(thisModule)) { - // Do not calculate the exports from the framework module. - // This is to handle the case where the framework is on the module path - // to avoid double exports from the system.bundles - continue; - } - Object descriptor = getDescriptor.invoke(m); - if ((Boolean) isAutomatic.invoke(descriptor)) { - /* - * Automatic modules are supposed to export all their packages. - * However, java.lang.module.ModuleDescriptor::exports returns an empty set for them. - * Add all their packages (as returned by java.lang.module.ModuleDescriptor::packages) - * to the list of VM supplied packages. - */ - packages.addAll((Set) packagesMethod.invoke(descriptor)); - } else { - for (Object export : (Set) exports.invoke(descriptor)) { - String pkg = (String) source.invoke(export); - if (!((Boolean) isQualified.invoke(export))) { - packages.add(pkg); - } - } - } - } - Collections.sort(packages); - StringBuilder result = new StringBuilder(); - for (String pkg : packages) { - if (result.length() != 0) { - result.append(',').append(' '); - } - result.append(pkg); - } - return result.toString(); - } catch (Exception e) { - equinoxContainer.getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, "Error determining system packages.", e); //$NON-NLS-1$ - return null; - } - } - - private InputStream getNextBestProfile(Generation systemGeneration, String javaEdition, Version javaVersion, String embeddedProfileName) { - if (javaVersion == null || javaEdition != JAVASE) - return null; // we cannot automatically choose the next best profile unless this is a JavaSE vm - InputStream bestProfile = findNextBestProfile(systemGeneration, javaEdition, javaVersion, embeddedProfileName); - if (bestProfile == null && !"-".equals(embeddedProfileName)) { //$NON-NLS-1$ - // Just use the base javaEdition name without the profile name as backup - return getNextBestProfile(systemGeneration, javaEdition, javaVersion, "-"); //$NON-NLS-1$ - } - return bestProfile; - } - - private InputStream findNextBestProfile(Generation systemGeneration, String javaEdition, Version javaVersion, String embeddedProfileName) { - InputStream result = null; - int major = javaVersion.getMajor(); - int minor = javaVersion.getMinor(); - do { - // If minor is zero then it is not included in the name - String profileResourceName = javaEdition + embeddedProfileName + major + ((minor > 0) ? "." + minor : "") + PROFILE_EXT; //$NON-NLS-1$ //$NON-NLS-2$ - result = findInSystemBundle(systemGeneration, profileResourceName); - if (minor > 0) { - minor -= 1; - } else if (major > 9) { - major -= 1; - } else if (major <= 9 && major > 1) { - minor = 8; - major = 1; - } else { - // we have reached the end of our search; return the existing result; - return result; - } - } while (result == null && minor >= 0); - return result; - } - - private InputStream findInSystemBundle(Generation systemGeneration, String entry) { - BundleFile systemContent = systemGeneration.getBundleFile(); - BundleEntry systemEntry = systemContent != null ? systemContent.getEntry(entry) : null; - InputStream result = null; - if (systemEntry != null) { - try { - result = systemEntry.getInputStream(); - } catch (IOException e) { - // Do nothing - } - } - if (result == null) { - // Check the ClassLoader in case we're launched off the Java boot classpath - ClassLoader loader = getClass().getClassLoader(); - result = loader == null ? ClassLoader.getSystemResourceAsStream(entry) : loader.getResourceAsStream(entry); - } - return result; - } - - public static Enumeration findEntries(List generations, String path, String filePattern, int options) { - List bundleFiles = new ArrayList<>(generations.size()); - for (Generation generation : generations) - bundleFiles.add(generation.getBundleFile()); - // search all the bundle files - List pathList = listEntryPaths(bundleFiles, path, filePattern, options); - // return null if no entries found - if (pathList.size() == 0) - return null; - // create an enumeration to enumerate the pathList (generations must not change) - Stream entries = pathList.stream().flatMap(p -> generations.stream().map(g -> g.getEntry(p))) - .filter(Objects::nonNull); - return InternalUtils.asEnumeration(entries.iterator()); - } - - /** - * Returns the names of resources available from a list of bundle files. - * No duplicate resource names are returned, each name is unique. - * @param bundleFiles the list of bundle files to search in - * @param path The path name in which to look. - * @param filePattern The file name pattern for selecting resource names in - * the specified path. - * @param options The options for listing resource names. - * @return a list of resource names. If no resources are found then - * the empty list is returned. - * @see BundleWiring#listResources(String, String, int) - */ - public static List listEntryPaths(List bundleFiles, String path, String filePattern, int options) { - // Use LinkedHashSet for optimized performance of contains() plus - // ordering guarantees. - LinkedHashSet pathList = new LinkedHashSet<>(); - Filter patternFilter = null; - Hashtable patternProps = null; - if (filePattern != null) { - // Optimization: If the file pattern does not include a wildcard or escape char then it must represent a single file. - // Avoid pattern matching and use BundleFile.getEntry() if recursion was not requested. - if ((options & BundleWiring.FINDENTRIES_RECURSE) == 0 && filePattern.indexOf('*') == -1 && filePattern.indexOf('\\') == -1) { - if (path.length() == 0) - path = filePattern; - else - path += path.charAt(path.length() - 1) == '/' ? filePattern : '/' + filePattern; - for (BundleFile bundleFile : bundleFiles) { - if (bundleFile.getEntry(path) != null && !pathList.contains(path)) - pathList.add(path); - } - return new ArrayList<>(pathList); - } - // For when the file pattern includes a wildcard. - try { - // create a file pattern filter with 'filename' as the key - patternFilter = FilterImpl.newInstance("(filename=" + sanitizeFilterInput(filePattern) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - // create a single hashtable to be shared during the recursive search - patternProps = new Hashtable<>(2); - } catch (InvalidSyntaxException e) { - // TODO something unexpected happened; log error and return nothing - // Bundle b = context == null ? null : context.getBundle(); - // eventPublisher.publishFrameworkEvent(FrameworkEvent.ERROR, b, e); - return new ArrayList<>(pathList); - } - } - // find the entry paths for the datas - for (BundleFile bundleFile : bundleFiles) { - listEntryPaths(bundleFile, path, patternFilter, patternProps, options, pathList); - } - return new ArrayList<>(pathList); - } - - public static String sanitizeFilterInput(String filePattern) throws InvalidSyntaxException { - StringBuilder buffer = null; - boolean foundEscape = false; - for (int i = 0; i < filePattern.length(); i++) { - char c = filePattern.charAt(i); - switch (c) { - case '\\' : - // we either used the escape found or found a new escape. - foundEscape = foundEscape ? false : true; - if (buffer != null) - buffer.append(c); - break; - case '(' : - case ')' : - if (!foundEscape) { - if (buffer == null) { - buffer = new StringBuilder(filePattern.length() + 16); - buffer.append(filePattern.substring(0, i)); - } - // must escape with '\' - buffer.append('\\'); - } else { - foundEscape = false; // used the escape found - } - if (buffer != null) - buffer.append(c); - break; - default : - // if we found an escape it has been used - foundEscape = false; - if (buffer != null) - buffer.append(c); - break; - } - } - if (foundEscape) - throw new InvalidSyntaxException("Trailing escape characters must be escaped.", filePattern); //$NON-NLS-1$ - return buffer == null ? filePattern : buffer.toString(); - } - - // Use LinkedHashSet for optimized performance of contains() plus ordering - // guarantees. - private static LinkedHashSet listEntryPaths(BundleFile bundleFile, String path, Filter patternFilter, Hashtable patternProps, int options, LinkedHashSet pathList) { - if (pathList == null) - pathList = new LinkedHashSet<>(); - boolean recurse = (options & BundleWiring.FINDENTRIES_RECURSE) != 0; - Enumeration entryPaths = bundleFile.getEntryPaths(path, recurse); - if (entryPaths == null) - return pathList; - while (entryPaths.hasMoreElements()) { - String entry = entryPaths.nextElement(); - int lastSlash = entry.lastIndexOf('/'); - if (patternProps != null) { - int secondToLastSlash = entry.lastIndexOf('/', lastSlash - 1); - int fileStart; - int fileEnd = entry.length(); - if (lastSlash < 0) - fileStart = 0; - else if (lastSlash != entry.length() - 1) - fileStart = lastSlash + 1; - else { - fileEnd = lastSlash; // leave the lastSlash out - if (secondToLastSlash < 0) - fileStart = 0; - else - fileStart = secondToLastSlash + 1; - } - String fileName = entry.substring(fileStart, fileEnd); - // set the filename to the current entry - patternProps.put("filename", fileName); //$NON-NLS-1$ - } - // prevent duplicates and match on the patternFilter - if (!pathList.contains(entry) && (patternFilter == null || patternFilter.matchCase(patternProps))) - pathList.add(entry); - } - return pathList; - } - - public String copyToTempLibrary(Generation generation, String absolutePath) { - File libTempDir = new File(childRoot, LIB_TEMP); - // we assume the absolutePath is a File path - File realLib = new File(absolutePath); - String libName = realLib.getName(); - // find a temp dir for the bundle data and the library; - File bundleTempDir = null; - File libTempFile = null; - // We need a somewhat predictable temp dir for the libraries of a given bundle; - // This is not strictly necessary but it does help scenarios where one native library loads another native library without using java. - // On some OSes this causes issues because the second library is cannot be found. - // This has been worked around by the bundles loading the libraries in a particular order (and setting some LIB_PATH env). - // The one catch is that the libraries need to be in the same directory and they must use their original lib names. - // - // This bit of code attempts to do that by using the bundle ID as an ID for the temp dir along with an incrementing ID - // in cases where the temp dir may already exist. - long bundleID = generation.getBundleInfo().getBundleId(); - for (int i = 0; i < Integer.MAX_VALUE; i++) { - bundleTempDir = new File(libTempDir, bundleID + "_" + i); //$NON-NLS-1$ - libTempFile = new File(bundleTempDir, libName); - if (bundleTempDir.exists()) { - if (libTempFile.exists()) - continue; // to to next temp file - break; - } - break; - } - if (!bundleTempDir.isDirectory()) { - bundleTempDir.mkdirs(); - bundleTempDir.deleteOnExit(); - // This is just a safeguard incase the VM is terminated unexpectantly, it also looks like deleteOnExit cannot really work because - // the VM likely will still have a lock on the lib file at the time of VM exit. - try { // need to create a delete flag to force removal the temp libraries - ensureDeleteFlagFileExists(libTempDir.toPath()); - } catch (IOException e) { - // do nothing; that would mean we did not make the temp dir successfully - } - } - // copy the library file - try { - StorageUtil.copy(realLib, libTempFile); - // set permissions if needed - setPermissions(libTempFile); - libTempFile.deleteOnExit(); // this probably will not work because the VM will probably have the lib locked at exit - // return the temporary path - return libTempFile.getAbsolutePath(); - } catch (IOException e) { - equinoxContainer.getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, e.getMessage(), e); - return null; - } - } - - private static void ensureDeleteFlagFileExists(Path directory) throws IOException { - Path deleteFlag = directory.resolve(DELETE_FLAG); - if (!Files.exists(deleteFlag) ) { - Files.createFile(deleteFlag); - } - } - - public SecurityAdmin getSecurityAdmin() { - return securityAdmin; - } - - protected StorageManager getChildStorageManager() throws IOException { - String locking = getConfiguration().getConfiguration(LocationHelper.PROP_OSGI_LOCKING, LocationHelper.LOCKING_NIO); - StorageManager sManager = new StorageManager(childRoot, isReadOnly() ? LocationHelper.LOCKING_NONE : locking, isReadOnly()); - try { - sManager.open(!isReadOnly()); - } catch (IOException ex) { - if (getConfiguration().getDebug().DEBUG_STORAGE) { - Debug.println("Error reading framework.info: " + ex.getMessage()); //$NON-NLS-1$ - Debug.printStackTrace(ex); - } - String message = NLS.bind(Msg.ECLIPSE_STARTUP_FILEMANAGER_OPEN_ERROR, ex.getMessage()); - equinoxContainer.getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, message, ex); - getConfiguration().setProperty(EclipseStarter.PROP_EXITCODE, "15"); //$NON-NLS-1$ - String errorDialog = "" + Msg.ADAPTOR_STORAGE_INIT_FAILED_TITLE + "" + NLS.bind(Msg.ADAPTOR_STORAGE_INIT_FAILED_MSG, childRoot) + "\n" + ex.getMessage(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - getConfiguration().setProperty(EclipseStarter.PROP_EXITDATA, errorDialog); - throw ex; - } - return sManager; - } - - private InputStream getInfoInputStream() throws IOException { - StorageManager storageManager = getChildStorageManager(); - InputStream storageStream = null; - try { - storageStream = storageManager.getInputStream(FRAMEWORK_INFO); - } catch (IOException ex) { - if (getConfiguration().getDebug().DEBUG_STORAGE) { - Debug.println("Error reading framework.info: " + ex.getMessage()); //$NON-NLS-1$ - Debug.printStackTrace(ex); - } - } finally { - storageManager.close(); - } - if (storageStream == null && parentRoot != null) { - StorageManager parentStorageManager = null; - try { - parentStorageManager = new StorageManager(parentRoot, LocationHelper.LOCKING_NONE, true); - parentStorageManager.open(false); - storageStream = parentStorageManager.getInputStream(FRAMEWORK_INFO); - } catch (IOException e1) { - // That's ok we will regenerate the framework.info - } finally { - if (parentStorageManager != null) { - parentStorageManager.close(); - } - } - } - return storageStream; - } - - EquinoxContainer getEquinoxContainer() { - return equinoxContainer; - } -}