This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new dfa8bb664c juneau-marshall improvements
dfa8bb664c is described below
commit dfa8bb664c9c8be8e0bac384d15bdb33dccea854
Author: James Bognar <[email protected]>
AuthorDate: Wed Dec 17 13:09:47 2025 -0500
juneau-marshall improvements
---
.../main/java/org/apache/juneau/BeanContext.java | 13 ++++---
.../org/apache/juneau/html/HtmlDocSerializer.java | 14 +++++---
.../org/apache/juneau/html/HtmlSerializer.java | 14 +++++---
.../org/apache/juneau/json/JsonSerializer.java | 14 +++++---
.../org/apache/juneau/rest/client/RestClient.java | 41 +++++++++++++---------
.../apache/juneau/rest/stats/MethodExecStats.java | 19 +++++++---
6 files changed, 78 insertions(+), 37 deletions(-)
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
index 982b41b103..dfde27e167 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
@@ -31,6 +31,7 @@ import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
import java.util.stream.*;
import org.apache.juneau.annotation.*;
@@ -3590,7 +3591,7 @@ public class BeanContext extends Context {
private final BeanRegistry beanRegistry;
private final BeanSession defaultSession;
private final PropertyNamer propertyNamerBean;
- private volatile WriterSerializer beanToStringSerializer;
+ private final AtomicReference<WriterSerializer> beanToStringSerializer
= new AtomicReference<>();
/**
* Constructor.
@@ -4221,12 +4222,16 @@ public class BeanContext extends Context {
* @return The serializer. May be <jk>null</jk> if all initialization
has occurred.
*/
protected WriterSerializer getBeanToStringSerializer() {
- if (beanToStringSerializer == null) {
+ WriterSerializer result = beanToStringSerializer.get();
+ if (result == null) {
if (JsonSerializer.DEFAULT == null)
return null;
- this.beanToStringSerializer =
JsonSerializer.create().beanContext(this).sq().simpleAttrs().build();
+ result =
JsonSerializer.create().beanContext(this).sq().simpleAttrs().build();
+ if (! beanToStringSerializer.compareAndSet(null,
result)) {
+ result = beanToStringSerializer.get();
+ }
}
- return beanToStringSerializer;
+ return result;
}
/**
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
index 3d66197ee4..29c2570b4b 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
@@ -23,6 +23,7 @@ import static org.apache.juneau.commons.utils.Utils.*;
import java.lang.annotation.*;
import java.nio.charset.*;
import java.util.*;
+import java.util.concurrent.atomic.*;
import java.util.function.*;
import java.util.regex.*;
@@ -1640,7 +1641,7 @@ public class HtmlDocSerializer extends
HtmlStrippedDocSerializer {
private final HtmlWidget[] widgetArray;
private final HtmlDocTemplate templateBean;
- private volatile HtmlSchemaDocSerializer schemaSerializer;
+ private final AtomicReference<HtmlSchemaDocSerializer> schemaSerializer
= new AtomicReference<>();
/**
* Constructor.
@@ -1683,9 +1684,14 @@ public class HtmlDocSerializer extends
HtmlStrippedDocSerializer {
@Override /* Overridden from XmlSerializer */
public HtmlSerializer getSchemaSerializer() {
- if (schemaSerializer == null)
- schemaSerializer =
HtmlSchemaDocSerializer.create().beanContext(getBeanContext()).build();
- return schemaSerializer;
+ HtmlSchemaDocSerializer result = schemaSerializer.get();
+ if (result == null) {
+ result =
HtmlSchemaDocSerializer.create().beanContext(getBeanContext()).build();
+ if (! schemaSerializer.compareAndSet(null, result)) {
+ result = schemaSerializer.get();
+ }
+ }
+ return result;
}
@Override /* Overridden from Context */
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index 02d5402d90..887f46cfeb 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -23,6 +23,7 @@ import java.lang.annotation.*;
import java.nio.charset.*;
import java.util.*;
import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
import org.apache.juneau.*;
import org.apache.juneau.commons.collections.*;
@@ -1440,7 +1441,7 @@ public class HtmlSerializer extends XmlSerializer
implements HtmlMetaProvider {
private final Map<ClassMeta<?>,HtmlClassMeta> htmlClassMetas = new
ConcurrentHashMap<>();
private final Map<BeanPropertyMeta,HtmlBeanPropertyMeta>
htmlBeanPropertyMetas = new ConcurrentHashMap<>();
- private volatile HtmlSchemaSerializer schemaSerializer;
+ private final AtomicReference<HtmlSchemaSerializer> schemaSerializer =
new AtomicReference<>();
/**
* Constructor.
@@ -1495,9 +1496,14 @@ public class HtmlSerializer extends XmlSerializer
implements HtmlMetaProvider {
* @return The schema serializer.
*/
public HtmlSerializer getSchemaSerializer() {
- if (schemaSerializer == null)
- schemaSerializer =
HtmlSchemaSerializer.create().beanContext(getBeanContext()).build();
- return schemaSerializer;
+ HtmlSchemaSerializer result = schemaSerializer.get();
+ if (result == null) {
+ result =
HtmlSchemaSerializer.create().beanContext(getBeanContext()).build();
+ if (! schemaSerializer.compareAndSet(null, result)) {
+ result = schemaSerializer.get();
+ }
+ }
+ return result;
}
@Override /* Overridden from Context */
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
index ef15cb046d..9a0615340d 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -23,6 +23,7 @@ import java.lang.annotation.*;
import java.nio.charset.*;
import java.util.*;
import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
import org.apache.juneau.*;
import org.apache.juneau.commons.collections.*;
@@ -1047,7 +1048,7 @@ public class JsonSerializer extends WriterSerializer
implements JsonMetaProvider
private final Map<BeanPropertyMeta,JsonBeanPropertyMeta>
jsonBeanPropertyMetas = new ConcurrentHashMap<>();
private final Map<ClassMeta<?>,JsonClassMeta> jsonClassMetas = new
ConcurrentHashMap<>();
- private volatile JsonSchemaSerializer schemaSerializer;
+ private final AtomicReference<JsonSchemaSerializer> schemaSerializer =
new AtomicReference<>();
/**
* Constructor.
@@ -1105,9 +1106,14 @@ public class JsonSerializer extends WriterSerializer
implements JsonMetaProvider
* @return The schema serializer.
*/
public JsonSchemaSerializer getSchemaSerializer() {
- if (schemaSerializer == null)
- schemaSerializer =
JsonSchemaSerializer.create().beanContext(getBeanContext()).build();
- return schemaSerializer;
+ JsonSchemaSerializer result = schemaSerializer.get();
+ if (result == null) {
+ result =
JsonSchemaSerializer.create().beanContext(getBeanContext()).build();
+ if (! schemaSerializer.compareAndSet(null, result)) {
+ result = schemaSerializer.get();
+ }
+ }
+ return result;
}
@Override /* Overridden from Context */
diff --git
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index 4803413635..ed95b037f8 100644
---
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -40,6 +40,7 @@ import java.nio.charset.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
import java.util.function.*;
import java.util.logging.*;
import java.util.regex.*;
@@ -6191,8 +6192,8 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
private final String rootUrl;
private final boolean executorServiceShutdownOnClose;
private final boolean logToConsole;
- private volatile boolean isClosed = false;
- private volatile ExecutorService executorService;
+ private final AtomicBoolean isClosed = new AtomicBoolean(false);
+ private final AtomicReference<ExecutorService> executorService = new
AtomicReference<>();
/**
* Constructor.
@@ -6217,7 +6218,8 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
errorCodes = builder.errorCodes;
connectionManager = builder.connectionManager;
console = nn(builder.console) ? builder.console : System.err;
- executorService = builder.executorService;
+ if (builder.executorService != null)
+ executorService.set(builder.executorService);
executorServiceShutdownOnClose =
builder.executorServiceShutdownOnClose;
ignoreErrors = builder.ignoreErrors;
keepHttpClientOpen = builder.keepHttpClientOpen;
@@ -6340,11 +6342,12 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
*/
@Override
public void close() throws IOException {
- isClosed = true;
+ isClosed.set(true);
+ ExecutorService es = executorService.get();
if (! keepHttpClientOpen)
httpClient.close();
- if (nn(executorService) && executorServiceShutdownOnClose)
- executorService.shutdown();
+ if (nn(es) && executorServiceShutdownOnClose)
+ es.shutdown();
if (nn(creationStack))
closedStack = Thread.currentThread().getStackTrace();
}
@@ -6353,12 +6356,13 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
* Same as {@link #close()}, but ignores any exceptions.
*/
public void closeQuietly() {
- isClosed = true;
+ isClosed.set(true);
try {
if (! keepHttpClientOpen)
httpClient.close();
- if (nn(executorService) &&
executorServiceShutdownOnClose)
- executorService.shutdown();
+ ExecutorService es = executorService.get();
+ if (nn(es) && executorServiceShutdownOnClose)
+ es.shutdown();
} catch (@SuppressWarnings("unused") Throwable t) {}
if (nn(creationStack))
closedStack = Thread.currentThread().getStackTrace();
@@ -7697,7 +7701,7 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
@Override
protected void finalize() throws Throwable {
- if (detectLeaks && ! isClosed && ! keepHttpClientOpen) {
+ if (detectLeaks && ! isClosed.get() && ! keepHttpClientOpen) {
var sb = new StringBuilder("WARNING: RestClient
garbage collected before it was finalized."); // NOT DEBUG
if (nn(creationStack)) {
sb.append("\nCreation Stack:"); // NOT DEBUG
@@ -7895,7 +7899,7 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
protected FluentMap<String,Object> properties() {
return super.properties()
.a("errorCodes", errorCodes)
- .a("executorService", executorService)
+ .a("executorService", executorService.get())
.a("executorServiceShutdownOnClose",
executorServiceShutdownOnClose)
.a("headerData", headerData)
.a("interceptors", interceptors)
@@ -7920,7 +7924,7 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
* @throws RestCallException If any authentication errors occurred.
*/
protected RestRequest request(RestOperation op) throws
RestCallException {
- if (isClosed) {
+ if (isClosed.get()) {
var e2 = (Exception)null;
if (nn(closedStack)) {
e2 = new Exception("Creation stack:");
@@ -8017,11 +8021,16 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
}
ExecutorService getExecutorService() {
- if (nn(executorService))
- return executorService;
+ ExecutorService result = executorService.get();
+ if (nn(result))
+ return result;
synchronized (this) {
- executorService = new ThreadPoolExecutor(1, 1, 30,
TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
- return executorService;
+ result = executorService.get();
+ if (nn(result))
+ return result;
+ result = new ThreadPoolExecutor(1, 1, 30,
TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
+ executorService.set(result);
+ return result;
}
}
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStats.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStats.java
index 8160fef02b..3ee8d7f2d8 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStats.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStats.java
@@ -108,7 +108,8 @@ public class MethodExecStats {
private final Method method;
private final ThrownStore thrownStore;
- private volatile int minTime = -1, maxTime;
+ private final AtomicInteger maxTime = new AtomicInteger();
+ private final AtomicInteger minTime = new AtomicInteger(-1);
private AtomicInteger starts = new AtomicInteger(), finishes = new
AtomicInteger(), errors = new AtomicInteger();
@@ -147,8 +148,13 @@ public class MethodExecStats {
finishes.incrementAndGet();
int milliTime = (int)(nanoTime / 1_000_000);
totalTime.addAndGet(nanoTime);
- minTime = minTime == -1 ? milliTime : Math.min(minTime,
milliTime);
- maxTime = Math.max(maxTime, milliTime);
+ int currentMin = minTime.get();
+ if (currentMin == -1) {
+ minTime.compareAndSet(-1, milliTime);
+ } else {
+ minTime.updateAndGet(x -> Math.min(x, milliTime));
+ }
+ maxTime.updateAndGet(x -> Math.max(x, milliTime));
return this;
}
@@ -186,7 +192,7 @@ public class MethodExecStats {
*
* @return The average execution time in milliseconds.
*/
- public int getMaxTime() { return maxTime; }
+ public int getMaxTime() { return maxTime.get(); }
/**
* Returns the method name of these stats.
@@ -200,7 +206,10 @@ public class MethodExecStats {
*
* @return The average execution time in milliseconds.
*/
- public int getMinTime() { return minTime == -1 ? 0 : minTime; }
+ public int getMinTime() {
+ int value = minTime.get();
+ return value == -1 ? 0 : value;
+ }
/**
* Returns the number currently running method invocations.