Skip to content

Commit

Permalink
Trace method calls to figure out the root cause of FasterXML#179
Browse files Browse the repository at this point in the history
  • Loading branch information
ppalaga committed Jan 5, 2024
1 parent 8f060f5 commit 4a5afcf
Show file tree
Hide file tree
Showing 4 changed files with 323 additions and 17 deletions.
43 changes: 36 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ SAX2 and Stax2 APIs
<version.plugin.javadoc>3.1.1</version.plugin.javadoc>

<!-- Woodstox 5.0 is 1.6+ -->
<javac.src.version>1.6</javac.src.version>
<javac.target.version>1.6</javac.target.version>
<javac.src.version>1.8</javac.src.version>
<javac.target.version>1.8</javac.target.version>

<!-- Since our groupId is NOT the same as Java package id, need to explicitly define.
And due to number of packages, let's just include all.
Expand Down Expand Up @@ -93,7 +93,7 @@ SAX2 and Stax2 APIs
+ "msv" ones (3 subgroups)
+ "com.sun.msv", but only for xsdlib
and all with varying sets of dependencies;
and all with varying sets of dependencies;
For now, we'll just use "msv", which does not properly define
dependencies...
Expand Down Expand Up @@ -129,8 +129,12 @@ SAX2 and Stax2 APIs
-->
<optional>true</optional>
</dependency>

<!-- 03-Jun-2019, tatu: Not sure why this was added as a dep as it's only one class,
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.7</version>
</dependency>
<!-- 03-Jun-2019, tatu: Not sure why this was added as a dep as it's only one class,
`com.sun.msv.writer.relaxng.Driver`, and some metadata. I assumed it was needed by MSV
but at least unit tests do not cache issues. So, will remove from 5.3.0
-->
Expand Down Expand Up @@ -174,6 +178,23 @@ SAX2 and Stax2 APIs

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.15.0</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal> <!-- use this goal to weave all your main classes -->
</goals>
</execution>
</executions>
</plugin>
<!-- 10-Jul-2021, tatu: Add code coverage again -->
<plugin>
<groupId>org.jacoco</groupId>
Expand Down Expand Up @@ -217,8 +238,8 @@ SAX2 and Stax2 APIs
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>1.8</source>
<target>1.8</target>
<!--
<excludes>
<exclude>test/**</exclude>
Expand All @@ -239,7 +260,15 @@ SAX2 and Stax2 APIs
<include>**/*Test.java</include>
<include>**/Test*.java</include>
</includes>
<argLine>-javaagent:/home/data/m2/repository/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-1.9.7.jar</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
Expand Down
157 changes: 157 additions & 0 deletions src/main/java/com/ctc/aop/TraceAspect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package com.ctc.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;
import org.aspectj.lang.annotation.AfterReturning;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.aspectj.lang.JoinPoint;

@Aspect
public class TraceAspect {

private int indent = 0;
private List<String> indents = new ArrayList<>();
private static final Set<String> renderableTypes = new HashSet<>(Arrays.asList(
javax.xml.namespace.QName.class.getName(),
int.class.getName(),
long.class.getName(),
byte.class.getName(),
boolean.class.getName(),
Integer.class.getName(),
Long.class.getName(),
Byte.class.getName(),
Boolean.class.getName()
));

@Before("execution(* com.ctc.wstx..*.*(..)) && !handler(*) && !execution(* com.ctc.wstx.util.XmlChars.*(..))")
public void beforeMethodCall(JoinPoint joinPoint) {
if (joinPoint.getSignature() instanceof CodeSignature) {
CodeSignature sig = (CodeSignature) joinPoint.getSignature();
System.out.println(indent() + "> " + sig.getDeclaringTypeName() + "." + sig.getName() + "("+
params(sig.getParameterTypes(), joinPoint.getArgs()) +")");
}
}

@AfterReturning(pointcut = "execution(* com.ctc.wstx..*.*(..)) && !handler(*) && !execution(* com.ctc.wstx.util.XmlChars.*(..))", returning = "returnValue")
//@After("execution(* com.ctc.wstx..*.*(..)) && !handler(*) && !execution(* com.ctc.wstx.util.XmlChars.*(..))")
public void afterMethodCall(JoinPoint joinPoint, Object returnValue) {
if (joinPoint.getSignature() instanceof CodeSignature) {
CodeSignature sig = (CodeSignature) joinPoint.getSignature();
StringBuilder ret = new StringBuilder();
String returnType = (sig instanceof MethodSignature) ? ((MethodSignature) sig).getReturnType().getName() : "void";
param(ret, returnValue, returnType);
System.out.println(unindent() + "< " + sig.getDeclaringTypeName() + "." + sig.getName() + "("+
params(sig.getParameterTypes(), joinPoint.getArgs()) +") : " + ret.toString());
}
}

static String params(Class<?>[] types, Object[] args) {
if (types.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < types.length; i++) {
if (i > 0) {
sb.append(", ");
}
Object val = args[i];
final String type = types[i].getName();
param(sb, val, type);
}
return sb.toString();
}

private static void param(StringBuilder sb, Object val, final String type) {
if (val == null) {
sb.append("null").append(':').append(type);
} else if (val.getClass() == String.class) {
escapeString('"', (String) val, sb);
sb.append(':').append(type);
} else if (val != null && (val.getClass() == char.class || val.getClass() == Character.class)) {
escapeChar('\'', (Character) val, sb);
sb.append(':').append(type);
} else if (renderableTypes.contains(val.getClass().getName())) {
sb.append(val).append(':').append(type);
} else {
sb.append(type);
}
}
static void escapeString(char quote, String input, StringBuilder escapedString) {
escapedString.append(quote);
for (char c : input.toCharArray()) {
switch (c) {
case '\n':
escapedString.append("\\n");
break;
case '\r':
escapedString.append("\\r");
break;
case '\t':
escapedString.append("\\t");
break;
case '\"':
escapedString.append("\\\"");
break;
case '\\':
escapedString.append("\\\\");
break;
// Add more cases here for other special characters if needed
default:
escapedString.append(c);
}
}
escapedString.append(quote);
}

static void escapeChar(char quote, Character c, StringBuilder escapedString) {
escapedString.append(quote);
switch (c.charValue()) {
case '\n':
escapedString.append("\\n");
break;
case '\r':
escapedString.append("\\r");
break;
case '\t':
escapedString.append("\\t");
break;
case '\"':
escapedString.append("\\\"");
break;
case '\\':
escapedString.append("\\\\");
break;
// Add more cases here for other special characters if needed
default:
escapedString.append(c);
}
escapedString.append(quote);
}

private String indent() {
while (indent >= indents.size()) {
indents.add(spaces(indents.size()));
}
return indents.get(indent++);
}

private String unindent() {
return indents.get(--indent);
}

static String spaces(int size) {
StringBuilder sb = new StringBuilder(size);
for (int i = 0; i < size; i++) {
sb.append(' ');
}
return sb.toString();
}
}
8 changes: 8 additions & 0 deletions src/main/resources/META-INF/aop.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<aspectj>
<weaver>
<include within="com.ctc.wstx..*"/>
</weaver>
<aspects>
<aspect name="com.ctc.aop.TraceAspect"/>
</aspects>
</aspectj>
Loading

0 comments on commit 4a5afcf

Please sign in to comment.