diff --git a/blackbox-test-inject/src/main/java/org/example/myapp/pkg_private/Adder.java b/blackbox-test-inject/src/main/java/org/example/myapp/pkg_private/Adder.java new file mode 100644 index 00000000..d219aedc --- /dev/null +++ b/blackbox-test-inject/src/main/java/org/example/myapp/pkg_private/Adder.java @@ -0,0 +1,5 @@ +package org.example.myapp.pkg_private; + + interface Adder { + int add(int a, int b); +} diff --git a/blackbox-test-inject/src/main/java/org/example/myapp/pkg_private/AdderImpl.java b/blackbox-test-inject/src/main/java/org/example/myapp/pkg_private/AdderImpl.java new file mode 100644 index 00000000..95c6d0c8 --- /dev/null +++ b/blackbox-test-inject/src/main/java/org/example/myapp/pkg_private/AdderImpl.java @@ -0,0 +1,12 @@ +package org.example.myapp.pkg_private; + +import jakarta.inject.Singleton; + +@Singleton +class AdderImpl implements Adder { + + @Override + public int add(int a, int b) { + return a + b; + } +} diff --git a/blackbox-test-inject/src/main/java/org/example/myapp/pkg_private/Calculator.java b/blackbox-test-inject/src/main/java/org/example/myapp/pkg_private/Calculator.java new file mode 100644 index 00000000..9e496f80 --- /dev/null +++ b/blackbox-test-inject/src/main/java/org/example/myapp/pkg_private/Calculator.java @@ -0,0 +1,16 @@ +package org.example.myapp.pkg_private; + +import jakarta.inject.Singleton; + +@Singleton +public class Calculator { + private final Adder adder; + + public Calculator(Adder adder) { + this.adder = adder; + } + + public int sum(int a, int b) { + return adder.add(a, b); + } +} diff --git a/blackbox-test-inject/src/test/java/org/example/myapp/pkg_private/PackagePrivateTest.java b/blackbox-test-inject/src/test/java/org/example/myapp/pkg_private/PackagePrivateTest.java new file mode 100644 index 00000000..ebc61ad4 --- /dev/null +++ b/blackbox-test-inject/src/test/java/org/example/myapp/pkg_private/PackagePrivateTest.java @@ -0,0 +1,23 @@ +package org.example.myapp.pkg_private; + +import io.avaje.inject.BeanScope; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class PackagePrivateTest { + + @Test + void package_private_wires() { + try (BeanScope beanScope = BeanScope.builder().build()) { + var calculator = beanScope.get(Calculator.class); + var adder = beanScope.get(Adder.class); + + assertThat(calculator).isNotNull(); + assertThat(adder).isNotNull(); + + int result = calculator.sum(3, 7); + assertThat(result).isEqualTo(10); + } + } +} diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java index 02509614..a46883ca 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java @@ -142,7 +142,8 @@ final class MethodReader { var beanTypes = BeanTypesPrism.getOptionalOn(element).map(BeanTypesPrism::value); beanTypes.ifPresent(t -> Util.validateBeanTypes(element, t)); this.typeReader = - new TypeReader(beanTypes.orElse(List.of()), genericType, returnElement, importTypes); + new TypeReader( + beanTypes.orElse(List.of()), genericType, returnElement, importTypes, element); typeReader.process(); MethodLifecycleReader lifecycleReader = new MethodLifecycleReader(returnElement, initMethod, destroyMethod); this.initMethod = lifecycleReader.initMethod(); diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/TypeExtendsReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/TypeExtendsReader.java index ffb23076..28d89739 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/TypeExtendsReader.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/TypeExtendsReader.java @@ -41,8 +41,15 @@ final class TypeExtendsReader { * The implied qualifier name based on naming convention. */ private String qualifierName; - - TypeExtendsReader(UType baseUType, TypeElement baseType, boolean factory, ImportTypeMap importTypes, boolean proxyBean) { + private Element source; + + TypeExtendsReader( + UType baseUType, + TypeElement baseType, + boolean factory, + ImportTypeMap importTypes, + boolean proxyBean, + Element source) { this.baseUType = baseUType; this.baseType = baseType; this.extendsInjection = new TypeExtendsInjection(baseType, factory, importTypes); @@ -54,6 +61,7 @@ final class TypeExtendsReader { this.controller = ControllerPrism.isPresent(baseType); this.closeable = closeableClient(baseType); this.autoProvide = autoProvide(); + this.source = source; } /** @@ -255,7 +263,11 @@ private void readInterfacesOf(TypeMirror anInterface) { } private boolean isPublic(Element element) { - return element != null && element.getModifiers().contains(Modifier.PUBLIC); + return element != null && element.getModifiers().contains(Modifier.PUBLIC) + || source != null + && APContext.elements() + .getPackageOf(element) + .equals(APContext.elements().getPackageOf(source)); } void validate() { diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/TypeReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/TypeReader.java index c0fd20fb..adc636dd 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/TypeReader.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/TypeReader.java @@ -7,6 +7,7 @@ import java.util.Set; import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; @@ -28,15 +29,16 @@ final class TypeReader { TypeElement beanType, ImportTypeMap importTypes, boolean factory) { - this(injectsTypes, genericType, true, beanType, importTypes, factory); + this(injectsTypes, genericType, true, beanType, importTypes, factory, beanType); } TypeReader( List injectsTypes, UType genericType, TypeElement returnElement, - ImportTypeMap importTypes) { - this(injectsTypes, genericType, false, returnElement, importTypes, false); + ImportTypeMap importTypes, + ExecutableElement source) { + this(injectsTypes, genericType, false, returnElement, importTypes, false, source); } private TypeReader( @@ -45,13 +47,15 @@ private TypeReader( boolean forBean, TypeElement beanType, ImportTypeMap importTypes, - boolean factory) { + boolean factory, + Element source) { this.injectsTypes = injectsTypes.stream().map(UType::parse).collect(toList()); this.forBean = forBean; this.beanType = beanType; this.importTypes = importTypes; final boolean proxyBean = forBean && ProxyPrism.isPresent(beanType); - this.extendsReader = new TypeExtendsReader(genericType, beanType, factory, importTypes, proxyBean); + this.extendsReader = + new TypeExtendsReader(genericType, beanType, factory, importTypes, proxyBean, source); this.annotationReader = new TypeAnnotationReader(beanType); } diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/InhPub.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/InhPub.java new file mode 100644 index 00000000..fc67d023 --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/InhPub.java @@ -0,0 +1,14 @@ +package io.avaje.inject.generator.models.valid; + +import io.avaje.inject.Bean; +import io.avaje.inject.Factory; +import io.avaje.inject.generator.models.valid.pkg_private.PubExposed; + +@Factory +public class InhPub { + + @Bean + PubExposed exposed() { + return new PubExposed(); + } +} diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/Adder.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/Adder.java new file mode 100644 index 00000000..c1b16275 --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/Adder.java @@ -0,0 +1,5 @@ +package io.avaje.inject.generator.models.valid.pkg_private; + + interface Adder { + int add(int a, int b); +} diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/AdderImpl.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/AdderImpl.java new file mode 100644 index 00000000..4364c606 --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/AdderImpl.java @@ -0,0 +1,12 @@ +package io.avaje.inject.generator.models.valid.pkg_private; + +import jakarta.inject.Singleton; + +@Singleton +class AdderImpl implements Adder { + + @Override + public int add(int a, int b) { + return a + b; + } +} diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/Calculator.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/Calculator.java new file mode 100644 index 00000000..8e4f85fb --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/Calculator.java @@ -0,0 +1,16 @@ +package io.avaje.inject.generator.models.valid.pkg_private; + +import jakarta.inject.Singleton; + +@Singleton +public class Calculator { + private final Adder adder; + + public Calculator(Adder adder) { + this.adder = adder; + } + + public int sum(int a, int b) { + return adder.add(a, b); + } +} \ No newline at end of file diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/NonPubBase.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/NonPubBase.java new file mode 100644 index 00000000..1858a442 --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/NonPubBase.java @@ -0,0 +1,11 @@ +package io.avaje.inject.generator.models.valid.pkg_private; + +/** + * Package protected (NOT public) + */ +class NonPubBase { + + public String hello() { + return "hello"; + } +} diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/NonPubIface.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/NonPubIface.java new file mode 100644 index 00000000..3eadf52d --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/NonPubIface.java @@ -0,0 +1,6 @@ +package io.avaje.inject.generator.models.valid.pkg_private; + +interface NonPubIface { + + String ifaceMethod(); +} diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/PubExposed.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/PubExposed.java new file mode 100644 index 00000000..fdf399dc --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/pkg_private/PubExposed.java @@ -0,0 +1,15 @@ +package io.avaje.inject.generator.models.valid.pkg_private; + +/** + * Extends a package protected class, implements package protected interface. + *

+ * Neither should be including in the generated isAddBeanFor(). + */ +public class PubExposed extends NonPubBase implements NonPubIface { + + @Override + public String ifaceMethod() { + return "ifaceMethod"; + } + +}