From d5a2470cd8ce43339a4f021bc697df6b37cf6380 Mon Sep 17 00:00:00 2001 From: Artyom Drozdov Date: Thu, 21 Nov 2013 21:30:13 +0400 Subject: [PATCH 1/2] fix: StackOverflowError for singleton scope --- .../processing/EBeanProcessor.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanProcessor.java index 899a24500b..7f1da39e9c 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanProcessor.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanProcessor.java @@ -94,6 +94,10 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder eBeansHo holder.initActivityRef = helper.castContextToActivity(holder, holder.initIfActivityBody); } + EBean eBeanAnnotation = element.getAnnotation(EBean.class); + EBean.Scope eBeanScope = eBeanAnnotation.scope(); + boolean hasSingletonScope = eBeanScope == EBean.Scope.Singleton; + { // Constructor @@ -113,13 +117,11 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder eBeansHo constructorBody.assign(contextField, constructorContextParam); - constructorBody.invoke(init); + if (!hasSingletonScope) { + constructorBody.invoke(init); + } } - EBean eBeanAnnotation = element.getAnnotation(EBean.class); - EBean.Scope eBeanScope = eBeanAnnotation.scope(); - boolean hasSingletonScope = eBeanScope == EBean.Scope.Singleton; - { // Factory method @@ -141,6 +143,7 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder eBeansHo ._then(); JVar previousNotifier = holder.replacePreviousNotifierWithNull(creationBlock); creationBlock.assign(instanceField, _new(holder.generatedClass).arg(factoryMethodContextParam.invoke("getApplicationContext"))); + creationBlock.invoke(instanceField, init); holder.resetPreviousNotifier(creationBlock, previousNotifier); factoryMethodBody._return(instanceField); From 95f02ca2b381debe78a444db991472dae9e7119c Mon Sep 17 00:00:00 2001 From: Artyom Drozdov Date: Fri, 22 Nov 2013 22:29:00 +0400 Subject: [PATCH 2/2] add: tests for singletons with cyclic dependencies --- .../test15/ebean/CyclicSingletonTest.java | 23 ++++++++++++++++ .../test15/ebean/SomeCyclicSingletonA.java | 27 +++++++++++++++++++ .../test15/ebean/SomeCyclicSingletonB.java | 27 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/ebean/CyclicSingletonTest.java create mode 100644 AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ebean/SomeCyclicSingletonA.java create mode 100644 AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ebean/SomeCyclicSingletonB.java diff --git a/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/ebean/CyclicSingletonTest.java b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/ebean/CyclicSingletonTest.java new file mode 100644 index 0000000000..3acd71aae4 --- /dev/null +++ b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/ebean/CyclicSingletonTest.java @@ -0,0 +1,23 @@ +package org.androidannotations.test15.ebean; + +import static org.fest.assertions.Assertions.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.androidannotations.test15.AndroidAnnotationsTestRunner; +import org.androidannotations.test15.EmptyActivityWithoutLayout_; + +@RunWith(AndroidAnnotationsTestRunner.class) +public class CyclicSingletonTest { + + @Test + public void cyclic_singleton() { + EmptyActivityWithoutLayout_ context = new EmptyActivityWithoutLayout_(); + SomeCyclicSingletonA_ singletonA = SomeCyclicSingletonA_.getInstance_(context); + SomeCyclicSingletonB_ singletonB = SomeCyclicSingletonB_.getInstance_(context); + assertThat(singletonA.singletonB).isSameAs(singletonB); + assertThat(singletonB.singletonA).isSameAs(singletonA); + } + +} diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ebean/SomeCyclicSingletonA.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ebean/SomeCyclicSingletonA.java new file mode 100644 index 0000000000..ce94d82ce1 --- /dev/null +++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ebean/SomeCyclicSingletonA.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2010-2013 eBusiness Information, Excilys Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed To in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.androidannotations.test15.ebean; + +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EBean; + +@EBean(scope = EBean.Scope.Singleton) +public class SomeCyclicSingletonA { + + @Bean + SomeCyclicSingletonB singletonB; + +} diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ebean/SomeCyclicSingletonB.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ebean/SomeCyclicSingletonB.java new file mode 100644 index 0000000000..4ec2b7fa6e --- /dev/null +++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ebean/SomeCyclicSingletonB.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2010-2013 eBusiness Information, Excilys Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed To in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.androidannotations.test15.ebean; + +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EBean; + +@EBean(scope = EBean.Scope.Singleton) +public class SomeCyclicSingletonB { + + @Bean + SomeCyclicSingletonA singletonA; + +}