[ 
https://issues.apache.org/jira/browse/FELIX-4984?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14662878#comment-14662878
 ] 

Pierre De Rop commented on FELIX-4984:
--------------------------------------

So, I think I reproduced the issue with DEBUG logs. I introduced a new 
"WRITE_LOGS_TO_FILE" variable in the ComponentTestBase class in order to allow 
the CircularReferenceTest to log to a file in /tmp asynchronously instead of 
logging into the BndTools console.

The concerned test is "test_A11_B0n_delayed_B_first" test (the assert fails at 
line 157).

Please look into the attached log file ( 
org.apache.felix.scr.integration.CircularReferenceTest.test_A11_B0n_delayed_B_first.log),
 which is the log file for the failing test and look for the "detected 
problems", line 1095

So, here, the "A.setB(B b)"  method is indirectly called by the 
SingleComponentManager.createComponent() method, which opens the 
DependencyManager, (the open method calls "A.setB(B b)"). You can check this 
from the stacktrace line 1098

Then, concurrently (see at line 1142), the ComponentActor thread calls 
"invokeBindMethodLate", which ends up calling the "A.setB(B b)" method a second 
time.

My theory is the following (not sure, it's a supposition, please confirm this): 
I think that from the integration test, when the ServiceReference on B is 
dereferenced (line 146), then when the SingleComponentManager.createComponent 
method creates B, this method (at the end) calls " 
activator.missingServicePresent" line 140. And this method seems to find A 
component (because at this point, A is in the m_missingDependencies table). So 
a task is scheduled in the ComponentActor thread which ends up calling the 
A.setB(B b) method at the same time A is created (at the same time we are 
concurrently executing from the main thread the code called from the line 152 
in the CircularReferenceTest). And when we are execute code from line 152 
(CircularReferenceTest.java), we are currently in the 
SingleComponentManager.createComponent method (for the A component), and the 
DependencyManager.open has been called and has already called "A.setB(b b)" 
method.

So, this results in two invocations on A.setB(B b) method.
Is my analysis correct or is all this a result of a side effect on my porting 
of SCR integration tests under bndtools ?

Hope you will find interesting information in the DEBUG logs.

Thank you;

> Issues in CircularReferenceTest
> -------------------------------
>
>                 Key: FELIX-4984
>                 URL: https://issues.apache.org/jira/browse/FELIX-4984
>             Project: Felix
>          Issue Type: Bug
>          Components: Declarative Services (SCR)
>            Reporter: Pierre De Rop
>            Priority: Minor
>
> This issue is described in the dev mailing list, in 
> http://www.mail-archive.com/[email protected]/msg37281.html
> while working on FELIX-4955, I sometimes have the CircularReferenceTest 
> failing.
> Everything is located in my sandbox, in 
> http://svn.apache.org/repos/asf/felix/sandbox/pderop/dependencymanager.ds/
> To reproduce the test:
> install eclipse Mars
> install latest bndtools using "install new software" from Eclipse, and then 
> add latest stable release from http://dl.bintray.com/bndtools/bndtools/latest/
> install a java8 runtime (I'm using oracle java8 1.8.0_45, 64 bit version). 
> The whole new dependencymanager.ds project is intented to be build in java8.
> checkout my sandbox:
> $ svn checkout 
> http://svn.apache.org/repos/asf/felix/sandbox/pderop/dependencymanager.ds
> go to "dependencymanager.ds" directory:
> $ cd dependencymanager.ds/
> due to a pending issue, you have to first build the DM bnd annotation plugin 
> before importing the project into eclipse. to do so, just type:
> $ ./gradlew org.apache.felix.dependencymanager.annotation:jar
> now launch eclipse and use the the dependencymanager/ds directory as the 
> workspace dir for Eclipse.
> switch to BndTools perpective.
> import the bndtools project into eclipse: Import -> Existing Projects into 
> Workspace -> Browse -> select dependencymanager.ds directory (it is proposed 
> by default).
> normally, and hopefully, everything should compile fine. Junit tests are left 
> in org.apache.felix.dependencymanager.ds/ directory and integration tests are 
> located in org.apache.felix.dependencymanager.ds.itest/ directory.
> Open under Eclipse the 
> org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/CircularReferenceTest.java
> I slightly modified it in order to dump stack traces when A component is 
> bound multiple times to the same B instance.
> (I believe that only delayed components are concerned by the issue).
> For example, in the test_A11_B0n_delayed_A_first() method, I added a call to 
> "assertABoundToOneB(a)" like this:
> {code}
>     @Test
>     public void test_A11_B0n_delayed_A_first() throws InvalidSyntaxException
>     {
>         String componentNameA = "4.1.A.1.1.dynamic";
>         final ComponentConfigurationDTO componentA = 
> findComponentConfigurationByName( componentNameA, 
> ComponentConfigurationDTO.SATISFIED );
>         String componentNameB = "4.1.B.0.n.dynamic";
>         final ComponentConfigurationDTO componentB = 
> findComponentConfigurationByName( componentNameB, 
> ComponentConfigurationDTO.SATISFIED );
>         delay();
>         A a = getServiceFromConfiguration(componentA, A.class);
>         assertABoundToOneB(a);
>         delay(); //async binding of a to b after circular ref detected
>         B b = getServiceFromConfiguration(componentB, B.class);
>         assertEquals( 1, b.getAs().size() );
>     }
> {code}
> the "assertABoundToOneB(a)" call does this:
> {code}
>     private void assertABoundToOneB(A a) {
>         if (a.getBs().size() != 1) {
>             System.err.println("detected problem ...");
>             a.dumpStackTracesWhenBWasBound();
>         }
>         assertEquals( 1, a.getBs().size());
>     }
> {code}
> And stacktraces will be dumped in order to determine why A was bound two 
> times to the same B instance.
> it's possible that you have to run several times the "CircularReferenceTest" 
> test before having a failure (and some stacktraces).
> Thanks.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to