From bb5d47cbfe9fef53b75b5de894350c1409ff9805 Mon Sep 17 00:00:00 2001 From: Tamas Cservenak Date: Fri, 15 Aug 2025 16:21:10 +0200 Subject: [PATCH 1/4] Utilize VT if possible Also, do not pre-create as many threads as many cores reported by Java as many times they are simply unused. --- pom.xml | 20 +++++++++ .../archiver/zip/ConcurrentJarCreator.java | 5 +-- ...rrentJarCreatorExecutorServiceFactory.java | 45 +++++++++++++++++++ ...rrentJarCreatorExecutorServiceFactory.java | 33 ++++++++++++++ 4 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java create mode 100644 src/main/java21/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java diff --git a/pom.xml b/pom.xml index 329cc67eb..09462b2e8 100644 --- a/pom.xml +++ b/pom.xml @@ -147,6 +147,26 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + + java21 + + compile + + compile + + 21 + + ${project.basedir}/src/main/java21 + + true + + + + org.apache.maven.plugins maven-release-plugin diff --git a/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreator.java b/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreator.java index 5a3c32c5a..f2687c4ec 100644 --- a/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreator.java +++ b/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreator.java @@ -23,7 +23,6 @@ import java.io.SequenceInputStream; import java.io.UncheckedIOException; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; import java.util.zip.Deflater; import java.util.zip.ZipEntry; @@ -119,8 +118,8 @@ public ConcurrentJarCreator(boolean compressAddedZips, int nThreads) throws IOEx manifest = createDeferred(defaultSupplier); directories = createDeferred(defaultSupplier); synchronousEntries = createDeferred(defaultSupplier); - parallelScatterZipCreator = - new ParallelScatterZipCreator(Executors.newFixedThreadPool(nThreads), defaultSupplier); + parallelScatterZipCreator = new ParallelScatterZipCreator( + ConcurrentJarCreatorExecutorServiceFactory.createExecutorService(nThreads), defaultSupplier); } /** diff --git a/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java b/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java new file mode 100644 index 000000000..4bf3bc8a2 --- /dev/null +++ b/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java @@ -0,0 +1,45 @@ +/* + * 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.codehaus.plexus.archiver.zip; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +public class ConcurrentJarCreatorExecutorServiceFactory { + private static final AtomicInteger POOL_COUNTER = new AtomicInteger(); + + static ExecutorService createExecutorService(int poolSize) { + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + int poolCount = POOL_COUNTER.incrementAndGet(); + AtomicInteger threadCounter = new AtomicInteger(); + ThreadFactory threadFactory = new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread thread = + new Thread(threadGroup, r, "plx-arch-" + poolCount + "-" + threadCounter.incrementAndGet()); + thread.setDaemon(true); + return thread; + } + }; + return new ThreadPoolExecutor(1, poolSize, 1L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), threadFactory); + } +} diff --git a/src/main/java21/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java b/src/main/java21/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java new file mode 100644 index 000000000..62044e523 --- /dev/null +++ b/src/main/java21/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java @@ -0,0 +1,33 @@ +/* + * 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.codehaus.plexus.archiver.zip; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +public class ConcurrentJarCreatorExecutorServiceFactory { + private static final AtomicInteger POOL_COUNTER = new AtomicInteger(); + + static ExecutorService createExecutorService(int poolSize) { + int poolCount = POOL_COUNTER.incrementAndGet(); + AtomicInteger threadCounter = new AtomicInteger(); + return Executors.newThreadPerTaskExecutor( + Thread.ofVirtual().name("plx-arch-" + poolCount + "-" + threadCounter.incrementAndGet()).factory()); + } +} From b09134b0796a8d9ec5c65e5f382975c1d758661d Mon Sep 17 00:00:00 2001 From: Tamas Cservenak Date: Fri, 15 Aug 2025 16:23:43 +0200 Subject: [PATCH 2/4] Add Javadoc --- .../zip/ConcurrentJarCreatorExecutorServiceFactory.java | 6 ++++++ .../zip/ConcurrentJarCreatorExecutorServiceFactory.java | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java b/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java index 4bf3bc8a2..b475a7780 100644 --- a/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java +++ b/src/main/java/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java @@ -24,6 +24,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +/** + * Classic (pre Java 21) implementation. Create one thread eagerly, but allow pool to scale up to provided + * number (usually set to Java reported CPU count). Apply same thread names as well. + * + * @since 4.10.1 + */ public class ConcurrentJarCreatorExecutorServiceFactory { private static final AtomicInteger POOL_COUNTER = new AtomicInteger(); diff --git a/src/main/java21/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java b/src/main/java21/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java index 62044e523..27302a0b2 100644 --- a/src/main/java21/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java +++ b/src/main/java21/org/codehaus/plexus/archiver/zip/ConcurrentJarCreatorExecutorServiceFactory.java @@ -21,6 +21,11 @@ import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; +/** + * Post Java 21 implementation. Create one Virtual Thread per task execution. Apply same thread names as well. + * + * @since 4.10.1 + */ public class ConcurrentJarCreatorExecutorServiceFactory { private static final AtomicInteger POOL_COUNTER = new AtomicInteger(); From 5b54276a9812721e27a24514aa8aab39bd3c8548 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Tue, 19 Aug 2025 18:14:30 +0200 Subject: [PATCH 3/4] Build by jdk21 in profile --- pom.xml | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/pom.xml b/pom.xml index 09462b2e8..19f2599cd 100644 --- a/pom.xml +++ b/pom.xml @@ -147,26 +147,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - - java21 - - compile - - compile - - 21 - - ${project.basedir}/src/main/java21 - - true - - - - org.apache.maven.plugins maven-release-plugin @@ -202,4 +182,36 @@ + + + jdk21 + + [21,) + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + java21 + + compile + + compile + + 21 + + ${project.basedir}/src/main/java21 + + true + + + + + + + + From 46306e820d6c0616309c45bc07cd7df607799883 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Tue, 19 Aug 2025 19:48:53 +0200 Subject: [PATCH 4/4] Force release by jdk 21 at least --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 19f2599cd..5b89b6d91 100644 --- a/pom.xml +++ b/pom.xml @@ -213,5 +213,11 @@ + + plexus-release + + 21 + +