Skip to content

Commit

Permalink
Fix for eagerInitSingletons attempting to instantiate prototype facto…
Browse files Browse the repository at this point in the history
…ry methods (#4950)

* Fix eagerInitSingletons attempting to create factory prototypes. Fixes #4929

* Add expectation no exception is thrown

* Add @SInCE javadoc
  • Loading branch information
jameskleeh committed Feb 18, 2021
1 parent 29158f0 commit 8d931d4
Show file tree
Hide file tree
Showing 42 changed files with 177 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,26 @@ default boolean hasDeclaredStereotype(@Nullable String annotation) {
return false;
}

/**
* Checks whether this object has any of the given stereotype directly declared on the object.
*
* @param annotations The annotations
* @return True if any of the given stereotypes are present
* @since 2.3.3
*/
@SuppressWarnings("unchecked")
default boolean hasDeclaredStereotype(@Nullable String... annotations) {
if (ArrayUtils.isEmpty(annotations)) {
return false;
}
for (String annotation : annotations) {
if (hasDeclaredStereotype(annotation)) {
return true;
}
}
return false;
}

/**
* Return the default values for the given annotation name.
* @param annotation The annotation name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
package io.micronaut.inject.configproperties;

import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.context.annotation.Requires;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;
import java.net.URL;

@Requires(property = "spec.name", value = "ValidatedConfigurationSpec")
@ConfigurationProperties("foo.bar")
public class ValidatedConfig {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ class ValidatedConfigurationSpec extends AbstractTypeElementSpec {

void "test validated config with invalid config"() {
given:
ApplicationContext applicationContext = new DefaultApplicationContext("test")
applicationContext.start()
ApplicationContext applicationContext = ApplicationContext.run(["spec.name": getClass().simpleName], "test")

when:
ValidatedConfig config = applicationContext.getBean(ValidatedConfig)
Expand All @@ -47,7 +46,10 @@ class ValidatedConfigurationSpec extends AbstractTypeElementSpec {

void "test validated config with valid config"() {
given:
ApplicationContext applicationContext = new DefaultApplicationContext("test")
ApplicationContext applicationContext = ApplicationContext.builder()
.properties(["spec.name": getClass().simpleName])
.environments("test")
.build()
applicationContext.environment.addPropertySource(PropertySource.of(
'foo.bar.url':'http://localhost',
'foo.bar.name':'test'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
package io.micronaut.inject.configproperties;

import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.context.annotation.Requires;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.net.URL;

@Requires(property = "spec.name", value = "ValidatedGetterConfigurationSpec")
@ConfigurationProperties("foo.bar")
public class ValidatedGetterConfig {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ class ValidatedGetterConfigurationSpec extends Specification {

void "test validated config with invalid config"() {
given:
ApplicationContext applicationContext = new DefaultApplicationContext("test")
applicationContext.start()
ApplicationContext applicationContext = ApplicationContext.run(["spec.name": getClass().simpleName], "test")

when:
ValidatedGetterConfig config = applicationContext.getBean(ValidatedGetterConfig)
Expand All @@ -44,7 +43,10 @@ class ValidatedGetterConfigurationSpec extends Specification {

void "test validated config with valid config"() {
given:
ApplicationContext applicationContext = new DefaultApplicationContext("test")
ApplicationContext applicationContext = ApplicationContext.builder()
.properties(["spec.name": getClass().simpleName])
.environments("test")
.build()
applicationContext.environment.addPropertySource(PropertySource.of(
'foo.bar.url':'http://localhost',
'foo.bar.name':'test'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.micronaut.inject.context

import io.micronaut.context.ApplicationContext
import spock.lang.Specification

class EagerInitSingletonsSpec extends Specification {

void "test eager init works with prototype factories"() {
when:
def context = ApplicationContext.builder()
.eagerInitSingletons(true)
.start()

then:
noExceptionThrown()
!Pojo.instantiated

cleanup:
context.close()
}
}
10 changes: 10 additions & 0 deletions inject-java/src/test/groovy/io/micronaut/inject/context/Pojo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.micronaut.inject.context;

public class Pojo {

public static boolean instantiated;

public Pojo() {
instantiated = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.micronaut.inject.context;

import io.micronaut.context.annotation.Factory;
import io.micronaut.context.annotation.Prototype;

@Factory
public class PrototypeFactory {

@Prototype
Pojo prototype() {
return new Pojo();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,17 @@
*/
package io.micronaut.inject.factory.inject

import io.micronaut.context.BeanContext
import io.micronaut.context.ApplicationContext
import spock.lang.Specification
import spock.lang.Unroll

class InjectExistingFactorySpec extends Specification {

@Unroll
void "test that it is possible inject an existing factory instance without a circular dependency issue"() {

given:
MyFactory myFactory = new MyFactory()
BeanContext ctx = BeanContext.run()
ApplicationContext ctx = ApplicationContext.run(["spec.name": getClass().simpleName])
ctx.inject(myFactory)

expect:
Expand All @@ -37,7 +36,5 @@ class InjectExistingFactorySpec extends Specification {

where:
times << [1,2,3,4,5,6,7,9,10]


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@

import io.micronaut.context.annotation.Factory;
import io.micronaut.context.annotation.Prototype;
import io.micronaut.context.annotation.Requires;

import javax.inject.Inject;

@Requires(property = "spec.name", value = "InjectExistingFactorySpec")
@Factory
public class MyFactory {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
package io.micronaut.inject.factory.nullreturn;

import io.micronaut.context.annotation.Factory;
import io.micronaut.context.annotation.Requires;

@Requires(property = "spec.name", value = "NullReturnFactorySpec")
@Factory
public class FactoryConstructor {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class Test2 {}

void "test factory that returns null"() {
given:
BeanContext beanContext = ApplicationContext.run()
BeanContext beanContext = ApplicationContext.run(["spec.name": getClass().simpleName])
NullableFactory factory = beanContext.getBean(NullableFactory)

when:
Expand Down Expand Up @@ -124,7 +124,7 @@ class Test2 {}

void "test it works as expected nested resolution"() {
given:
BeanContext beanContext = ApplicationContext.run()
BeanContext beanContext = ApplicationContext.run(["spec.name": getClass().simpleName])
NullableFactory factory = beanContext.getBean(NullableFactory)

expect:
Expand All @@ -141,7 +141,7 @@ class Test2 {}

void "test each bean on a class with null factory"() {
given:
BeanContext beanContext = ApplicationContext.run()
BeanContext beanContext = ApplicationContext.run(["spec.name": getClass().simpleName])

expect:
beanContext.getBeansOfType(DProcessor).size() == 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
*/
package io.micronaut.inject.failures.ctorcirculardependency;

import io.micronaut.context.annotation.Requires;

import javax.inject.Singleton;

@Requires(property = "spec.name", value = "ConstructorCircularDependencyFailureSpec")
@Singleton
public class A {
public A(C c) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
*/
package io.micronaut.inject.failures.ctorcirculardependency;

import io.micronaut.context.annotation.Requires;

import javax.inject.Inject;
import javax.inject.Singleton;

@Requires(property = "spec.name", value = "ConstructorCircularDependencyFailureSpec")
@Singleton
public class B {
@Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class ConstructorCircularDependencyFailureSpec extends Specification {

void "test simple constructor circular dependency failure"() {
given:
BeanContext context = new DefaultBeanContext()
context.start()
ApplicationContext context = ApplicationContext.run(["spec.name": getClass().simpleName])

when:"A bean is obtained that has a setter with @Inject"
B b = context.getBean(B)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
*/
package io.micronaut.inject.failures.ctorexception;

import io.micronaut.context.annotation.Requires;

import javax.inject.Singleton;

@Requires(property = "spec.name", value = "ConstructorExceptionSpec")
@Singleton
public class A {
public A(C c) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
*/
package io.micronaut.inject.failures.ctorexception;

import io.micronaut.context.annotation.Requires;

import javax.inject.Singleton;

@Requires(property = "spec.name", value = "ConstructorExceptionSpec")
@Singleton
public class C {
public C() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,15 @@
*/
package io.micronaut.inject.failures.ctorexception

import io.micronaut.context.BeanContext
import io.micronaut.context.DefaultBeanContext
import io.micronaut.context.ApplicationContext
import io.micronaut.context.exceptions.BeanInstantiationException
import io.micronaut.context.exceptions.DependencyInjectionException
import spock.lang.Specification

class ConstructorExceptionSpec extends Specification {

void "test error message when exception occurs in constructor"() {
given:
BeanContext context = new DefaultBeanContext()
context.start()
ApplicationContext context = ApplicationContext.run(["spec.name": getClass().simpleName])

when:"A bean is obtained that has a setter with @Inject"
B b = context.getBean(B)
Expand All @@ -39,6 +36,9 @@ Error instantiating bean of type [io.micronaut.inject.failures.ctorexception.A]
Message: bad
Path Taken: B.a --> new A([C c])'''

cleanup:
context.close()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
*/
package io.micronaut.inject.failures.fieldcirculardependency;

import io.micronaut.context.annotation.Requires;

import javax.inject.Singleton;

@Requires(property = "spec.name", value = "FieldCircularDependencyFailureSpec")
@Singleton
public class A {

public A(C c) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
*/
package io.micronaut.inject.failures.fieldcirculardependency;

import io.micronaut.context.annotation.Requires;

import javax.inject.Inject;
import javax.inject.Singleton;

@Requires(property = "spec.name", value = "FieldCircularDependencyFailureSpec")
@Singleton
public class B {
@Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.micronaut.inject.failures.fieldcirculardependency

import io.micronaut.context.ApplicationContext
import io.micronaut.context.BeanContext
import io.micronaut.context.DefaultBeanContext
import io.micronaut.context.exceptions.CircularDependencyException
Expand All @@ -24,8 +25,7 @@ class FieldCircularDependencyFailureSpec extends Specification {

void "test simple field circular dependency failure"() {
given:
BeanContext context = new DefaultBeanContext()
context.start()
ApplicationContext context = ApplicationContext.run(["spec.name": getClass().simpleName])

when:"A bean is obtained that has a setter with @Inject"
B b = context.getBean(B)
Expand All @@ -42,5 +42,8 @@ B.a --> new A([C c]) --> C.b
| |
| |
+-------------------------+'''

cleanup:
context.close()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class FieldDependencyMissingFailureSpec extends Specification {
Failed to inject value for field [a] of class: io.micronaut.inject.failures.fielddependencymissing.B
Path Taken: B.a'''

cleanup:
context.close()
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
*/
package io.micronaut.inject.failures.nesteddependency;

import io.micronaut.context.annotation.Requires;

import javax.inject.Singleton;

@Requires(property = "spec.name", value = "NestedDependencyFailureSpec")
@Singleton
public class A {
public A(C c) {
Expand Down
Loading

0 comments on commit 8d931d4

Please sign in to comment.