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 413ecc0727 Marshall module improvements
413ecc0727 is described below
commit 413ecc07278ef3c8520288b89e6191f94508dafd
Author: James Bognar <[email protected]>
AuthorDate: Mon Dec 8 17:11:01 2025 -0500
Marshall module improvements
---
.../juneau/bean/openapi3/OpenApiElement.java | 1 +
.../juneau/commons/utils/ThrowableUtils.java | 56 ++++++++++++++++++++++
.../main/java/org/apache/juneau/BeanContext.java | 14 +++---
.../src/main/java/org/apache/juneau/BeanMeta.java | 36 +++++++-------
4 files changed, 84 insertions(+), 23 deletions(-)
diff --git
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/OpenApiElement.java
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/OpenApiElement.java
index 8811bf28b2..75e37864d9 100644
---
a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/OpenApiElement.java
+++
b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/OpenApiElement.java
@@ -31,6 +31,7 @@ import org.apache.juneau.json.*;
/**
* Root class for all Swagger beans.
*/
+@Bean
public abstract class OpenApiElement {
private boolean strict;
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ThrowableUtils.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ThrowableUtils.java
index f40f9ee7b0..fa75de05a8 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ThrowableUtils.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ThrowableUtils.java
@@ -181,6 +181,62 @@ public class ThrowableUtils {
return sw.toString();
}
+ /**
+ * Prints a stack trace with a maximum depth limit.
+ *
+ * <p>
+ * This method is useful for {@link StackOverflowError} situations
where printing the full stack trace
+ * can cause additional errors due to stack exhaustion. The stack trace
will be limited to the specified
+ * maximum number of elements.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * <jk>try</jk> {
+ * <jc>// Some code that might cause
StackOverflowError</jc>
+ * } <jk>catch</jk> (StackOverflowError <jv>e</jv>) {
+ * <jc>// Print only first 100 stack trace elements</jc>
+ * ThrowableUtils.<jsm>printStackTrace</jsm>(<jv>e</jv>,
System.err, 100);
+ * }
+ * </p>
+ *
+ * @param t The throwable to print the stack trace for.
+ * @param pw The print writer to write to.
+ * @param maxDepth The maximum number of stack trace elements to print.
If <jk>null</jk> or negative, prints all elements.
+ */
+ public static void printStackTrace(Throwable t, PrintWriter pw, Integer
maxDepth) {
+ try {
+ pw.println(t);
+ var stackTrace = t.getStackTrace();
+ var depth = maxDepth != null && maxDepth > 0 ?
Math.min(maxDepth, stackTrace.length) : stackTrace.length;
+ for (var i = 0; i < depth; i++) {
+ pw.println("\tat " + stackTrace[i]);
+ }
+ if (maxDepth != null && maxDepth > 0 &&
stackTrace.length > maxDepth) {
+ pw.println("\t... (" + (stackTrace.length -
maxDepth) + " more)");
+ }
+ var cause = t.getCause();
+ if (cause != null && cause != t) {
+ pw.print("Caused by: ");
+ printStackTrace(cause, pw, maxDepth);
+ }
+ } catch (Exception e) {
+ pw.println("Error printing stack trace: " +
e.getMessage());
+ }
+ }
+
+ /**
+ * Prints a stack trace with a maximum depth limit to standard error.
+ *
+ * <p>
+ * Same as {@link #printStackTrace(Throwable, PrintWriter, Integer)}
but writes to {@link System#err}.
+ *
+ * @param t The throwable to print the stack trace for.
+ * @param maxDepth The maximum number of stack trace elements to print.
If <jk>null</jk> or negative, prints all elements.
+ */
+ public static void printStackTrace(Throwable t, Integer maxDepth) {
+ printStackTrace(t, new PrintWriter(System.err, true), maxDepth);
+ }
+
/**
* Same as {@link Throwable#getCause()} but searches the throwable
chain for an exception of the specified type.
*
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 667135d600..e5ec82be0b 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
@@ -4136,22 +4136,22 @@ public class BeanContext extends Context {
* Determines whether the specified class is ignored as a bean class
based on the various exclusion parameters
* specified on this context class.
*
- * @param c The class type being tested.
+ * @param ci The class info being tested.
* @return <jk>true</jk> if the specified class matches any of the
exclusion parameters.
*/
- protected final boolean isNotABean(Class<?> c) {
- if (c.isArray() || c.isPrimitive() || c.isEnum() ||
c.isAnnotation())
+ protected final boolean isNotABean(ClassInfo ci) {
+ if (ci.isArray() || ci.isPrimitive() || ci.isEnum() ||
ci.isAnnotation())
return true;
- Package p = c.getPackage();
+ var p = ci.getPackage();
if (nn(p)) {
+ var pn = p.getName();
for (var p2 : notBeanPackageNames)
- if (p.getName().equals(p2))
+ if (pn.equals(p2))
return true;
for (var p2 : notBeanPackagePrefixes)
- if (p.getName().startsWith(p2))
+ if (pn.startsWith(p2))
return true;
}
- var ci = info(c);
for (var exclude : notBeanClassesArray)
if (ci.isChildOf(exclude))
return true;
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
index 1cb7ad4401..ac85da45f0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
@@ -135,6 +135,22 @@ public class BeanMeta<T> {
*/
public static <T> BeanMetaValue<T> create(ClassMeta<T> cm, BeanFilter
bf, String[] pNames, ConstructorInfo implClassConstructor) {
try {
+ var bc = cm.getBeanContext();
+ var ap = bc.getAnnotationProvider();
+
+ // Sanity checks first.
+ if (bc.isNotABean(cm))
+ return notABean("Class matches exclude-class
list");
+
+ if (bf == null && bc.isBeansRequireSerializable() && !
cm.isChildOf(Serializable.class))
+ return notABean("Class is not serializable");
+
+ if (ap.has(BeanIgnore.class, cm))
+ return notABean("Class is annotated with
@BeanIgnore");
+
+ if ((!
bc.getBeanClassVisibility().isVisible(cm.getModifiers()) ||
cm.isAnonymousClass()) && ! ap.has(Bean.class, cm))
+ return notABean("Class is not public");
+
var bm = new BeanMeta<>(cm, bf, pNames,
implClassConstructor);
var nabr = bm.notABeanReason;
return new BeanMetaValue<>(nabr == null ? bm : null,
nabr);
@@ -143,6 +159,10 @@ public class BeanMeta<T> {
}
}
+ private static <T> BeanMetaValue<T> notABean(String reason) {
+ return new BeanMetaValue<>(null, reason);
+ }
+
/*
* Temporary getter/setter method struct.
*/
@@ -253,7 +273,6 @@ public class BeanMeta<T> {
try {
var conVis = ctx.getBeanConstructorVisibility();
- var cVis = ctx.getBeanClassVisibility();
var mVis = ctx.getBeanMethodVisibility();
var fVis = ctx.getBeanFieldVisibility();
@@ -284,21 +303,6 @@ public class BeanMeta<T> {
Map<String,BeanPropertyMeta.Builder>
normalProps = map(); // NOAI
var hasBean = ap.has(Bean.class, ci);
- var hasBeanIgnore = ap.has(BeanIgnore.class,
ci);
-
- /// See if this class matches one the patterns
in the exclude-class list.
- if (ctx.isNotABean(c))
- return "Class matches exclude-class
list";
-
- if (! hasBean && !
(cVis.isVisible(c.getModifiers()) || c.isAnonymousClass()))
- return "Class is not public";
-
- if (hasBeanIgnore)
- return "Class is annotated with
@BeanIgnore";
-
- // Make sure it's serializable.
- if (beanFilter == null &&
ctx.isBeansRequireSerializable() && ! ci.isChildOf(Serializable.class))
- return "Class is not serializable";
// Look for @Beanc constructor on public
constructors.
ci.getPublicConstructors().stream().filter(x ->
ap.has(Beanc.class, x)).forEach(x -> {