From 633f7481d4f2dff9b8ba33183922d1a1355b59f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raymond=20Aug=C3=A9?= Date: Sat, 7 May 2022 11:23:57 -0400 Subject: [PATCH 1/6] CXF-8700: Eliminate the `java.compiler` dependency from cxf-core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raymond Augé --- bom/pom.xml | 5 ++ osgi/itests-felix/pom.xml | 7 ++- .../cxf/osgi/itests/NoAriesBlueprintTest.java | 2 + .../features/src/main/resources/features.xml | 1 + rt/frontend/simple/pom.xml | 5 ++ .../dynamic/DynamicClientFactory.java | 6 +-- tools/common/pom.xml | 5 ++ .../apache/cxf/tools/common/ClassUtils.java | 2 +- tools/compiler/pom.xml | 49 +++++++++++++++++++ .../apache/cxf/tools/compiler}/Compiler.java | 8 +-- .../cxf/tools/compiler}/StreamPrinter.java | 2 +- tools/javato/ws/pom.xml | 5 ++ .../generator/wsdl11/BeanGenerator.java | 2 +- .../cxf/tools/java2ws/JavaToWSTest.java | 2 +- tools/pom.xml | 1 + 15 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 tools/compiler/pom.xml rename {core/src/main/java/org/apache/cxf/common/util => tools/compiler/src/main/java/org/apache/cxf/tools/compiler}/Compiler.java (98%) rename {core/src/main/java/org/apache/cxf/common/util => tools/compiler/src/main/java/org/apache/cxf/tools/compiler}/StreamPrinter.java (98%) diff --git a/bom/pom.xml b/bom/pom.xml index 86e5f09f552..041376a418c 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -414,6 +414,11 @@ cxf-tools-common ${project.version} + + org.apache.cxf + cxf-tools-compiler + ${project.version} + org.apache.cxf cxf-tools-corba diff --git a/osgi/itests-felix/pom.xml b/osgi/itests-felix/pom.xml index d30204f6740..3a163767d5c 100644 --- a/osgi/itests-felix/pom.xml +++ b/osgi/itests-felix/pom.xml @@ -86,7 +86,12 @@ cxf-rt-frontend-jaxws ${project.version} - + + org.apache.cxf + cxf-tools-compiler + ${project.version} + + org.ops4j.pax.exam pax-exam-container-native diff --git a/osgi/itests-felix/src/test/java/org/apache/cxf/osgi/itests/NoAriesBlueprintTest.java b/osgi/itests-felix/src/test/java/org/apache/cxf/osgi/itests/NoAriesBlueprintTest.java index 142376c0c29..389bbb99144 100644 --- a/osgi/itests-felix/src/test/java/org/apache/cxf/osgi/itests/NoAriesBlueprintTest.java +++ b/osgi/itests-felix/src/test/java/org/apache/cxf/osgi/itests/NoAriesBlueprintTest.java @@ -58,6 +58,7 @@ public void testCXFBundles() throws Exception { assertBundleStarted("org.apache.cxf.cxf-core"); assertBundleStarted("org.apache.cxf.cxf-rt-frontend-simple"); assertBundleStarted("org.apache.cxf.cxf-rt-frontend-jaxws"); + assertBundleStarted("org.apache.cxf.cxf-tools-compiler"); } @Configuration @@ -84,6 +85,7 @@ public Option[] config() throws NoSuchAlgorithmException, NoSuchPaddingException mavenBundle("jakarta.servlet", "jakarta.servlet-api").versionAsInProject(), mavenBundle("org.apache.cxf", "cxf-rt-transports-http").versionAsInProject(), mavenBundle("org.apache.cxf", "cxf-rt-frontend-jaxws").versionAsInProject(), + mavenBundle("org.apache.cxf", "cxf-tools-compiler").versionAsInProject(), junitBundles(), systemPackages( "javax.annotation;version=\"1.3\"", diff --git a/osgi/karaf/features/src/main/resources/features.xml b/osgi/karaf/features/src/main/resources/features.xml index 25dda519ede..bc2a1365642 100644 --- a/osgi/karaf/features/src/main/resources/features.xml +++ b/osgi/karaf/features/src/main/resources/features.xml @@ -223,6 +223,7 @@ cxf-databinding-jaxb cxf-bindings-soap cxf-http + mvn:org.apache.cxf/cxf-tools-compiler/${project.version} mvn:org.apache.cxf/cxf-rt-frontend-simple/${project.version} mvn:org.apache.cxf/cxf-rt-frontend-jaxws/${project.version} diff --git a/rt/frontend/simple/pom.xml b/rt/frontend/simple/pom.xml index f21a3be3a15..66177a53e0b 100644 --- a/rt/frontend/simple/pom.xml +++ b/rt/frontend/simple/pom.xml @@ -118,6 +118,11 @@ cxf-core ${project.version} + + org.apache.cxf + cxf-tools-compiler + ${project.version} + org.apache.cxf cxf-rt-bindings-soap diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java index 2e8b4160aad..8abc3a0b90f 100644 --- a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java +++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java @@ -626,8 +626,8 @@ public void setSimpleBindingEnabled(boolean simpleBindingEnabled) { } protected boolean compileJavaSrc(String classPath, List srcList, String dest) { - org.apache.cxf.common.util.Compiler javaCompiler - = new org.apache.cxf.common.util.Compiler(); + org.apache.cxf.tools.compiler.Compiler javaCompiler + = new org.apache.cxf.tools.compiler.Compiler(); javaCompiler.setClassPath(classPath); javaCompiler.setOutputDir(dest); @@ -735,7 +735,7 @@ private URL composeUrl(String s) { } catch (IOException e) { throw new ServiceConstructionException(new Message("COULD_NOT_RESOLVE_URL", LOG, s), e); } - + throw new ServiceConstructionException(new Message("COULD_NOT_RESOLVE_URL", LOG, s)); } diff --git a/tools/common/pom.xml b/tools/common/pom.xml index b72cd5cdc99..54c391787fb 100644 --- a/tools/common/pom.xml +++ b/tools/common/pom.xml @@ -64,6 +64,11 @@ cxf-core ${project.version} + + org.apache.cxf + cxf-tools-compiler + ${project.version} + com.fasterxml.woodstox woodstox-core diff --git a/tools/common/src/main/java/org/apache/cxf/tools/common/ClassUtils.java b/tools/common/src/main/java/org/apache/cxf/tools/common/ClassUtils.java index 12ed3327fad..ac526457b3a 100644 --- a/tools/common/src/main/java/org/apache/cxf/tools/common/ClassUtils.java +++ b/tools/common/src/main/java/org/apache/cxf/tools/common/ClassUtils.java @@ -33,8 +33,8 @@ import org.apache.cxf.common.i18n.Message; import org.apache.cxf.common.logging.LogUtils; -import org.apache.cxf.common.util.Compiler; import org.apache.cxf.helpers.FileUtils; +import org.apache.cxf.tools.compiler.Compiler; import org.apache.cxf.tools.util.ClassCollector; public class ClassUtils { diff --git a/tools/compiler/pom.xml b/tools/compiler/pom.xml new file mode 100644 index 00000000000..f1230c653a2 --- /dev/null +++ b/tools/compiler/pom.xml @@ -0,0 +1,49 @@ + + + + 4.0.0 + cxf-tools-compiler + bundle + Apache CXF Tools Compiler + Apache CXF Tools Compiler + https://cxf.apache.org + + org.apache.cxf + cxf-parent + 4.0.0-SNAPSHOT + ../../parent/pom.xml + + + org.apache.cxf.tools.compiler + + + + org.apache.cxf + cxf-core + ${project.version} + + + + junit + junit + test + + + diff --git a/core/src/main/java/org/apache/cxf/common/util/Compiler.java b/tools/compiler/src/main/java/org/apache/cxf/tools/compiler/Compiler.java similarity index 98% rename from core/src/main/java/org/apache/cxf/common/util/Compiler.java rename to tools/compiler/src/main/java/org/apache/cxf/tools/compiler/Compiler.java index cc2e43173c8..d8aefab5629 100644 --- a/core/src/main/java/org/apache/cxf/common/util/Compiler.java +++ b/tools/compiler/src/main/java/org/apache/cxf/tools/compiler/Compiler.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.cxf.common.util; +package org.apache.cxf.tools.compiler; import java.io.File; import java.io.FileWriter; @@ -38,6 +38,8 @@ import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; +import org.apache.cxf.common.util.StringUtils; +import org.apache.cxf.common.util.SystemPropertyAction; import org.apache.cxf.helpers.FileUtils; public class Compiler { @@ -93,9 +95,9 @@ private String getSystemClassPath() { List correctedEntries = new ArrayList<>(); String[] toks = javaClasspath.split(File.pathSeparator); - + for (String tok: toks) { - // if any classpath entry contains a whitespace char, + // if any classpath entry contains a whitespace char, // enclose the entry in double quotes if (tok.matches(".*\\s+.*")) { correctedEntries.add("\"" + tok + "\""); diff --git a/core/src/main/java/org/apache/cxf/common/util/StreamPrinter.java b/tools/compiler/src/main/java/org/apache/cxf/tools/compiler/StreamPrinter.java similarity index 98% rename from core/src/main/java/org/apache/cxf/common/util/StreamPrinter.java rename to tools/compiler/src/main/java/org/apache/cxf/tools/compiler/StreamPrinter.java index fa8828764d5..712bd2660ed 100644 --- a/core/src/main/java/org/apache/cxf/common/util/StreamPrinter.java +++ b/tools/compiler/src/main/java/org/apache/cxf/tools/compiler/StreamPrinter.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.cxf.common.util; +package org.apache.cxf.tools.compiler; import java.io.BufferedReader; import java.io.IOException; diff --git a/tools/javato/ws/pom.xml b/tools/javato/ws/pom.xml index 42742bc8e8a..452923635cd 100644 --- a/tools/javato/ws/pom.xml +++ b/tools/javato/ws/pom.xml @@ -44,6 +44,11 @@ cxf-tools-common ${project.version} + + org.apache.cxf + cxf-tools-compiler + ${project.version} + org.apache.cxf cxf-core diff --git a/tools/javato/ws/src/main/java/org/apache/cxf/tools/java2wsdl/generator/wsdl11/BeanGenerator.java b/tools/javato/ws/src/main/java/org/apache/cxf/tools/java2wsdl/generator/wsdl11/BeanGenerator.java index 15f8b48f68e..74e6aef49d1 100644 --- a/tools/javato/ws/src/main/java/org/apache/cxf/tools/java2wsdl/generator/wsdl11/BeanGenerator.java +++ b/tools/javato/ws/src/main/java/org/apache/cxf/tools/java2wsdl/generator/wsdl11/BeanGenerator.java @@ -24,11 +24,11 @@ import java.util.Collection; import java.util.List; -import org.apache.cxf.common.util.Compiler; import org.apache.cxf.service.model.ServiceInfo; import org.apache.cxf.tools.common.ToolConstants; import org.apache.cxf.tools.common.VelocityGenerator; import org.apache.cxf.tools.common.model.JavaClass; +import org.apache.cxf.tools.compiler.Compiler; import org.apache.cxf.tools.java2wsdl.generator.AbstractGenerator; import org.apache.cxf.tools.util.FileWriterUtil; diff --git a/tools/javato/ws/src/test/java/org/apache/cxf/tools/java2ws/JavaToWSTest.java b/tools/javato/ws/src/test/java/org/apache/cxf/tools/java2ws/JavaToWSTest.java index 8bf1be3688b..b50e9b3339d 100644 --- a/tools/javato/ws/src/test/java/org/apache/cxf/tools/java2ws/JavaToWSTest.java +++ b/tools/javato/ws/src/test/java/org/apache/cxf/tools/java2ws/JavaToWSTest.java @@ -28,7 +28,6 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.apache.cxf.common.util.Compiler; import org.apache.cxf.helpers.FileUtils; import org.apache.cxf.helpers.XPathUtils; import org.apache.cxf.staxutils.StaxUtils; @@ -36,6 +35,7 @@ import org.apache.cxf.tools.common.TestFileUtils; import org.apache.cxf.tools.common.ToolContext; import org.apache.cxf.tools.common.ToolTestBase; +import org.apache.cxf.tools.compiler.Compiler; import org.junit.After; import org.junit.Before; diff --git a/tools/pom.xml b/tools/pom.xml index 3cc594b57c7..a93f85befc6 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -30,6 +30,7 @@ 4.0.0-SNAPSHOT + compiler common validator wsdlto From 7f650e61c1d49e08667c6021804513a7635f7f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raymond=20Aug=C3=A9?= Date: Sat, 7 May 2022 12:06:25 -0400 Subject: [PATCH 2/6] CXF-8701: extract ImageDataContentHandler to a separate module in order to lower footprint of `java.desktop` dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raymond Augé --- .../apache/cxf/attachment/AttachmentUtil.java | 14 +++- rt/attachment-image/pom.xml | 65 +++++++++++++++++++ .../image}/ImageDataContentHandler.java | 2 +- rt/pom.xml | 1 + 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 rt/attachment-image/pom.xml rename {core/src/main/java/org/apache/cxf/attachment => rt/attachment-image/src/main/java/org/apache/cxf/management/attachment/image}/ImageDataContentHandler.java (98%) diff --git a/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java b/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java index 7c72f004494..27655aac14f 100644 --- a/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java +++ b/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java @@ -155,8 +155,18 @@ private AttachmentUtil() { } static { - COMMAND_MAP.addMailcap("image/*;;x-java-content-handler=" - + ImageDataContentHandler.class.getName()); + String imageDataContentHandlerClassName = "org.apache.cxf.management.attachment.image.ImageDataContentHandler"; + + try { + Class imageDataContentHandlerClass = Class.forName( + imageDataContentHandlerClassName); + + COMMAND_MAP.addMailcap("image/*;;x-java-content-handler=" + + imageDataContentHandlerClass.getName()); + } catch (ReflectiveOperationException e) { + LOG.warning(() -> imageDataContentHandlerClassName.concat( + " cannot be found. Is cxf-rt-attachment-image present?")); + } } public static CommandMap getCommandMap() { diff --git a/rt/attachment-image/pom.xml b/rt/attachment-image/pom.xml new file mode 100644 index 00000000000..68098e93959 --- /dev/null +++ b/rt/attachment-image/pom.xml @@ -0,0 +1,65 @@ + + + + 4.0.0 + cxf-rt-attachment-image + bundle + Apache CXF Runtime Attachment Image + Apache CXF Runtime Attachment Image + https://cxf.apache.org + + org.apache.cxf + cxf-parent + 4.0.0-SNAPSHOT + ../../parent/pom.xml + + + org.apache.cxf.management.attachment.image + + + + org.apache.cxf + cxf-core + ${project.version} + + + junit + junit + test + + + org.slf4j + jcl-over-slf4j + test + + + org.apache.cxf + cxf-testutils + ${project.version} + test + + + org.easymock + easymock + test + + + + diff --git a/core/src/main/java/org/apache/cxf/attachment/ImageDataContentHandler.java b/rt/attachment-image/src/main/java/org/apache/cxf/management/attachment/image/ImageDataContentHandler.java similarity index 98% rename from core/src/main/java/org/apache/cxf/attachment/ImageDataContentHandler.java rename to rt/attachment-image/src/main/java/org/apache/cxf/management/attachment/image/ImageDataContentHandler.java index 0de70cd3ce5..3682db20f34 100644 --- a/core/src/main/java/org/apache/cxf/attachment/ImageDataContentHandler.java +++ b/rt/attachment-image/src/main/java/org/apache/cxf/management/attachment/image/ImageDataContentHandler.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.cxf.attachment; +package org.apache.cxf.management.attachment.image; import java.awt.Component; import java.awt.Graphics; diff --git a/rt/pom.xml b/rt/pom.xml index 7b13daebe01..939cc68246a 100644 --- a/rt/pom.xml +++ b/rt/pom.xml @@ -36,6 +36,7 @@ bindings features frontend + attachment-image ws rs management From b36351da50ce9d856cbea51bffc5afaea4fb8781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raymond=20Aug=C3=A9?= Date: Sat, 7 May 2022 12:09:50 -0400 Subject: [PATCH 3/6] CXF-8701: Use reflection to access ImageIO in cases where it's not present, reduces the footprint of the `java.desktop` dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raymond Augé --- .../main/java/org/apache/cxf/common/logging/JDKBugHacks.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/cxf/common/logging/JDKBugHacks.java b/core/src/main/java/org/apache/cxf/common/logging/JDKBugHacks.java index a1a5c82cc59..748bbcd0e54 100644 --- a/core/src/main/java/org/apache/cxf/common/logging/JDKBugHacks.java +++ b/core/src/main/java/org/apache/cxf/common/logging/JDKBugHacks.java @@ -29,7 +29,6 @@ import java.security.AccessController; import java.security.PrivilegedAction; -import javax.imageio.ImageIO; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.cxf.common.classloader.ClassLoaderUtils; @@ -101,7 +100,9 @@ public static void doHacks() { try { //Trigger a call to sun.awt.AppContext.getAppContext() if (!skipHack("org.apache.cxf.JDKBugHacks.imageIO", "true")) { - ImageIO.getCacheDirectory(); + Class imageIOClass = Class.forName("javax.imageio.ImageIO"); + Method getCacheDirectoryMethod = imageIOClass.getDeclaredMethod("getCacheDirectory"); + getCacheDirectoryMethod.invoke(null); } } catch (Throwable t) { //ignore From 6ba9e126dca915e9b89d5aab1fa9cba16d12a049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raymond=20Aug=C3=A9?= Date: Sat, 7 May 2022 12:32:10 -0400 Subject: [PATCH 4/6] CXF-8701: eliminate use of PropertyChange* to lower footprint of `java.desktop` dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raymond Augé --- .../cxf/bus/osgi/ManagedWorkQueueList.java | 10 ++-- .../cxf/workqueue/AutomaticWorkQueueImpl.java | 30 +++++----- .../apache/cxf/workqueue/WorkqueueEvent.java | 60 +++++++++++++++++++ .../cxf/workqueue/WorkqueueEventListener.java | 26 ++++++++ 4 files changed, 105 insertions(+), 21 deletions(-) create mode 100644 core/src/main/java/org/apache/cxf/workqueue/WorkqueueEvent.java create mode 100644 core/src/main/java/org/apache/cxf/workqueue/WorkqueueEventListener.java diff --git a/core/src/main/java/org/apache/cxf/bus/osgi/ManagedWorkQueueList.java b/core/src/main/java/org/apache/cxf/bus/osgi/ManagedWorkQueueList.java index cd71e400c9d..3fa91037772 100644 --- a/core/src/main/java/org/apache/cxf/bus/osgi/ManagedWorkQueueList.java +++ b/core/src/main/java/org/apache/cxf/bus/osgi/ManagedWorkQueueList.java @@ -18,8 +18,6 @@ */ package org.apache.cxf.bus.osgi; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.Dictionary; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -30,6 +28,8 @@ import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.workqueue.AutomaticWorkQueueImpl; import org.apache.cxf.workqueue.WorkQueueManager; +import org.apache.cxf.workqueue.WorkqueueEvent; +import org.apache.cxf.workqueue.WorkqueueEventListener; import org.osgi.service.cm.Configuration; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.cm.ConfigurationException; @@ -39,7 +39,7 @@ /** * List of work queues that can be managed using the OSGi configuration admin service */ -public class ManagedWorkQueueList implements ManagedServiceFactory, PropertyChangeListener { +public class ManagedWorkQueueList implements ManagedServiceFactory, WorkqueueEventListener { public static final String FACTORY_PID = "org.apache.cxf.workqueues"; private static final Logger LOG = LogUtils.getL7dLogger(ManagedWorkQueueList.class); @@ -76,9 +76,9 @@ public void deleted(String pid) { /* * On property changes of queue settings we update the config admin service pid of the queue */ - public void propertyChange(PropertyChangeEvent evt) { + public void processEvent(WorkqueueEvent workqueueEvent) { try { - AutomaticWorkQueueImpl queue = (AutomaticWorkQueueImpl)evt.getSource(); + AutomaticWorkQueueImpl queue = (AutomaticWorkQueueImpl)workqueueEvent.getSource(); ConfigurationAdmin configurationAdmin = configAdminTracker.getService(); if (configurationAdmin != null) { Configuration selectedConfig = findConfigForQueueName(queue, configurationAdmin); diff --git a/core/src/main/java/org/apache/cxf/workqueue/AutomaticWorkQueueImpl.java b/core/src/main/java/org/apache/cxf/workqueue/AutomaticWorkQueueImpl.java index 67dd3b4ddb8..64f7fce280a 100644 --- a/core/src/main/java/org/apache/cxf/workqueue/AutomaticWorkQueueImpl.java +++ b/core/src/main/java/org/apache/cxf/workqueue/AutomaticWorkQueueImpl.java @@ -19,8 +19,6 @@ package org.apache.cxf.workqueue; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; @@ -78,7 +76,7 @@ public class AutomaticWorkQueueImpl implements AutomaticWorkQueue { boolean shared; int sharedCount; - private List changeListenerList; + private List workqueueEventListeners; public AutomaticWorkQueueImpl() { this(DEFAULT_MAX_QUEUE_SIZE); @@ -116,20 +114,20 @@ public AutomaticWorkQueueImpl(int mqs, this.lowWaterMark = -1 == lowWaterMark ? Integer.MAX_VALUE : lowWaterMark; this.dequeueTimeout = dequeueTimeout; this.name = name; - this.changeListenerList = new ArrayList<>(); + this.workqueueEventListeners = new ArrayList<>(); } - public void addChangeListener(PropertyChangeListener listener) { - this.changeListenerList.add(listener); + public void addChangeListener(WorkqueueEventListener listener) { + this.workqueueEventListeners.add(listener); } - public void removeChangeListener(PropertyChangeListener listener) { - this.changeListenerList.remove(listener); + public void removeChangeListener(WorkqueueEventListener listener) { + this.workqueueEventListeners.remove(listener); } - public void notifyChangeListeners(PropertyChangeEvent event) { - for (PropertyChangeListener listener : changeListenerList) { - listener.propertyChange(event); + public void notifyChangeListeners(WorkqueueEvent workqueueEvent) { + for (WorkqueueEventListener listener : workqueueEventListeners) { + listener.processEvent(workqueueEvent); } } @@ -530,7 +528,7 @@ public int getInitialSize() { public void setHighWaterMark(int hwm) { highWaterMark = hwm < 0 ? Integer.MAX_VALUE : hwm; if (executor != null) { - notifyChangeListeners(new PropertyChangeEvent(this, "highWaterMark", + notifyChangeListeners(new WorkqueueEvent(this, "highWaterMark", this.executor.getMaximumPoolSize(), hwm)); executor.setMaximumPoolSize(highWaterMark); } @@ -539,24 +537,24 @@ public void setHighWaterMark(int hwm) { public void setLowWaterMark(int lwm) { lowWaterMark = lwm < 0 ? 0 : lwm; if (executor != null) { - notifyChangeListeners(new PropertyChangeEvent(this, "lowWaterMark", + notifyChangeListeners(new WorkqueueEvent(this, "lowWaterMark", this.executor.getCorePoolSize(), lwm)); executor.setCorePoolSize(lowWaterMark); } } public void setInitialSize(int initialSize) { - notifyChangeListeners(new PropertyChangeEvent(this, "initialSize", this.initialThreads, initialSize)); + notifyChangeListeners(new WorkqueueEvent(this, "initialSize", this.initialThreads, initialSize)); this.initialThreads = initialSize; } public void setQueueSize(int size) { - notifyChangeListeners(new PropertyChangeEvent(this, "queueSize", this.maxQueueSize, size)); + notifyChangeListeners(new WorkqueueEvent(this, "queueSize", this.maxQueueSize, size)); this.maxQueueSize = size; } public void setDequeueTimeout(long l) { - notifyChangeListeners(new PropertyChangeEvent(this, "dequeueTimeout", this.dequeueTimeout, l)); + notifyChangeListeners(new WorkqueueEvent(this, "dequeueTimeout", this.dequeueTimeout, l)); this.dequeueTimeout = l; } diff --git a/core/src/main/java/org/apache/cxf/workqueue/WorkqueueEvent.java b/core/src/main/java/org/apache/cxf/workqueue/WorkqueueEvent.java new file mode 100644 index 00000000000..f973494038b --- /dev/null +++ b/core/src/main/java/org/apache/cxf/workqueue/WorkqueueEvent.java @@ -0,0 +1,60 @@ +/** + * 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.cxf.workqueue; + +import java.util.EventObject; + +public class WorkqueueEvent extends EventObject { + private static final long serialVersionUID = 2445723027847701801L; + + private final Object newValue; + private final Object oldValue; + private final String propertyName; + + public WorkqueueEvent( + Object source, String propertyName, Object oldValue, Object newValue) { + super(source); + this.propertyName = propertyName; + this.newValue = newValue; + this.oldValue = oldValue; + } + + public String getPropertyName() { + return propertyName; + } + + public Object getNewValue() { + return newValue; + } + + public Object getOldValue() { + return oldValue; + } + + public String toString() { + StringBuilder sb = new StringBuilder(getClass().getName()); + sb.append("[propertyName=").append(getPropertyName()); + sb.append("; oldValue=").append(getOldValue()); + sb.append("; newValue=").append(getNewValue()); + sb.append("; source=").append(getSource()); + return sb.append(']').toString(); + } + +} diff --git a/core/src/main/java/org/apache/cxf/workqueue/WorkqueueEventListener.java b/core/src/main/java/org/apache/cxf/workqueue/WorkqueueEventListener.java new file mode 100644 index 00000000000..e4fd786a9de --- /dev/null +++ b/core/src/main/java/org/apache/cxf/workqueue/WorkqueueEventListener.java @@ -0,0 +1,26 @@ +/** + * 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.cxf.workqueue; + +public interface WorkqueueEventListener extends java.util.EventListener { + + void processEvent(WorkqueueEvent workqueueEvent); + +} From 877ff6643ddca2b7645bd13c89747c1a3c52cd41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raymond=20Aug=C3=A9?= Date: Sat, 7 May 2022 12:42:54 -0400 Subject: [PATCH 5/6] CXF-8701: eliminate use of java.beans.Introspector, reduce footprint dependency on `java.desktop` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raymond Augé --- .../jaxb/SchemaCollectionContextProxy.java | 5 +++-- .../org/apache/cxf/common/util/ClassHelper.java | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/cxf/common/jaxb/SchemaCollectionContextProxy.java b/core/src/main/java/org/apache/cxf/common/jaxb/SchemaCollectionContextProxy.java index 0c5522d6936..b34262914d5 100644 --- a/core/src/main/java/org/apache/cxf/common/jaxb/SchemaCollectionContextProxy.java +++ b/core/src/main/java/org/apache/cxf/common/jaxb/SchemaCollectionContextProxy.java @@ -43,6 +43,7 @@ import org.w3c.dom.Document; +import org.apache.cxf.common.util.ClassHelper; import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.common.xmlschema.SchemaCollection; import org.apache.ws.commons.schema.XmlSchemaElement; @@ -135,7 +136,7 @@ public Object getBeanInfo(Class cls) { String name = xre == null ? "##default" : xre.name(); String namespace = xre == null ? "##default" : xre.namespace(); if ("##default".equals(name)) { - name = java.beans.Introspector.decapitalize(cls.getSimpleName()); + name = ClassHelper.decapitalizedSimpleName(cls); } if ("##default".equals(namespace) && cls.getPackage() != null) { XmlSchema sc = cls.getPackage().getAnnotation(XmlSchema.class); @@ -199,7 +200,7 @@ private QName getTypeQName(Class cls, String namespace) { String tn = xtype == null ? "##default" : xtype.name(); String tns = xtype == null ? "##default" : xtype.namespace(); if ("##default".equals(tn)) { - tn = java.beans.Introspector.decapitalize(cls.getSimpleName()); + tn = ClassHelper.decapitalizedSimpleName(cls); } if ("##default".equals(tns) || StringUtils.isEmpty(tns)) { tns = JAXBUtils.getPackageNamespace(cls); diff --git a/core/src/main/java/org/apache/cxf/common/util/ClassHelper.java b/core/src/main/java/org/apache/cxf/common/util/ClassHelper.java index adec469fdcf..2ae4faf809c 100644 --- a/core/src/main/java/org/apache/cxf/common/util/ClassHelper.java +++ b/core/src/main/java/org/apache/cxf/common/util/ClassHelper.java @@ -101,6 +101,23 @@ private Object getRealObjectInternal(Object o) { return o instanceof Proxy ? Proxy.getInvocationHandler(o) : o; } + public static String decapitalizedSimpleName(Class clazz) { + if (clazz == null) { + return null; + } + String name = clazz.getSimpleName(); + if (name == null || name.isEmpty()) { + return name; + } + if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) + && Character.isUpperCase(name.charAt(0))) { + return name; + } + char[] chars = name.toCharArray(); + chars[0] = Character.toLowerCase(chars[0]); + return new String(chars); + } + public static Class getRealClass(Object o) { return getRealClass(null, o); } From afae43db472077141b7314a9e533ffe7a8105da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raymond=20Aug=C3=A9?= Date: Sat, 7 May 2022 13:02:20 -0400 Subject: [PATCH 6/6] CXF-8701: move getPropertyDescriptorsAvoidSunBug to the only place where it's used, reduce footprint of `java.desktop` dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raymond Augé --- .../cxf/common/util/ReflectionUtil.java | 65 ----------------- .../cxf/aegis/type/basic/BeanTypeInfo.java | 70 +++++++++++++++++-- 2 files changed, 65 insertions(+), 70 deletions(-) diff --git a/core/src/main/java/org/apache/cxf/common/util/ReflectionUtil.java b/core/src/main/java/org/apache/cxf/common/util/ReflectionUtil.java index 146d7fc5762..7142c803bb9 100644 --- a/core/src/main/java/org/apache/cxf/common/util/ReflectionUtil.java +++ b/core/src/main/java/org/apache/cxf/common/util/ReflectionUtil.java @@ -19,28 +19,18 @@ package org.apache.cxf.common.util; -import java.beans.BeanInfo; -import java.beans.PropertyDescriptor; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.List; - -import org.apache.cxf.common.classloader.ClassLoaderUtils; public final class ReflectionUtil { - private static Method springBeanUtilsDescriptorFetcher; - private static boolean springChecked; - private ReflectionUtil() { // intentionally empty } @@ -195,61 +185,6 @@ public T run() { }); } - /** - * create own array of property descriptors to: - *
-     *  - prevent memory leaks by Introspector's cache
-     *  - get correct type for generic properties from superclass
-     *     that are limited to a specific type in beanClass
-     *    see http://bugs.sun.com/view_bug.do?bug_id=6528714
-     *   we cannot use BeanUtils.getPropertyDescriptors because of issue SPR-6063
-     *   
- * @param refClass calling class for class loading. - * @param beanInfo Bean in question - * @param beanClass class for bean in question - * @param propertyDescriptors raw descriptors - */ - public static PropertyDescriptor[] getPropertyDescriptorsAvoidSunBug(Class refClass, - BeanInfo beanInfo, - Class beanClass, - PropertyDescriptor[] propertyDescriptors) { - if (!springChecked) { - try { - springChecked = true; - Class cls = ClassLoaderUtils - .loadClass("org.springframework.beans.BeanUtils", refClass); - springBeanUtilsDescriptorFetcher - = cls.getMethod("getPropertyDescriptor", Class.class, String.class); - } catch (Exception e) { - //ignore - just assume it's an unsupported/unknown annotation - } - } - - if (springBeanUtilsDescriptorFetcher != null) { - if (propertyDescriptors != null) { - List descriptors = new ArrayList<>(propertyDescriptors.length); - for (int i = 0; i < propertyDescriptors.length; i++) { - PropertyDescriptor propertyDescriptor = propertyDescriptors[i]; - try { - propertyDescriptor = (PropertyDescriptor)springBeanUtilsDescriptorFetcher.invoke(null, - beanClass, - propertyDescriptor.getName()); - if (propertyDescriptor != null) { - descriptors.add(propertyDescriptor); - } - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e.getCause()); - } - } - return descriptors.toArray(new PropertyDescriptor[0]); - } - return null; - } - return beanInfo.getPropertyDescriptors(); - } - /** * Look for a specified annotation on a method. If there, return it. If not, search it's containing class. * Assume that the annotation is marked @Inherited. diff --git a/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java b/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java index aa4fef6c344..6e702d0e9de 100644 --- a/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java +++ b/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/type/basic/BeanTypeInfo.java @@ -22,6 +22,8 @@ import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -38,9 +40,12 @@ import org.apache.cxf.aegis.type.AegisType; import org.apache.cxf.aegis.type.TypeCreator; import org.apache.cxf.aegis.type.TypeMapping; -import org.apache.cxf.common.util.ReflectionUtil; +import org.apache.cxf.common.classloader.ClassLoaderUtils; public class BeanTypeInfo { + private static Method springBeanUtilsDescriptorFetcher; + private static boolean springChecked; + private Map mappedName2typeName = new HashMap<>(); private Map mappedName2pdName = new HashMap<>(); private Map mappedName2type = new HashMap<>(); @@ -106,6 +111,61 @@ public void initialize() { } } + /** + * create own array of property descriptors to: + *
+     *  - prevent memory leaks by Introspector's cache
+     *  - get correct type for generic properties from superclass
+     *     that are limited to a specific type in beanClass
+     *    see http://bugs.sun.com/view_bug.do?bug_id=6528714
+     *   we cannot use BeanUtils.getPropertyDescriptors because of issue SPR-6063
+     *   
+ * @param refClass calling class for class loading. + * @param beanInfo Bean in question + * @param beanClass class for bean in question + * @param propertyDescriptors raw descriptors + */ + public static PropertyDescriptor[] getPropertyDescriptorsAvoidSunBug(Class refClass, + BeanInfo beanInfo, + Class beanClass, + PropertyDescriptor[] propertyDescriptors) { + if (!springChecked) { + try { + springChecked = true; + Class cls = ClassLoaderUtils + .loadClass("org.springframework.beans.BeanUtils", refClass); + springBeanUtilsDescriptorFetcher + = cls.getMethod("getPropertyDescriptor", Class.class, String.class); + } catch (Exception e) { + //ignore - just assume it's an unsupported/unknown annotation + } + } + + if (springBeanUtilsDescriptorFetcher != null) { + if (propertyDescriptors != null) { + List descriptors = new ArrayList<>(propertyDescriptors.length); + for (int i = 0; i < propertyDescriptors.length; i++) { + PropertyDescriptor propertyDescriptor = propertyDescriptors[i]; + try { + propertyDescriptor = (PropertyDescriptor)springBeanUtilsDescriptorFetcher.invoke(null, + beanClass, + propertyDescriptor.getName()); + if (propertyDescriptor != null) { + descriptors.add(propertyDescriptor); + } + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e.getCause()); + } + } + return descriptors.toArray(new PropertyDescriptor[0]); + } + return null; + } + return beanInfo.getPropertyDescriptors(); + } + private synchronized void initializeSync() { if (!initialized) { for (int i = 0; i < descriptors.length; i++) { @@ -285,10 +345,10 @@ private void initializeProperties() { PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); if (propertyDescriptors != null) { // see comments on this function. - descriptors = ReflectionUtil.getPropertyDescriptorsAvoidSunBug(getClass(), - beanInfo, - beanClass, - propertyDescriptors); + descriptors = getPropertyDescriptorsAvoidSunBug(getClass(), + beanInfo, + beanClass, + propertyDescriptors); } }