Skip to content

Commit 4bab305

Browse files
committed
start
1 parent b15edcc commit 4bab305

File tree

10 files changed

+145
-55
lines changed

10 files changed

+145
-55
lines changed

blackbox-test-inject/pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
</dependencies>
9090
<build>
9191
<plugins>
92-
<!-- <plugin>
92+
<plugin>
9393
<groupId>io.avaje</groupId>
9494
<artifactId>avaje-inject-maven-plugin</artifactId>
9595
<version>${project.version}</version>
@@ -101,7 +101,7 @@
101101
</goals>
102102
</execution>
103103
</executions>
104-
</plugin> -->
104+
</plugin>
105105
<plugin>
106106
<groupId>org.apache.maven.plugins</groupId>
107107
<artifactId>maven-compiler-plugin</artifactId>

blackbox-test-inject/src/main/java/module-info.java

-27
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.example.myapp;
2+
3+
import java.lang.invoke.MethodHandles;
4+
import java.lang.invoke.MethodHandles.Lookup;
5+
6+
import io.avaje.inject.test.LookupProvider;
7+
import io.avaje.spi.ServiceProvider;
8+
9+
@ServiceProvider
10+
public class LookupsO implements LookupProvider {
11+
12+
@Override
13+
public Lookup provideLookup() {
14+
return MethodHandles.lookup();
15+
}
16+
}

inject-generator/src/test/java/io/avaje/inject/generator/InjectProcessorTest.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import javax.tools.ToolProvider;
2424

2525
import org.junit.jupiter.api.AfterEach;
26-
import org.junit.jupiter.api.Test;
2726

2827
class InjectProcessorTest {
2928

@@ -43,8 +42,8 @@ void deleteGeneratedFiles() {
4342
}
4443
}
4544

