Skip to content

Commit 342b07e

Browse files
samebGuice Team
authored and
Guice Team
committed
Add a utility class for checking if Guice has enhanced a class (and returning the unenhanced version).
(Also changes the classname suffix to be a hex string instead of an int, which had previously included a leading negative sign, which was weird.) Fixes #1340 & fixes #187. PiperOrigin-RevId: 525256080
1 parent 356f6ba commit 342b07e

File tree

3 files changed

+122
-2
lines changed

3 files changed

+122
-2
lines changed

core/src/com/google/inject/internal/aop/AbstractGlueGenerator.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ protected AbstractGlueGenerator(Class<?> hostClass, String marker) {
102102

103103
/** Generates a unique name based on the original class name and marker. */
104104
private static String proxyName(String hostName, String marker, int hash) {
105-
int id = ((hash & 0x000FFFFF) | (COUNTER.getAndIncrement() << 20));
106-
String proxyName = hostName + marker + id;
105+
long id = ((hash & 0x000FFFFF) | (COUNTER.getAndIncrement() << 20));
106+
String proxyName = hostName + marker + Long.toHexString(id);
107107
if (proxyName.startsWith("java/") && !ClassDefining.hasPackageAccess()) {
108108
proxyName = '$' + proxyName; // can't define java.* glue in same package
109109
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (C) 2023 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.inject.util;
18+
19+
import com.google.inject.internal.BytecodeGen;
20+
import java.util.Optional;
21+
22+
/** Utilities for checking if classes are enhanced and/or getting the original un-enhanced class. */
23+
public final class Enhanced {
24+
private Enhanced() {}
25+
26+
/** Returns true if this is a class that Guice enhanced with AOP functionality. */
27+
public static boolean isEnhanced(Class<?> clazz) {
28+
return clazz.getSimpleName().contains(BytecodeGen.ENHANCER_BY_GUICE_MARKER);
29+
}
30+
31+
/**
32+
* If the input class is a class that {@link #isEnhanced} is true for, returns the un-enhanced
33+
* version of the class. Otherwise returns an empty optional.
34+
*/
35+
public static <T> Optional<Class<? super T>> unenhancedClass(Class<T> clazz) {
36+
return isEnhanced(clazz) ? Optional.of(clazz.getSuperclass()) : Optional.empty();
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.google.inject.util;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
import static com.google.common.truth.Truth8.assertThat;
5+
import static org.junit.Assume.assumeTrue;
6+
7+
import com.google.inject.AbstractModule;
8+
import com.google.inject.Guice;
9+
import com.google.inject.Injector;
10+
import com.google.inject.internal.InternalFlags;
11+
import com.google.inject.matcher.Matchers;
12+
import java.util.Optional;
13+
import org.aopalliance.intercept.MethodInterceptor;
14+
import org.aopalliance.intercept.MethodInvocation;
15+
import org.junit.Test;
16+
import org.junit.runner.RunWith;
17+
import org.junit.runners.JUnit4;
18+
19+
@RunWith(JUnit4.class)
20+
public final class EnhancedTest {
21+
@Test
22+
public void isEnhanced() {
23+
assumeTrue(InternalFlags.isBytecodeGenEnabled());
24+
25+
Injector injector = Guice.createInjector(new InterceptingModule());
26+
Foo foo = injector.getInstance(Foo.class);
27+
Bar bar = injector.getInstance(Bar.class);
28+
// Validate preconditions: foo is intercepted & bar isn't.
29+
assertThat(foo.foo()).isEqualTo("intercepted-foo");
30+
assertThat(bar.bar()).isEqualTo("bar");
31+
32+
// The actual tests.
33+
assertThat(Enhanced.isEnhanced(foo.getClass())).isTrue();
34+
assertThat(Enhanced.isEnhanced(bar.getClass())).isFalse();
35+
}
36+
37+
@Test
38+
public void unenhancedClass() {
39+
assumeTrue(InternalFlags.isBytecodeGenEnabled());
40+
41+
Injector injector = Guice.createInjector(new InterceptingModule());
42+
Foo foo = injector.getInstance(Foo.class);
43+
Bar bar = injector.getInstance(Bar.class);
44+
// Validate preconditions: foo is intercepted & bar isn't.
45+
assertThat(foo.foo()).isEqualTo("intercepted-foo");
46+
assertThat(bar.bar()).isEqualTo("bar");
47+
48+
// The actual tests.
49+
assertThat(Enhanced.unenhancedClass(foo.getClass())).isEqualTo(Optional.of(Foo.class));
50+
assertThat(Enhanced.unenhancedClass(bar.getClass())).isEmpty();
51+
}
52+
53+
private static class InterceptingModule extends AbstractModule {
54+
@Override
55+
protected void configure() {
56+
binder()
57+
.bindInterceptor(
58+
Matchers.only(Foo.class),
59+
Matchers.any(),
60+
new MethodInterceptor() {
61+
@Override
62+
public Object invoke(MethodInvocation i) throws Throwable {
63+
return "intercepted-" + i.proceed();
64+
}
65+
});
66+
bind(Foo.class);
67+
bind(Bar.class);
68+
}
69+
}
70+
71+
public static class Foo {
72+
public String foo() {
73+
return "foo";
74+
}
75+
}
76+
77+
public static class Bar {
78+
public String bar() {
79+
return "bar";
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)