Spring AOP und Kryo => CME


#1

Hallo Community,

ich wollte einige Klassen um Aspekte erweitern und habe mal einen einfachen Log Aspect mit Spring AOP geschrieben. Die Objekte sollen später mit Kryo serialisiert werden und da kracht es [inline]java.util.ConcurrentModificationException[/inline]. Ohne Aspekte funktioniert es problemlos.

Hier mal ein bisschen Code:
application-config.xml:
[xml]<?xml version="1.0" encoding="UTF-8"?>

<context:component-scan base-package="org.aspecttest" />
<aop:aspectj-autoproxy />
[/xml]

ABean.java:

@Scope("prototype")
public class ABean {

	String	test;
	String	world;

	public void actionButtonClick() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {}
	}

	public String getTest() {
		return test;
	}

	public void setTest(String test) {
		this.test = test;
	}

	public String getWorld() {
		return world;
	}

	public void setWorld(String world) {
		this.world = world;
	}
}

ABeanKryoSerializer.java :

public class ABeanKryoSerializer {

	public static void main(String... args) throws IOException {
		Kryo kryo = new Kryo();
		kryo.register(ABean.class);

		ApplicationContext appContext = new ClassPathXmlApplicationContext("spring/application-config.xml");
		ABean bean = (ABean) appContext.getBean("ABean");
		bean.setTest("Hallo Welt"); // Test Aspekte
		bean.setWorld("What"); // Test Aspekte
		bean.getWorld(); // Test Aspekte
		System.out.println(bean);

		bean.actionButtonClick();

		write(kryo, bean);
	}

	public static void write(Kryo kryo, ABean abean) throws IOException {

		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(16384);
		DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream);
		Output output = new Output(deflaterOutputStream);
		kryo.writeObject(output, abean); //Hier fliegt die CME
		output.close();
	}

}

SimpleAspect:

@Aspect
public class SimpleAspect {

	@After("execution(* org.aspecttest.*.set*(..))")
	public void logSetter(JoinPoint joinPoint) {
		Logger log = Logger.getLogger(joinPoint.getTarget().getClass());
		log.trace(joinPoint.getTarget().getClass().getSimpleName() + "." + joinPoint.getSignature().getName() + getArgString(joinPoint.getArgs()));
	}

	private String getArgString(Object[] args) {
		if (args != null && args.length >= 1) {
			StringBuilder sb = new StringBuilder();
			sb.append(": ");
			for (Object item : args) {
				sb.append(item);
				sb.append(" / ");
			}
			return sb.substring(0, sb.length() - 3);
		}
		return "";
	}
}```

Stacktrace:
```Exception in thread "main" com.esotericsoftware.kryo.KryoException: java.util.ConcurrentModificationException
Serialization trace:
classes (sun.misc.Launcher$AppClassLoader)
beanClassLoader (org.springframework.beans.factory.support.DefaultListableBeanFactory)
beanFactory (org.springframework.aop.aspectj.annotation.BeanFactoryAspectInstanceFactory)
maaif (org.springframework.aop.aspectj.annotation.LazySingletonAspectInstanceFactoryDecorator)
aspectInstanceFactory (org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl)
advisorArray (org.springframework.aop.framework.ProxyFactory)
advised (org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor)
CGLIB$CALLBACK_0 (org.aspecttest.ABean$$EnhancerBySpringCGLIB$$891f9a71)
	at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:82)
	at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:474)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:538)
	at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:61)
	at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:474)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:538)
	at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:61)
	at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:474)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:538)
	at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:61)
	at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:474)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:538)
	at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:61)
	at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:474)
	at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:614)
	at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.write(DefaultArraySerializers.java:337)
	at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.write(DefaultArraySerializers.java:276)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:538)
	at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:61)
	at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:474)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:538)
	at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:61)
	at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:474)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:538)
	at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:61)
	at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:474)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:520)
	at org.aspecttest.ABeanKryoSerializer.write(ABeanKryoSerializer.java:41)
	at org.aspecttest.ABeanKryoSerializer.main(ABeanKryoSerializer.java:33)
Caused by: java.util.ConcurrentModificationException
	at java.util.Vector$Itr.checkForComodification(Vector.java:1156)
	at java.util.Vector$Itr.next(Vector.java:1133)
	at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:70)
	at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:18)
	at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:538)
	at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:61)
	... 28 more```

Mache ich was falsch, oder wollen Spring AOP und Kryo nicht zusammenarbeiten? Unabhängig voneinander arbeiten beide hervorragend. Nur miteinander wollen sie nicht.

#2

So, ich bin nun nicht untätig gewesen. Ich habe nun Maven (pom.xml) nach dem Tutorial http://www.javacodegeeks.com/2010/07/aspect-oriented-programming-with-spring.html so konfiguriert:

[XML]


org.codehaus.mojo
aspectj-maven-plugin
1.3

${maven.compiler.source}
${maven.compiler.target}




compile



		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<version>2.0.2</version>
			<configuration>
				<source>${maven.compiler.source}</source>
				<target>${maven.compiler.target}</target>
			</configuration>
		</plugin>

	</plugins>

</build>[/XML]

Anscheinend aktiviert diese Konfig “compile time weaving” auch wenn das nicht explizit so erklärt wird. Aber nur so erklärt es sich für mich, dass diese Konfiguration Abhilfe geschaffen hat.