Skip to content

Ambiguous constructor error when defining an injected and non-injected c'tor #242

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 4 commits into from
Nov 1, 2022
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.9</version>
<version>8.10</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.9</version>
<version>8.10</version>
</parent>

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

<!-- test dependencies -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,25 @@ class RequestScope {
private static final String JAVALIN_CONTEXT = "io.javalin.http.Context";
private static final String HELIDON_REQ = "io.helidon.webserver.ServerRequest";
private static final String HELIDON_RES = "io.helidon.webserver.ServerResponse";
private static final Map<String, Handler> TYPES = new HashMap<>();

private static final String NIMA_REQ = "io.helidon.nima.webserver.http.ServerRequest";
private static final String NIMA_RES = "io.helidon.nima.webserver.http.ServerResponse";
private static final String HELIDON_REACTIVE_REQ = "io.helidon.reactive.webserver.ServerRequest";
private static final String HELIDON_REACTIVE_RES = "io.helidon.reactive.webserver.ServerResponse";

private static final Map<String, Handler> TYPES = new HashMap<>();
static {
TYPES.put(JEX_CONTEXT, new Jex());
TYPES.put(JAVALIN_CONTEXT, new Javalin());
TYPES.put(HELIDON_REQ, new Helidon());
TYPES.put(HELIDON_RES, new Helidon());
TYPES.put(JEX_CONTEXT, new JexHandler());
TYPES.put(JAVALIN_CONTEXT, new JavalinHandler());
final var helidon = new Helidon();
TYPES.put(HELIDON_REQ, helidon);
TYPES.put(HELIDON_RES, helidon);
final var helidonReactive = new HelidonReactive();
TYPES.put(HELIDON_REACTIVE_REQ, helidonReactive);
TYPES.put(HELIDON_REACTIVE_RES, helidonReactive);
final var helidonNima = new HelidonNima();
TYPES.put(NIMA_REQ, helidonNima);
TYPES.put(NIMA_RES, helidonNima);
}

/**
Expand Down Expand Up @@ -62,37 +74,48 @@ interface Handler {
String argumentName(String paramType);
}

/**
* Jex support for request scoping/BeanFactory.
*/
private static class Jex implements Handler {

@Override
public void factoryInterface(Append writer, String parentType) {
writer.append("BeanFactory<%s, %s>", parentType, "Context");
private static final class JexHandler extends ContextHandler {
private JexHandler() {
super(JEX_CONTEXT);
}
}

@Override
public void addImports(Set<String> importTypes) {
importTypes.add(Constants.BEAN_FACTORY);
importTypes.add(JEX_CONTEXT);
private static final class JavalinHandler extends ContextHandler {
private JavalinHandler() {
super(JAVALIN_CONTEXT);
}
}

@Override
public void writeCreateMethod(Append writer, String parentType) {
writer.append(" public %s create(Context context) {", parentType).eol();
private static final class Helidon extends RequestResponseHandler {
Helidon() {
super(HELIDON_REQ, HELIDON_RES);
}
}

@Override
public String argumentName(String paramType) {
return "context";
private static final class HelidonReactive extends RequestResponseHandler {
HelidonReactive() {
super(HELIDON_REACTIVE_REQ, HELIDON_REACTIVE_RES);
}
}

private static final class HelidonNima extends RequestResponseHandler {
HelidonNima() {
super(NIMA_REQ, NIMA_RES);
}
}


/**
* Javalin support for request scoping/BeanFactory.
* Single Context based handlers.
*/
private static class Javalin implements Handler {
private static abstract class ContextHandler implements Handler {

final String contextType;

private ContextHandler(String contextType) {
this.contextType = contextType;
}

@Override
public void factoryInterface(Append writer, String parentType) {
Expand All @@ -102,7 +125,7 @@ public void factoryInterface(Append writer, String parentType) {
@Override
public void addImports(Set<String> importTypes) {
importTypes.add(Constants.BEAN_FACTORY);
importTypes.add(JAVALIN_CONTEXT);
importTypes.add(contextType);
}

@Override
Expand All @@ -117,9 +140,17 @@ public String argumentName(String paramType) {
}

/**
* Helidon support for request scoping/BeanFactory.
* ServerRequest ServerResponse based Handlers.
*/
private static class Helidon implements Handler {
private static abstract class RequestResponseHandler implements Handler {

final String reqType;
final String resType;

RequestResponseHandler(String reqType, String resType) {
this.reqType = reqType;
this.resType = resType;
}

@Override
public void factoryInterface(Append writer, String parentType) {
Expand All @@ -129,8 +160,8 @@ public void factoryInterface(Append writer, String parentType) {
@Override
public void addImports(Set<String> importTypes) {
importTypes.add(Constants.BEAN_FACTORY2);
importTypes.add(HELIDON_REQ);
importTypes.add(HELIDON_RES);
importTypes.add(reqType);
importTypes.add(resType);
}

@Override
Expand All @@ -140,7 +171,7 @@ public void writeCreateMethod(Append writer, String parentType) {

@Override
public String argumentName(String paramType) {
if (paramType.equals(HELIDON_RES)) {
if (paramType.equals(resType)) {
return "response";
} else {
return "request";
Expand Down
8 changes: 4 additions & 4 deletions inject-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
<parent>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject-parent</artifactId>
<version>8.9</version>
<version>8.10</version>
</parent>

<artifactId>avaje-inject-test</artifactId>

<properties>
<jupiter.version>5.8.2</jupiter.version>
<mockito.version>4.6.1</mockito.version>
<jupiter.version>5.9.0</jupiter.version>
<mockito.version>4.7.0</mockito.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -124,7 +124,7 @@
<path>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject-generator</artifactId>
<version>8.9</version>
<version>8.10</version>
</path>
</annotationProcessorPaths>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.example.coffee.core;

import io.avaje.inject.Component;
import jakarta.inject.Inject;

@Component
public class WithMultiCtor {

final Steamer steamer;

public WithMultiCtor(Integer ignored) {
this.steamer = null;
}

@Inject
public WithMultiCtor(Steamer steamer) {
this.steamer = steamer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.example.coffee.core;

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

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

class WithMultiCtorTest {

@Test
void injectConstructor_expect_notAmbiguous() {
try (BeanScope beanScope = BeanScope.builder().build()) {
WithMultiCtor withMultiCtor = beanScope.get(WithMultiCtor.class);

assertThat(withMultiCtor.steamer).isNotNull();
}
}
}
4 changes: 2 additions & 2 deletions 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.9</version>
<version>8.10</version>
</parent>

<artifactId>avaje-inject</artifactId>
Expand Down Expand Up @@ -34,7 +34,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.6.1</version>
<version>4.7.0</version>
<optional>true</optional>
</dependency>

Expand Down
81 changes: 68 additions & 13 deletions inject/src/main/java/io/avaje/inject/spi/Builder.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,34 +98,84 @@ static Builder newBuilder(List<SuppliedBean> suppliedBeans, List<EnrichBean> enr
*/
void addInjector(Consumer<Builder> injector);

/**
* Get a dependency.
*/
<T> T get(Class<T> cls);

/**
* Get a named dependency.
*/
<T> T get(Class<T> cls, String name);

/**
* Get a dependency for the generic type.
*/
<T> T get(Type cls);

/**
* Get a named dependency for the generic type.
*/
<T> T get(Type cls, String name);

/**
* Get an optional dependency.
*/
<T> Optional<T> getOptional(Type cls);
<T> Optional<T> getOptional(Class<T> cls);

/**
* Get an optional named dependency.
*/
<T> Optional<T> getOptional(Class<T> cls, String name);

/**
* Get an optional dependency for the generic type.
*/
<T> Optional<T> getOptional(Type cls);

/**
* Get an optional named dependency for the generic type.
*/
<T> Optional<T> getOptional(Type cls, String name);

/**
* Get an optional dependency potentially returning null.
*/
<T> T getNullable(Type cls);
<T> T getNullable(Class<T> cls);

/**
* Get an optional named dependency potentially returning null.
*/
<T> T getNullable(Class<T> cls, String name);

/**
* Get an optional dependency potentially returning null for the generic type.
*/
<T> T getNullable(Type cls);

/**
* Get an optional named dependency potentially returning null for the generic type.
*/
<T> T getNullable(Type cls, String name);

/**
* Return Provider of T given the type.
*/
<T> Provider<T> getProvider(Type cls);
<T> Provider<T> getProvider(Class<T> cls);

/**
* Return Provider of T given the type and name.
*/
<T> Provider<T> getProvider(Class<T> cls, String name);

/**
* Return Provider of T given the generic type.
*/
<T> Provider<T> getProvider(Type cls);

/**
* Return Provider of T given the generic type and name.
*/
<T> Provider<T> getProvider(Type cls, String name);

/**
Expand All @@ -137,29 +187,34 @@ static Builder newBuilder(List<SuppliedBean> suppliedBeans, List<EnrichBean> enr
<T> Provider<T> getProviderFor(Class<?> cls, Type type);

/**
* Get a dependency.
* Get a list of dependencies for the type.
*/
<T> T get(Type cls);
<T> List<T> list(Class<T> type);

/**
* Get a named dependency.
* Get a list of dependencies for the generic type.
*/
<T> T get(Type cls, String name);
<T> List<T> list(Type type);

/**
* Get a list of dependencies for the type.
* Get a set of dependencies for the type.
*/
<T> List<T> list(Type interfaceType);
<T> Set<T> set(Class<T> type);

/**
* Get a set of dependencies for the type.
* Get a set of dependencies for the generic type.
*/
<T> Set<T> set(Type type);

/**
* Return a map of dependencies for the type keyed by qualifier name.
*/
<T> Set<T> set(Type interfaceType);
<T> Map<String, T> map(Class<T> type);

/**
* Return a map of dependencies keyed by qualifier name.
* Return a map of dependencies for the generic type keyed by qualifier name.
*/
<T> Map<String, T> map(Type interfaceType);
<T> Map<String, T> map(Type type);

/**
* Build and return the bean scope.
Expand Down
Loading