Bug 349398 - Abstract generic aspect leads to java.lang.ClassFormatError: Duplicate method name&signature in class file
Summary: Abstract generic aspect leads to java.lang.ClassFormatError: Duplicate method...
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P2 normal (vote)
Target Milestone: 1.6.12   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-15 01:51 EDT by Johannes Unterstein CLA
Modified: 2011-06-16 08:31 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Unterstein CLA 2011-06-15 01:51:43 EDT
Build Identifier: 1.6.12.20110613132200

Hey there,

i have a very similar problem like
https://bugs.eclipse.org/bugs/show_bug.cgi?id=223226

but i am running version 1.6.12 and the other bug should be closed to 1.6.1 :-(.

Here my project. Dont bother about the Generator class, its only for university ;)

package info.unterstein.hagen.moderne.ea6.a3;

import java.util.HashMap;

/**
 * Enables a more complex and generic caching aspect which can be extended to be
 * used in several use cases.
 * 
 * @author <a href="mailto:unterstein@me.com">Johannes Unterstein</a>
 * @param <k>
 *            the class of the keys
 * @param <V>
 *            the class of the cached values
 */
public abstract aspect CacheAspect<V> {
	private HashMap<Object, V> cache;

	public abstract pointcut cachePoint(Object key);

	V around(Object key) : cachePoint(key) {
		if (this.cache == null) {
			this.cache = new HashMap<Object, V>();
		}
		V result;
		if (this.cache.containsKey(key)) {
			result = this.cache.get(key);
		} else {
			result = proceed(key);
			this.cache.put(key, result);
		}
		return result;
	}
}

package info.unterstein.hagen.moderne.ea6.a3;

/**
 * An extension of the generic cache for the concrete use case of caching the
 * {@link DataGenerator}.
 * 
 * @author <a href="mailto:unterstein@me.com">Johannes Unterstein</a>
 */
public aspect DataGeneratorCacheAspect extends CacheAspect<Integer> {

	public pointcut cachePoint(Object key) : call(Integer DataGenerator.getData(Integer)) && args(key);
}

package info.unterstein.hagen.moderne.ea6.a3;

public class DataGenerator {

	private static final int MAGIC_NUMBER = 23;

	public Integer getData(Integer i) {
		try {
			Thread.sleep(100);
		} catch (InterruptedException ex) {
		}
		return new Integer(i * MAGIC_NUMBER);
	}
}


The eclipse AJDT cross reference view identifies the cross references between the pointcut and the according getData Method in the DataGenerator, but while running a test suite (see below) the compiler throws the following exception:

java.lang.ClassFormatError: Duplicate method name&signature in class file info/unterstein/hagen/moderne/ea6/a3/CacheAspect
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
	at java.lang.Class.getMethod0(Class.java:2670)
	at java.lang.Class.getMethod(Class.java:1603)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestLoader.getTest(JUnit3TestLoader.java:99)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestLoader.loadTests(JUnit3TestLoader.java:59)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


Cheers,
Johannes Unterstein







Here is the test suite:
package info.unterstein.hagen.moderne.ea6.a3;

import junit.framework.TestCase;

public class DataGeneratorTest extends TestCase {

	public void testGetData() {
		DataGenerator generator = new DataGenerator();
		assertEquals(new Integer(0), generator.getData(0));
		assertEquals(new Integer(23), generator.getData(1));
		assertEquals(new Integer(2 * 23), generator.getData(2));
	}

	public void testGetDataSpeedUp() {
		DataGenerator generator = new DataGenerator();
		long before = System.currentTimeMillis();
		for (int i = 0; i < 5; i++) {
			generator.getData(i);
		}
		for (int i = 0; i < 5; i++) {
			generator.getData(0);
		}
		long after = System.currentTimeMillis();
		assertTrue((after - before) < 600);
	}
}

Reproducible: Always

Steps to Reproduce:
1.Run the attached code
Comment 1 Andrew Clement CLA 2011-06-15 12:16:13 EDT
fixed ,thanks for the testcase.  will be in a dev build shortly.
Comment 2 Johannes Unterstein CLA 2011-06-16 08:31:18 EDT
Hey there,

does the fix can handle with this extended example as well?

package info.unterstein.hagen.moderne.ea6.a3;

import java.util.HashMap;

/**
 * Enables a more complex and generic caching aspect which can be extended to be
 * used in several use cases.
 * 
 * @author <a href="mailto:unterstein@me.com">Johannes Unterstein</a>
 * @param <k>
 *            the class of the keys
 * @param <V>
 *            the class of the cached values
 */
public abstract aspect CacheAspect<K, V> {
	private HashMap<K, V> cache;

	public abstract pointcut cachePoint(K key);

	V around(K key) : cachePoint(key) {
		if (this.cache == null) {
			this.cache = new HashMap<K, V>();
		}
		V result;
		if (this.cache.containsKey(key)) {
			result = this.cache.get(key);
		} else {
			result = proceed(key);
			this.cache.put(key, result);
		}
		return result;
	}
}

/**
 * An extension of the generic cache for the concrete use case of caching the
 * {@link DataGenerator}.
 * 
 * @author <a href="mailto:unterstein@me.com">Johannes Unterstein</a>
 */
public aspect DataGeneratorCacheAspect extends CacheAspect<Integer, Integer> {

	public pointcut cachePoint(Integer key) : call(Integer DataGenerator.getData(Integer)) && args(key);
}


Cheers and many thank,
Johannes