46-
//@Disabled
47-
@Test
45+
// @Disabled
46+
// @Test
4847
void testGeneration() throws Exception {
4948

5049
System.setProperty("append.debug", "true");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.avaje.inject.test;
2+
3+
import java.lang.invoke.MethodHandles.Lookup;
4+
5+
/**
6+
* Provides a Lookup instance for accessing entity/dto fields.
7+
*/
8+
public interface LookupProvider {
9+
10+
/**
11+
* Return the Lookup.
12+
*/
13+
Lookup provideLookup();
14+
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package io.avaje.inject.test;
2+
3+
import static java.util.stream.Collectors.toMap;
4+
5+
import java.lang.invoke.MethodHandles;
6+
import java.lang.invoke.MethodHandles.Lookup;
7+
import java.lang.invoke.VarHandle;
8+
import java.lang.reflect.Field;
9+
import java.lang.reflect.ParameterizedType;
10+
import java.lang.reflect.Type;
11+
import java.util.Map;
12+
import java.util.ServiceLoader;
13+
14+
/** Provides Lookup instances using potentially module specific Lookups. */
15+
final class Lookups {
16+
17+
// For public tests
18+
private static final Map<String, Lookup> MODULE_LOOKUP_MAP =
19+
ServiceLoader.load(LookupProvider.class).stream()
20+
.collect(toMap(p -> p.type().getModule().getName(), p -> p.get().provideLookup()));
21+
22+
private static final Lookup DEFAULT_LOOKUP = MethodHandles.publicLookup();
23+
24+
/** Return a Lookup ideally for the package associated with the given type. */
25+
static Lookup getLookup(Class<?> type) {
26+
return MODULE_LOOKUP_MAP.getOrDefault(type.getModule().getName(), DEFAULT_LOOKUP);
27+
}
28+
29+
static VarHandle getVarhandle(Class<?> testClass, Field field) {
30+
31+
try {
32+
var lookup = getLookup(testClass);
33+
34+
lookup =
35+
lookup.hasPrivateAccess()
36+
? MethodHandles.privateLookupIn(testClass, getLookup(testClass))
37+
: lookup;
38+
39+
return lookup.unreflectVarHandle(field);
40+
} catch (Exception e) {
41+
throw new IllegalStateException("Can't access field " + field, e);
42+
}
43+
}
44+
45+
public static Class<?> getaClass(Type generic) {
46+
if (generic instanceof Class) {
47+
return (Class<?>) generic;
48+
}
49+
if (generic instanceof ParameterizedType) {
50+
Type actual = ((ParameterizedType) generic).getActualTypeArguments()[0];
51+
if (actual instanceof Class) {
52+
return (Class<?>) actual;
53+
}
54+
if (actual instanceof ParameterizedType) {
55+
return (Class<?>) ((ParameterizedType) actual).getRawType();
56+
}
57+
}
58+
59+
return Object.class;
60+
}
61+
}

inject-test/src/main/java/io/avaje/inject/test/MetaReader.java

+31-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.avaje.inject.test;
22

33
import java.lang.annotation.Annotation;
4+
import java.lang.invoke.VarHandle;
45
import java.lang.reflect.Field;
56
import java.lang.reflect.Modifier;
67
import java.lang.reflect.ParameterizedType;
@@ -14,8 +15,6 @@
1415
import org.mockito.Captor;
1516
import org.mockito.Mock;
1617
import org.mockito.Spy;
17-
import org.mockito.internal.configuration.plugins.Plugins;
18-
import org.mockito.internal.util.reflection.GenericMaster;
1918

2019
import io.avaje.inject.BeanScope;
2120
import io.avaje.inject.BeanScopeBuilder;
@@ -26,6 +25,7 @@
2625
final class MetaReader {
2726

2827
private final SetupMethods methodFinder;
28+
final Class<?> testClass;
2929
final List<Field> captors = new ArrayList<>();
3030
final List<FieldTarget> mocks = new ArrayList<>();
3131
final List<FieldTarget> spies = new ArrayList<>();
@@ -41,6 +41,7 @@ final class MetaReader {
4141
boolean instancePlugin;
4242

4343
MetaReader(Class<?> testClass, Plugin plugin) {
44+
this.testClass = testClass;
4445
this.plugin = plugin;
4546
final var hierarchy = typeHierarchy(testClass);
4647
this.methodFinder = new SetupMethods(hierarchy);
@@ -54,9 +55,8 @@ final class MetaReader {
5455
boolean hasMocksOrSpies(Object testInstance) {
5556
if (testInstance == null) {
5657
return hasStaticMocksOrSpies() || methodFinder.hasStaticMethods();
57-
} else {
58-
return hasInstanceMocksOrSpies(testInstance) || methodFinder.hasInstanceMethods();
5958
}
59+
return hasInstanceMocksOrSpies(testInstance) || methodFinder.hasInstanceMethods();
6060
}
6161

6262
private boolean hasInstanceMocksOrSpies(Object testInstance) {
@@ -154,7 +154,7 @@ private void add(FieldTarget target, List<FieldTarget> instanceList, List<FieldT
154154
}
155155

156156
private FieldTarget newTarget(Field field) {
157-
return new FieldTarget(field, name(field));
157+
return new FieldTarget(field, name(field), Lookups.getVarhandle(testClass, field));
158158
}
159159

160160
private String name(Field field) {
@@ -178,9 +178,8 @@ private String name(Field field) {
178178
TestBeans setFromScope(TestBeans metaScope, Object testInstance) {
179179
if (testInstance != null) {
180180
return setForInstance(metaScope, testInstance);
181-
} else {
182-
return setForStatics(metaScope);
183181
}
182+
return setForStatics(metaScope);
184183
}
185184

186185
private TestBeans setForInstance(TestBeans metaScope, Object testInstance) {
@@ -189,7 +188,11 @@ private TestBeans setForInstance(TestBeans metaScope, Object testInstance) {
189188
BeanScope beanScope = metaScope.beanScope();
190189

191190
for (Field field : captors) {
192-
set(field, captorFor(field), testInstance);
191+
set(
192+
Modifier.isStatic(field.getModifiers()),
193+
Lookups.getVarhandle(testClass, field),
194+
captorFor(field),
195+
testInstance);
193196
}
194197
for (FieldTarget target : mocks) {
195198
target.setFromScope(beanScope, testInstance);
@@ -239,9 +242,12 @@ private TestBeans setForStatics(TestBeans metaScope) {
239242
private Object captorFor(Field field) {
240243
Class<?> type = field.getType();
241244
if (!ArgumentCaptor.class.isAssignableFrom(type)) {
242-
throw new IllegalStateException("@Captor field must be of the type ArgumentCaptor.\n Field: '" + field.getName() + "' has wrong type");
245+
throw new IllegalStateException(
246+
"@Captor field must be of the type ArgumentCaptor.\n Field: '"
247+
+ field.getName()
248+
+ "' has wrong type");
243249
}
244-
Class<?> cls = new GenericMaster().getGenericType(field);
250+
Class<?> cls = Lookups.getaClass(field.getGenericType());
245251
return ArgumentCaptor.forClass(cls);
246252
}
247253

@@ -308,8 +314,12 @@ private static void registerAsTestDouble(BeanScopeBuilder builder, FieldTarget t
308314
builder.bean(target.name(), target.type(), value);
309315
}
310316

311-
void set(Field field, Object val, Object testInstance) throws IllegalAccessException {
312-
Plugins.getMemberAccessor().set(field, testInstance, val);
317+
void set(boolean isStatic, VarHandle fieldHandle, Object val, Object testInstance) {
318+
if (isStatic) {
319+
fieldHandle.set(val);
320+
} else {
321+
fieldHandle.set(testInstance, val);
322+
}
313323
}
314324

315325
class FieldTarget {
@@ -319,11 +329,13 @@ class FieldTarget {
319329
private final boolean isStatic;
320330
private boolean pluginInjection;
321331
private boolean valueAlreadyProvided;
332+
private final VarHandle fieldHandle;
322333

323-
FieldTarget(Field field, String name) {
334+
FieldTarget(Field field, String name, VarHandle fieldHandle) {
324335
this.field = field;
325336
this.isStatic = Modifier.isStatic(field.getModifiers());
326337
this.name = name;
338+
this.fieldHandle = fieldHandle;
327339
}
328340

329341
@Override
@@ -344,11 +356,8 @@ boolean isStatic() {
344356
}
345357

346358
Object get(Object instance) {
347-
try {
348-
return Plugins.getMemberAccessor().get(field, instance);
349-
} catch (IllegalAccessException e) {
350-
throw new RuntimeException(e);
351-
}
359+
360+
return isStatic ? fieldHandle.get() : fieldHandle.get(instance);
352361
}
353362

354363
void setFromScope(BeanScope beanScope, Object testInstance) throws IllegalAccessException {
@@ -363,21 +372,21 @@ void setFromScope(BeanScope beanScope, Object testInstance) throws IllegalAccess
363372
final var typeArguments = parameterizedType.getActualTypeArguments();
364373

365374
if (rawType.equals(List.class)) {
366-
set(field, beanScope.list(typeArguments[0]), testInstance);
375+
set(isStatic, fieldHandle, beanScope.list(typeArguments[0]), testInstance);
367376
return;
368377
}
369378

370379
if (rawType.equals(Optional.class)) {
371-
set(field, beanScope.getOptional(typeArguments[0], name), testInstance);
380+
set(isStatic, fieldHandle, beanScope.getOptional(typeArguments[0], name), testInstance);
372381
return;
373382
}
374383
}
375384

376-
set(field, beanScope.get(type, name), testInstance);
385+
set(isStatic, fieldHandle, beanScope.get(type, name), testInstance);
377386
}
378387

379388
void setFromPlugin(Object value, Object testInstance) throws IllegalAccessException {
380-
set(field, value, testInstance);
389+
set(isStatic, fieldHandle, value, testInstance);
381390
}
382391

383392
void markForPluginInjection() {

inject-test/src/main/java/module-info.java

+1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616

1717
uses io.avaje.inject.test.TestModule;
1818
uses io.avaje.inject.test.Plugin;
19+
uses io.avaje.inject.test.LookupProvider;
1920
}

inject-test/src/test/java/io/avaje/inject/test/MetaReaderTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
class MetaReaderTest {
1818

1919
@Mock
20-
Pump pump;
20+
private Pump pump;
2121

2222
@Mock
2323
Grinder grinder;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.example.coffee.qualifier.members;
2+
3+
import java.lang.invoke.MethodHandles;
4+
import java.lang.invoke.MethodHandles.Lookup;
5+
6+
import io.avaje.inject.test.LookupProvider;
7+
import io.avaje.spi.ServiceProvider;
8+
9+
@ServiceProvider
10+
public class LookupsO implements LookupProvider {
11+
12+
@Override
13+
public Lookup provideLookup() {
14+
return MethodHandles.lookup();
15+
}
16+
}

0 commit comments

Comments
 (0)