Skip to content

#243 - Fix for ClassCastException with generic types #248

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion blackbox-test-inject/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>avaje-inject-parent</artifactId>
<groupId>io.avaje</groupId>
<version>8.10</version>
<version>8.11-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
4 changes: 2 additions & 2 deletions inject-generator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject-parent</artifactId>
<version>8.10</version>
<version>8.11-SNAPSHOT</version>
</parent>

<artifactId>avaje-inject-generator</artifactId>
Expand All @@ -16,7 +16,7 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject</artifactId>
<version>8.10</version>
<version>8.11-SNAPSHOT</version>
</dependency>

<!-- test dependencies -->
Expand Down
4 changes: 2 additions & 2 deletions inject-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject-parent</artifactId>
<version>8.10</version>
<version>8.11-SNAPSHOT</version>
</parent>

<artifactId>avaje-inject-test</artifactId>
Expand Down Expand Up @@ -124,7 +124,7 @@
<path>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject-generator</artifactId>
<version>8.10</version>
<version>8.11-SNAPSHOT</version>
</path>
</annotationProcessorPaths>
</configuration>
Expand Down
17 changes: 17 additions & 0 deletions inject-test/src/test/java/org/example/circular/CupholderTest.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
package org.example.circular;

import io.avaje.inject.BeanScope;
import io.avaje.inject.xtra.ApplicationScope;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

public class CupholderTest {

@Test
void mockOne() {
try (BeanScope beanScope = BeanScope.builder().forTesting()
.mock(Cupholder.class)
.build()) {

Cupholder cupholder = beanScope.get(Cupholder.class);
assertThat(cupholder.hello()).isNull();

List<Cupholder> all = beanScope.list(Cupholder.class);
assertThat(all).hasSize(1);
}
}

@Test
void circularDependency_via_providerInterface() {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.example.generic.repo;

public abstract class AbstractRepo<T> {

public abstract T get();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.example.generic.repo;

import io.avaje.inject.BeanScope;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class GenericWithMockTest {

@Test
void withMock() {
try (BeanScope beanScope = BeanScope.builder().forTesting()
.mock(MapRepo1.class)
.build()) {

ServiceClass serviceClass = beanScope.get(ServiceClass.class);
MapRepo1 mapRepo1 = beanScope.get(MapRepo1.class);
assertThat(mapRepo1.get()).isNull();

MapRepo2 mapRepo2 = beanScope.get(MapRepo2.class);
assertThat(mapRepo2.get()).isNotNull();
assertThat(serviceClass.map2.get()).isNotNull();
}
}

@Test
void wireNoMocks() {
try (BeanScope beanScope = BeanScope.builder().build()) {
var serviceClass = beanScope.get(ServiceClass.class);
String value = serviceClass.process();

assertThat(value).isEqualTo("{=Model1}|{=Model2}");
}
}
}
12 changes: 12 additions & 0 deletions inject-test/src/test/java/org/example/generic/repo/MapRepo1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.example.generic.repo;

import jakarta.inject.Singleton;

@Singleton
public class MapRepo1 extends AbstractRepo<Model1> {

@Override
public Model1 get() {
return new Model1();
}
}
12 changes: 12 additions & 0 deletions inject-test/src/test/java/org/example/generic/repo/MapRepo2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.example.generic.repo;

import jakarta.inject.Singleton;

@Singleton
public class MapRepo2 extends AbstractRepo<Model2> {

@Override
public Model2 get() {
return new Model2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.example.generic.repo;

public interface MapService<T> {

T get();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.example.generic.repo;

import jakarta.inject.Singleton;

import java.util.Map;

@Singleton
public class MapService1 implements MapService<Map<String, Model1>> {

final MapRepo1 repo;

public MapService1(MapRepo1 repo) {
this.repo = repo;
}

@Override
public Map<String, Model1> get() {
return Map.of("", repo.get());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.example.generic.repo;

import jakarta.inject.Singleton;

import java.util.Map;

@Singleton
public class MapService2 implements MapService<Map<String, Model2>> {

final MapRepo2 repo;

public MapService2(MapRepo2 repo) {
this.repo = repo;
}

@Override
public Map<String, Model2> get() {
return Map.of("", repo.get());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.example.generic.repo;

public class Model1 {

@Override
public String toString() {
return "Model1";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.example.generic.repo;

public class Model2 {

@Override
public String toString() {
return "Model2";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.example.generic.repo;

import jakarta.inject.Singleton;

import java.util.Map;

@Singleton
public class ServiceClass {

final MapService<Map<String, Model1>> map1;
final MapService<Map<String, Model2>> map2;

public ServiceClass(MapService<Map<String, Model1>> map1, MapService<Map<String, Model2>> map2) {
this.map1 = map1;
this.map2 = map2;
}

public String process() {
Map<String, Model1> m1 = map1.get();
Map<String, Model2> m2 = map2.get();
return m1.toString() + "|" + m2.toString();
}
}
2 changes: 1 addition & 1 deletion inject/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject-parent</artifactId>
<version>8.10</version>
<version>8.11-SNAPSHOT</version>
</parent>

<artifactId>avaje-inject</artifactId>
Expand Down
13 changes: 8 additions & 5 deletions inject/src/main/java/io/avaje/inject/spi/DBeanMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.avaje.inject.BeanScope;
import jakarta.inject.Provider;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.LinkedHashMap;
Expand Down Expand Up @@ -145,8 +146,10 @@ boolean isSupplied(String qualifierName, Type... types) {
DContextEntry entry = beans.get(type.getTypeName());
if (entry != null) {
DContextEntryBean suppliedBean = entry.supplied(qualifierName);
if (suppliedBean != null && types.length > 1) {
addSuppliedFor(type, types, suppliedBean);
if (suppliedBean != null) {
if (types.length > 1) {
addSuppliedFor(type, types, suppliedBean);
}
return true;
}
}
Expand All @@ -156,12 +159,12 @@ boolean isSupplied(String qualifierName, Type... types) {
}

/**
* Register the suppliedBean entry with other types (like other interfaces)
* IF those types don't already have a registered entry.
* Register the suppliedBean entry with parameterized types IF those types
* don't already have a registered entry.
*/
private void addSuppliedFor(Type matchType, Type[] types, DContextEntryBean suppliedBean) {
for (Type type : types) {
if (type != matchType) {
if (type != matchType && type instanceof ParameterizedType) {
beans.computeIfAbsent(type.getTypeName(), s -> new DContextEntry()).add(suppliedBean);
}
}
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<groupId>io.avaje</groupId>
<artifactId>avaje-inject-parent</artifactId>
<version>8.10</version>
<version>8.11-SNAPSHOT</version>
<packaging>pom</packaging>
<name>avaje inject parent</name>
<description>parent pom for avaje inject library</description>
Expand Down