This is an automated email from the ASF dual-hosted git repository.

jlmonteiro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq.git


The following commit(s) were added to refs/heads/main by this push:
     new b31e80401e ActiveMQ on Java 25 (#1563)
b31e80401e is described below

commit b31e80401eb0ea15bb05e837db0a57c7a9e5e078
Author: Jean-Louis Monteiro <[email protected]>
AuthorDate: Wed Feb 11 12:29:15 2026 +0100

    ActiveMQ on Java 25 (#1563)
    
    * [#] NO-JIRA: Update Jenkinsfile to add JDK 25
    * [AMQ-9563] Add a SubjectShim to support JAAS API JDK 24+
    * [AMQ-9366] Add DataFileFactroy to KahaDBPersistenceAdapter and update 
test to remove SecurityManager
    
    Co-authored-by: Gurpartap Singh <gurpartap0306>
    
    * Add support for Java 25 in CI configurations
    
    Ensure builds under Java 21 will still work with Security Manager
    
    Only run required tests
    
    * AMQ-9825: ActiveMQ on Java 25
    Use Java 25 compatible version of Mockito
    Use Mockito Agent because self attaching an agent is now unavailable since 
Java 21+
    Split integration tests (MRJAR dependent) into a specific integration-test 
phase so they use the jar in the classpath
    Do not rely on activeByDefault because when other profiles activate, quick 
becomes inactive
    
    * Remove unused import for AccessController in SubjectShim.java because the 
API will be removed anyways
    
    * Do not use * imports
    
    * Attempt to build the MRJAR earlier so tests can use it and we can avoid 
the failsafe integration tests
    
    * Update Maven Enforcer Plugin to require Java 24+ for builds
    
    ---------
    
    Co-authored-by: Matt Pavlovich <[email protected]>
---
 .github/workflows/ci-nightly.yml                   |  4 +-
 .github/workflows/ci-quick.yml                     |  9 ++-
 Jenkinsfile                                        | 20 ++---
 activemq-broker/pom.xml                            | 39 +++++++++-
 .../org/apache/activemq/broker/BrokerService.java  |  2 +-
 .../apache/activemq/broker/jmx/AnnotatedMBean.java | 11 ++-
 .../apache/activemq/broker/jmx/SubjectShim.java    | 35 +++++++++
 .../apache/activemq/broker/jmx/SubjectShim.java    | 34 +++++++++
 .../apache/activemq/thread/TaskRunnerFactory.java  | 21 +++---
 .../store/kahadb/KahaDBPersistenceAdapter.java     |  5 ++
 .../activemq/store/kahadb/MessageDatabase.java     | 13 ++++
 .../store/kahadb/disk/journal/DataFileFactory.java | 23 ++++++
 .../disk/journal/DefaultDataFileFactory.java       | 27 +++++++
 .../store/kahadb/disk/journal/Journal.java         | 15 +++-
 .../activemq/store/kahadb/JournalArchiveTest.java  | 17 ++---
 .../kahadb/disk/journal/ErrorDataFileFactory.java  | 47 ++++++++++++
 activemq-unit-tests/pom.xml                        |  1 -
 .../FailoverDurableSubTransactionTest.java         |  6 ++
 pom.xml                                            | 88 ++++++++--------------
 19 files changed, 313 insertions(+), 104 deletions(-)

diff --git a/.github/workflows/ci-nightly.yml b/.github/workflows/ci-nightly.yml
index ec22a81b87..93da3ea4ad 100644
--- a/.github/workflows/ci-nightly.yml
+++ b/.github/workflows/ci-nightly.yml
@@ -57,7 +57,7 @@ jobs:
       fail-fast: false
       matrix:
         os: [ ubuntu-24.04, ubuntu-22.04, macos-26, macos-15, windows-2025, 
windows-2022 ]
-        java-version: [ 17, 21 ]
+        java-version: [ 17, 21, 25 ]
 
     runs-on: ${{ matrix.os }}
 
@@ -69,7 +69,7 @@ jobs:
           java-version: ${{ matrix.java-version }}
           distribution: temurin
       - name: Test
-        run: mvn -B -e -fae test
+        run: mvn -B -e -fae verify
       - name: Upload Test Results
         if: (!cancelled())
         uses: actions/upload-artifact@v4
diff --git a/.github/workflows/ci-quick.yml b/.github/workflows/ci-quick.yml
index 8671dcc0a6..e52a6fe89d 100644
--- a/.github/workflows/ci-quick.yml
+++ b/.github/workflows/ci-quick.yml
@@ -33,7 +33,7 @@ jobs:
     strategy:
       matrix:
         os: [ ubuntu-24.04, macos-26, windows-2025 ]
-        java-version: [ 17, 21 ]
+        java-version: [ 17, 21, 25 ]
 
     runs-on: ${{ matrix.os }}
 
@@ -64,10 +64,11 @@ jobs:
       - name: Set up JDK
         uses: actions/setup-java@v4
         with:
-          java-version: 17
+          # temporary using 25 until all tests pass on Java 25 - to be changed 
back to 17 for quick. 25 will run nightly only
+          java-version: 25
           distribution: temurin
       - name: Test
-        run: mvn -B -e -fae test
+        run: mvn -B -e -fae verify -Pactivemq.tests-quick
       - name: Upload Test Results
         if: (!cancelled())
         uses: actions/upload-artifact@v4
@@ -81,4 +82,4 @@ jobs:
           large_files: true
           report_individual_runs: true
           report_suite_logs: error
-          files: '**/target/surefire-reports/*.xml'
+          files: '**/target/surefire-reports/*.xml'
\ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
index 95fb388301..100a3b8c73 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -46,10 +46,9 @@ pipeline {
     }
 
     parameters {
-        choice(name: 'nodeLabel', choices: [ 'ubuntu', 's390x', 'arm', 
'Windows' ]) 
-        choice(name: 'jdkVersion', choices: ['jdk_17_latest', 'jdk_21_latest', 
'jdk_24_latest', 'jdk_17_latest_windows', 'jdk_21_latest_windows', 
'jdk_24_latest_windows'])
+        choice(name: 'nodeLabel', choices: [ 'ubuntu', 's390x', 'arm', 
'Windows' ])
+        choice(name: 'jdkVersion', choices: ['jdk_17_latest', 'jdk_21_latest', 
'jdk_25_latest', 'jdk_17_latest_windows', 'jdk_21_latest_windows', 
'jdk_25_latest_windows'])
         booleanParam(name: 'deployEnabled', defaultValue: false)
-        booleanParam(name: 'parallelTestsEnabled', defaultValue: true)
         booleanParam(name: 'sonarEnabled', defaultValue: false)
         booleanParam(name: 'testsEnabled', defaultValue: true)
     }
@@ -77,12 +76,12 @@ pipeline {
             }
         }
 
-        stage('Build JDK 24') {
+        stage('Build JDK 25') {
             tools {
-                jdk "jdk_24_latest"
+                jdk "jdk_25_latest"
             }
             steps {
-                echo 'Building JDK 24'
+                echo 'Building JDK 25'
                 sh 'java -version'
                 sh 'mvn -version'
                 sh 'mvn -U -B -e clean install -DskipTests'
@@ -137,13 +136,8 @@ pipeline {
                 // all tests is very very long (10 hours on Apache Jenkins)
                 // sh 'mvn -B -e test -pl activemq-unit-tests 
-Dactivemq.tests=all'
                 script {
-                    if (params.parallelTestsEnabled == 'true') {
-                        sh 'echo "Running parallel-tests ..."'
-                        sh 'mvn -B -e -fae -Pparallel-tests test 
-Dsurefire.rerunFailingTestsCount=3'
-                    } else {
-                        sh 'echo "Running tests ..."'
-                        sh 'mvn -B -e -fae test 
-Dsurefire.rerunFailingTestsCount=3'
-                    }
+                    sh 'echo "Running tests ..."'
+                    sh 'mvn -B -e -fae verify -Pactivemq.tests-quick'
                 }
             }
             post {
diff --git a/activemq-broker/pom.xml b/activemq-broker/pom.xml
index 5ded615389..14a6e0e487 100644
--- a/activemq-broker/pom.xml
+++ b/activemq-broker/pom.xml
@@ -209,6 +209,16 @@
       <plugin>
         <artifactId>maven-jar-plugin</artifactId>
         <executions>
+          <execution>
+            <!-- Do jar creation earlier, before the "test" phase, so that the
+             multi-release-jar content is visible to any dependent modules,
+             enabling them to use the relevant classes during their tests. -->
+            <id>default-jar</id>
+            <phase>process-test-classes</phase>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
           <execution>
             <goals>
               <goal>test-jar</goal>
@@ -242,7 +252,7 @@
         </plugins>
       </build>
     </profile>
-       <profile>
+    <profile>
       <id>activemq.tests-autoTransport</id>
       <activation>
         <property>
@@ -263,5 +273,32 @@
         </plugins>
       </build>
     </profile>
+      <profile>
+      <id>jdk24-plus</id>
+      <activation>
+        <jdk>[24,)</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-compiler-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>java24-compile</id>
+                <phase>compile</phase>
+                <goals>
+                  <goal>compile</goal>
+                </goals>
+                <configuration>
+                  <release>24</release> <!-- Specific Java version for 
alternative classes -->
+                  
<compileSourceRoots>${project.basedir}/src/main/java24</compileSourceRoots>
+                  <multiReleaseOutput>true</multiReleaseOutput>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
   </profiles>
 </project>
diff --git 
a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java 
b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
index 1eeb6fb8b4..e51d521480 100644
--- 
a/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
+++ 
b/activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
@@ -1898,7 +1898,7 @@ public class BrokerService implements Service {
         return virtualThreadTaskRunner;
     }
 
-    @Experimental("Tech Preview for Virtaul Thread support")
+    @Experimental("Tech Preview for Virtual Thread support")
     public void setVirtualThreadTaskRunner(boolean virtualThreadTaskRunner) {
         this.virtualThreadTaskRunner = virtualThreadTaskRunner;
     }
diff --git 
a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AnnotatedMBean.java
 
b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AnnotatedMBean.java
index 51c135ddf5..7dcfd33c64 100644
--- 
a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AnnotatedMBean.java
+++ 
b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/AnnotatedMBean.java
@@ -205,8 +205,15 @@ public class AnnotatedMBean extends StandardMBean {
         objects = (objects == null) ? new Object[]{} : objects;
         JMXAuditLogEntry entry = null;
         if (audit != OFF) {
-            // [AMQ-9563] TODO: JDK 21 use Subject.current() instead
-            Subject subject = 
Subject.getSubject(AccessController.getContext());
+            /**
+             * [AMQ-9563] JDK JAAS API conversion assistance
+             *
+             * Use a shim along with multi-release jar to
+             * support JDK 17 and JDK 24+ in one build.
+             *
+             * see: src/main/java24 folder
+             */
+            Subject subject = SubjectShim.lookupSubject();
             String caller = "anonymous";
             if (subject != null) {
                 caller = "";
diff --git 
a/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/SubjectShim.java 
b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/SubjectShim.java
new file mode 100644
index 0000000000..fb8862ea37
--- /dev/null
+++ 
b/activemq-broker/src/main/java/org/apache/activemq/broker/jmx/SubjectShim.java
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.broker.jmx;
+
+import javax.security.auth.Subject;
+import java.security.AccessController;
+
+/**
+ * [AMQ-9563] JDK JAAS API conversion assistance
+ *
+ * This instance of the class is for JDK [17, 24)
+ *
+ */
+public class SubjectShim {
+
+    private SubjectShim() {}
+
+    public static Subject lookupSubject() {
+        return Subject.getSubject(AccessController.getContext());
+    }
+}
diff --git 
a/activemq-broker/src/main/java24/org/apache/activemq/broker/jmx/SubjectShim.java
 
b/activemq-broker/src/main/java24/org/apache/activemq/broker/jmx/SubjectShim.java
new file mode 100644
index 0000000000..f112b45b0f
--- /dev/null
+++ 
b/activemq-broker/src/main/java24/org/apache/activemq/broker/jmx/SubjectShim.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.broker.jmx;
+
+import javax.security.auth.Subject;
+
+/**
+ * [AMQ-9563] JDK JAAS API conversion assistance
+ *
+ * This instance of the class is for JDK 24+
+ *
+ */
+public class SubjectShim {
+
+    private SubjectShim() {}
+
+    public static Subject lookupSubject() {
+        return Subject.current();
+    }
+}
diff --git 
a/activemq-client/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java
 
b/activemq-client/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java
index 3c872bef3c..28f834efcb 100644
--- 
a/activemq-client/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java
+++ 
b/activemq-client/src/main/java/org/apache/activemq/thread/TaskRunnerFactory.java
@@ -240,10 +240,7 @@ public class TaskRunnerFactory implements Executor {
     }
 
     protected ExecutorService createVirtualThreadExecutor() {
-        if(!(Runtime.version().feature() >= 21)) {
-            LOG.error("Virtual Thread support requires JDK 21 or higher");
-            throw new IllegalStateException("Virtual Thread support requires 
JDK 21 or higher");
-        }
+        assertJDK21VirtualThreadSupport();
 
         try {
             Class<?> virtualThreadExecutorClass = 
Class.forName("org.apache.activemq.thread.VirtualThreadExecutor", false, 
threadClassLoader);
@@ -253,7 +250,7 @@ public class TaskRunnerFactory implements Executor {
                 throw new IllegalStateException("VirtualThreadExecutor not 
returned");
             }
             LOG.info("VirtualThreadExecutor initialized name:{}", name);
-            return ExecutorService.class.cast(result);
+            return (ExecutorService) result;
         } catch (ClassNotFoundException | NoSuchMethodException | 
SecurityException | IllegalAccessException | InvocationTargetException e) {
             LOG.error("VirtualThreadExecutor class failed to load", e);
             throw new IllegalStateException(e);
@@ -261,10 +258,7 @@ public class TaskRunnerFactory implements Executor {
     }
 
     protected TaskRunner createVirtualThreadTaskRunner(Executor executor, Task 
task, int maxIterations) {
-        if(!(Runtime.version().feature() >= 21)) {
-            LOG.error("Virtual Thread support requires JDK 21 or higher");
-            throw new IllegalStateException("Virtual Thread support requires 
JDK 21 or higher");
-        }
+        assertJDK21VirtualThreadSupport();
 
         try {
             Class<?> virtualThreadTaskRunnerClass = 
Class.forName("org.apache.activemq.thread.VirtualThreadTaskRunner", false, 
threadClassLoader);
@@ -273,13 +267,20 @@ public class TaskRunnerFactory implements Executor {
             if(!TaskRunner.class.isAssignableFrom(result.getClass())) {
                 throw new IllegalStateException("VirtualThreadTaskRunner not 
returned");
             }
-            return TaskRunner.class.cast(result);
+            return (TaskRunner) result;
         } catch (ClassNotFoundException | NoSuchMethodException | 
SecurityException | IllegalAccessException | InvocationTargetException | 
InstantiationException | IllegalArgumentException e) {
             LOG.error("VirtualThreadTaskRunner class failed to load", e);
             throw new IllegalStateException(e);
         }
     }
 
+    private void assertJDK21VirtualThreadSupport() {
+        if(!(Runtime.version().feature() >= 21)) {
+            LOG.error("Virtual Thread support requires JDK 21 or higher");
+            throw new IllegalStateException("Virtual Thread support requires 
JDK 21 or higher");
+        }
+    }
+
 
     public ExecutorService getExecutor() {
         return executorRef.get();
diff --git 
a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBPersistenceAdapter.java
 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBPersistenceAdapter.java
index eb0d56d154..1955f8450b 100644
--- 
a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBPersistenceAdapter.java
+++ 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/KahaDBPersistenceAdapter.java
@@ -44,6 +44,7 @@ import org.apache.activemq.store.TransactionStore;
 import org.apache.activemq.store.kahadb.data.KahaLocalTransactionId;
 import org.apache.activemq.store.kahadb.data.KahaTransactionInfo;
 import org.apache.activemq.store.kahadb.data.KahaXATransactionId;
+import org.apache.activemq.store.kahadb.disk.journal.DataFileFactory;
 import 
org.apache.activemq.store.kahadb.disk.journal.Journal.JournalDiskSyncStrategy;
 import org.apache.activemq.usage.SystemUsage;
 import org.apache.activemq.util.ServiceStopper;
@@ -840,4 +841,8 @@ public class KahaDBPersistenceAdapter extends 
LockableServiceSupport implements
     public boolean getCleanupOnStop() {
         return this.letter.getCleanupOnStop();
     }
+
+    public void setDataFileFactory(DataFileFactory dataFileFactory) {
+        this.letter.setDataFileFactory(dataFileFactory);
+    }
 }
diff --git 
a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MessageDatabase.java
 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MessageDatabase.java
index c21f982560..2709817d01 100644
--- 
a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MessageDatabase.java
+++ 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/MessageDatabase.java
@@ -90,6 +90,7 @@ import org.apache.activemq.store.kahadb.disk.index.BTreeIndex;
 import org.apache.activemq.store.kahadb.disk.index.BTreeVisitor;
 import org.apache.activemq.store.kahadb.disk.index.ListIndex;
 import org.apache.activemq.store.kahadb.disk.journal.DataFile;
+import org.apache.activemq.store.kahadb.disk.journal.DataFileFactory;
 import org.apache.activemq.store.kahadb.disk.journal.Journal;
 import 
org.apache.activemq.store.kahadb.disk.journal.Journal.JournalDiskSyncStrategy;
 import org.apache.activemq.store.kahadb.disk.journal.Location;
@@ -263,6 +264,7 @@ public abstract class MessageDatabase extends 
ServiceSupport implements BrokerSe
 
     protected JournalDiskSyncStrategy journalDiskSyncStrategy = 
JournalDiskSyncStrategy.ALWAYS;
     protected boolean archiveDataLogs;
+    protected DataFileFactory dataFileFactory;
     protected File directoryArchive;
     protected AtomicLong journalSize = new AtomicLong(0);
     long journalDiskSyncInterval = 1000;
@@ -3282,6 +3284,9 @@ public abstract class MessageDatabase extends 
ServiceSupport implements BrokerSe
             IOHelper.mkdirs(getDirectoryArchive());
             manager.setDirectoryArchive(getDirectoryArchive());
         }
+        if (getDataFileFactory() != null) {
+            manager.setDataFileFactory(getDataFileFactory());
+        }
         return manager;
     }
 
@@ -4156,4 +4161,12 @@ public abstract class MessageDatabase extends 
ServiceSupport implements BrokerSe
             LOG.debug(e.getMessage(), e);
         }
     }
+
+    public DataFileFactory getDataFileFactory() {
+        return this.dataFileFactory;
+    }
+
+    public void  setDataFileFactory(DataFileFactory dataFileFactory) {
+        this.dataFileFactory = dataFileFactory;
+    }
 }
diff --git 
a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/DataFileFactory.java
 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/DataFileFactory.java
new file mode 100644
index 0000000000..85120323a7
--- /dev/null
+++ 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/DataFileFactory.java
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.store.kahadb.disk.journal;
+
+import java.io.File;
+
+public interface DataFileFactory {
+    DataFile create(File file, int number);
+}
\ No newline at end of file
diff --git 
a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/DefaultDataFileFactory.java
 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/DefaultDataFileFactory.java
new file mode 100644
index 0000000000..cd80a0e039
--- /dev/null
+++ 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/DefaultDataFileFactory.java
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.store.kahadb.disk.journal;
+
+import java.io.File;
+
+public class DefaultDataFileFactory implements DataFileFactory {
+
+    @Override
+    public DataFile create(File file, int number) {
+        return new DataFile(file, number);
+    }
+}
\ No newline at end of file
diff --git 
a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/Journal.java
 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/Journal.java
index f565f9c6a6..754f280287 100644
--- 
a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/Journal.java
+++ 
b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/journal/Journal.java
@@ -241,6 +241,7 @@ public class Journal {
     private long cleanupInterval = DEFAULT_CLEANUP_INTERVAL;
 
     protected JournalDiskSyncStrategy journalDiskSyncStrategy = 
JournalDiskSyncStrategy.ALWAYS;
+    protected DataFileFactory dataFileFactory = new DefaultDataFileFactory();
 
     public interface DataFileRemovedListener {
         void fileRemoved(DataFile datafile);
@@ -272,7 +273,7 @@ public class Journal {
                     String n = file.getName();
                     String numStr = n.substring(filePrefix.length(), 
n.length()-fileSuffix.length());
                     int num = Integer.parseInt(numStr);
-                    DataFile dataFile = new DataFile(file, num);
+                    DataFile dataFile = dataFileFactory.create(file, num);
                     fileMap.put(dataFile.getDataFileId(), dataFile);
                     totalLength.addAndGet(dataFile.getLength());
                 } catch (NumberFormatException e) {
@@ -687,7 +688,7 @@ public class Journal {
     private DataFile newDataFile() throws IOException {
         int nextNum = nextDataFileId++;
         File file = getFile(nextNum);
-        DataFile nextWriteFile = new DataFile(file, nextNum);
+        DataFile nextWriteFile = dataFileFactory.create(file, nextNum);
         
preallocateEntireJournalDataFile(nextWriteFile.appendRandomAccessFile());
         return nextWriteFile;
     }
@@ -697,7 +698,7 @@ public class Journal {
         synchronized (dataFileIdLock) {
             int nextNum = nextDataFileId++;
             File file = getFile(nextNum);
-            DataFile reservedDataFile = new DataFile(file, nextNum);
+            DataFile reservedDataFile = dataFileFactory.create(file, nextNum);
             synchronized (currentDataFile) {
                 fileMap.put(reservedDataFile.getDataFileId(), 
reservedDataFile);
                 fileByFileMap.put(file, reservedDataFile);
@@ -1164,6 +1165,14 @@ public class Journal {
         this.dataFileRemovedListener = dataFileRemovedListener;
     }
 
+    public void setDataFileFactory(DataFileFactory dataFileFactory) {
+        this.dataFileFactory = dataFileFactory;
+    }
+
+    public DataFileFactory getDataFileFactory() {
+        return  this.dataFileFactory;
+    }
+
     public static class WriteCommand extends LinkedNode<WriteCommand> {
         public final Location location;
         public final ByteSequence data;
diff --git 
a/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/JournalArchiveTest.java
 
b/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/JournalArchiveTest.java
index 2a8bd60165..a8090d37e5 100644
--- 
a/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/JournalArchiveTest.java
+++ 
b/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/JournalArchiveTest.java
@@ -22,6 +22,9 @@ import org.apache.activemq.broker.region.policy.PolicyEntry;
 import org.apache.activemq.broker.region.policy.PolicyMap;
 import org.apache.activemq.command.ActiveMQQueue;
 import org.apache.activemq.store.kahadb.disk.journal.DataFile;
+import org.apache.activemq.store.kahadb.disk.journal.DataFileFactory;
+import org.apache.activemq.store.kahadb.disk.journal.DefaultDataFileFactory;
+import org.apache.activemq.store.kahadb.disk.journal.ErrorDataFileFactory;
 import org.junit.After;
 import org.junit.Test;
 import org.slf4j.Logger;
@@ -54,6 +57,7 @@ public class JournalArchiveTest {
     private BrokerService broker = null;
     private final Destination destination = new ActiveMQQueue("Test");
     private KahaDBPersistenceAdapter adapter;
+    private DataFileFactory dataFileFactory;
 
     protected void startBroker() throws Exception {
         doStartBroker(true);
@@ -104,6 +108,7 @@ public class JournalArchiveTest {
         adapter.setCheckForCorruptJournalFiles(true);
 
         adapter.setArchiveDataLogs(true);
+        adapter.setDataFileFactory(dataFileFactory);
     }
 
     @After
@@ -119,16 +124,8 @@ public class JournalArchiveTest {
     public void testRecoveryOnArchiveFailure() throws Exception {
         final AtomicInteger atomicInteger = new AtomicInteger();
 
-        System.setSecurityManager(new SecurityManager() {
-            public void checkPermission(Permission perm) {}
-            public void checkPermission(Permission perm, Object context) {}
+        this.dataFileFactory = new ErrorDataFileFactory();
 
-            public void checkWrite(String file) {
-                if (file.contains(DEFAULT_ARCHIVE_DIRECTORY) && 
atomicInteger.incrementAndGet() > 4) {
-                    throw new SecurityException("No Perms to write to archive 
times:" + atomicInteger.get());
-                }
-            }
-        });
         startBroker();
 
         int sent = produceMessagesToConsumeMultipleDataFiles(50);
@@ -151,7 +148,7 @@ public class JournalArchiveTest {
         assertTrue("broker got shutdown on page in error", 
gotShutdown.await(10, TimeUnit.SECONDS));
 
         // no restrictions
-        System.setSecurityManager(null);
+        this.dataFileFactory = new DefaultDataFileFactory();
 
         int numFilesAfterRestart = 0;
         try {
diff --git 
a/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/disk/journal/ErrorDataFileFactory.java
 
b/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/disk/journal/ErrorDataFileFactory.java
new file mode 100644
index 0000000000..e20f5061d8
--- /dev/null
+++ 
b/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/disk/journal/ErrorDataFileFactory.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.store.kahadb.disk.journal;
+
+import org.apache.activemq.util.IOHelper;
+
+import java.io.File;
+import java.io.IOException;
+
+import static 
org.apache.activemq.store.kahadb.disk.journal.Journal.DEFAULT_ARCHIVE_DIRECTORY;
+
+public class ErrorDataFileFactory implements DataFileFactory {
+
+    @Override
+    public DataFile create(File file, int number) {
+        return new ErrorDataFile(file, number);
+    }
+
+    public static class ErrorDataFile extends DataFile {
+
+        ErrorDataFile(File file, int number) {
+            super(file, number);
+        }
+
+        @Override
+        public synchronized void move(File targetDirectory) throws IOException 
{
+            if (targetDirectory.getName().contains(DEFAULT_ARCHIVE_DIRECTORY) 
&& this.dataFileId > 4) {
+                throw new SecurityException("No Perms to write to archive 
times:" + this.dataFileId);
+            }
+            IOHelper.moveFile(file, targetDirectory);
+        }
+    }
+}
diff --git a/activemq-unit-tests/pom.xml b/activemq-unit-tests/pom.xml
index 2e4d088dbb..78b0293807 100644
--- a/activemq-unit-tests/pom.xml
+++ b/activemq-unit-tests/pom.xml
@@ -717,7 +717,6 @@
     <profile>
       <id>activemq.tests-quick</id>
       <activation>
-        <activeByDefault>true</activeByDefault>
         <property>
           <name>activemq.tests</name>
           <value>quick</value>
diff --git 
a/activemq-unit-tests/src/test/java/org/apache/activemq/transport/failover/FailoverDurableSubTransactionTest.java
 
b/activemq-unit-tests/src/test/java/org/apache/activemq/transport/failover/FailoverDurableSubTransactionTest.java
index ad4db46912..f4a4d2a2f9 100644
--- 
a/activemq-unit-tests/src/test/java/org/apache/activemq/transport/failover/FailoverDurableSubTransactionTest.java
+++ 
b/activemq-unit-tests/src/test/java/org/apache/activemq/transport/failover/FailoverDurableSubTransactionTest.java
@@ -182,6 +182,9 @@ public class FailoverDurableSubTransactionTest {
         // Get the actual bound URI after broker starts (important for 
ephemeral ports)
         url = 
broker.getTransportConnectors().get(0).getPublishableConnectString();
 
+        // Get the actual bound URI after broker starts (important for 
ephemeral ports)
+        url = 
broker.getTransportConnectors().get(0).getPublishableConnectString();
+
         ActiveMQConnectionFactory cf = new 
ActiveMQConnectionFactory("failover:(" + url + ")");
         cf.setAlwaysSyncSend(true);
         cf.setAlwaysSessionAsync(false);
@@ -290,6 +293,9 @@ public class FailoverDurableSubTransactionTest {
         // Get the actual bound URI after broker starts (important for 
ephemeral ports)
         url = 
broker.getTransportConnectors().get(0).getPublishableConnectString();
 
+        // Get the actual bound URI after broker starts (important for 
ephemeral ports)
+        url = 
broker.getTransportConnectors().get(0).getPublishableConnectString();
+
         ActiveMQConnectionFactory cf = new 
ActiveMQConnectionFactory("failover:(" + url + ")");
         cf.setAlwaysSyncSend(true);
         cf.setAlwaysSessionAsync(true);
diff --git a/pom.xml b/pom.xml
index 447e33ab4c..6760202787 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,7 @@
     <javaVersion>17</javaVersion>
 
     <surefire.argLine></surefire.argLine>
-    
<maven.surefire.allow.securitymanager>-Djava.security.manager=allow</maven.surefire.allow.securitymanager>
+    
<maven.surefire.allow.securitymanager></maven.surefire.allow.securitymanager>
 
     <siteId>activemq-${project.version}</siteId>
     <projectName>Apache ActiveMQ</projectName>
@@ -1121,39 +1121,6 @@
     </pluginManagement>
 
     <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-enforcer-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>enforce-maven</id>
-            <goals>
-              <goal>enforce</goal>
-            </goals>
-            <configuration>
-              <rules>
-                <requireMavenVersion>
-                  <version>3.0.5</version>
-                </requireMavenVersion>
-              </rules>
-            </configuration>
-          </execution>
-          <execution>
-            <id>enforce-java-version</id>
-            <goals>
-              <goal>enforce</goal>
-            </goals>
-            <configuration>
-              <rules>
-                <requireJavaVersion>
-                  <version>[17,)</version>
-                  <message>You must use Java 17+ to build.</message>
-                </requireJavaVersion>
-              </rules>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
       <plugin>
         <groupId>org.apache.geronimo.genesis.plugins</groupId>
         <artifactId>tools-maven-plugin</artifactId>
@@ -1271,29 +1238,6 @@
   </build>
   <reporting>
     <plugins>
-      <!--
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jxr-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-report-plugin</artifactId>
-        <version>${maven-surefire-plugin-version}</version>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-pmd-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>cobertura-maven-plugin</artifactId>
-      </plugin>
-      -->
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>taglist-maven-plugin</artifactId>
@@ -1337,6 +1281,26 @@
       </activation>
       <build>
         <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-enforcer-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>enforce-java-version</id>
+                <goals>
+                  <goal>enforce</goal>
+                </goals>
+                <configuration>
+                  <rules>
+                    <requireJavaVersion>
+                      <version>[24,)</version>
+                      <message>You must use Java 24+ to build (we leverage 
MRJAR).</message>
+                    </requireJavaVersion>
+                  </rules>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
           <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-surefire-plugin</artifactId>
@@ -1449,5 +1413,15 @@
         <javadoc.options>-Xdoclint:none</javadoc.options>
      </properties>
    </profile>
+
+    <profile>
+      <id>allow-securitymanager</id>
+      <activation>
+        <jdk>[18,23]</jdk>
+      </activation>
+      <properties>
+        
<maven.surefire.allow.securitymanager>-Djava.security.manager=allow</maven.surefire.allow.securitymanager>
+      </properties>
+    </profile>
   </profiles>
 </project>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact



Reply via email to