Skip to content

Commit d098473

Browse files
authored
InstrumentingLoader should use findLoadedClass (bazel-contrib#877)
Because execution of `java.lang.ClassLoader.defineClass` multiple times with same class name causes `java.lang.LinkageError` with message "duplicate class definition".
1 parent 120675c commit d098473

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

org.jacoco.core.test/src/org/jacoco/core/test/InstrumentingLoader.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ public InstrumentingLoader(Class<?> target) throws Exception {
5252
protected synchronized Class<?> loadClass(String name, boolean resolve)
5353
throws ClassNotFoundException {
5454
if (name.startsWith(scope)) {
55+
Class<?> c = findLoadedClass(name);
56+
if (c != null) {
57+
return c;
58+
}
5559
final byte[] bytes;
5660
try {
5761
bytes = TargetLoader.getClassDataAsBytes(delegate, name);
@@ -64,8 +68,7 @@ protected synchronized Class<?> loadClass(String name, boolean resolve)
6468
} catch (IOException e) {
6569
throw new ClassNotFoundException("Unable to instrument", e);
6670
}
67-
final Class<?> c = defineClass(name, instrumented, 0,
68-
instrumented.length);
71+
c = defineClass(name, instrumented, 0, instrumented.length);
6972
if (resolve) {
7073
resolveClass(c);
7174
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2009, 2019 Mountainminds GmbH & Co. KG and Contributors
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Evgeny Mandrikov - initial API and implementation
10+
*
11+
*******************************************************************************/
12+
package org.jacoco.core.test;
13+
14+
import org.junit.Test;
15+
16+
import static org.junit.Assert.assertSame;
17+
18+
/**
19+
* Unit test for {@link InstrumentingLoader}.
20+
*/
21+
public class InstrumentingLoaderTest {
22+
23+
@Test
24+
public void should_use_findLoadedClass() throws Exception {
25+
final InstrumentingLoader loader = new InstrumentingLoader(
26+
InstrumentingLoaderTest.class);
27+
final Class<?> c1 = loader
28+
.loadClass(InstrumentingLoaderTest.class.getName());
29+
final Class<?> c2 = loader
30+
.loadClass(InstrumentingLoaderTest.class.getName());
31+
assertSame(c1, c2);
32+
}
33+
34+
}

0 commit comments

Comments
 (0)