[SPR-9288] JMX related failures in spring-context tests Created: 30/Mar/12  Updated: 29/Nov/12  Resolved: 29/Nov/12

Status: Resolved
Project: Spring Framework
Component/s: [Build]
Affects Version/s: 3.2 M1
Fix Version/s: 3.2 RC2

Type: Task Priority: Minor
Reporter: Rossen Stoyanchev Assignee: Phil Webb
Resolution: Fixed Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by SPR-10030 MBeanServerFactoryBeanTests.testWithL... Resolved
is duplicated by SPR-10031 JmxUtilsTests.testLocatePlatformMBean... Resolved
Days since last comment: 5 years, 1 day ago
Last commented by a User: false
Last updater: Phil Webb

 Description   

The failure occurs when I run all spring-context tests from the command line. It doesn't fail when running the test alone, the tests in the same package, or all tests inside Eclipse.

The test creates an MBeanServer via javax.management.MBeanServerFactory, then tries to check if an MBeanServerFactoryBean will locate that same instance. The assertSame on line 65 fails because more than one MBeanServer instances were found and the first one returned was not the same instance.

Running gradle in debug mode and using breakpoints in addMBeanServer() and removeMBeanServer() of MBeanServerFactory, I was able to find one case where an MBeanServer is added but not removed. It happens in AdvisedJRubyScriptFactoryTests inside JRuby itself when Spring tries to load a script via JRubyScriptFactory. So it looks like a side effect, which explains why the failure doesn't occur when running a single test but not why it doesn't fail inside Eclipse.

I experimented with a tearDown() method in AdvisedJRubyScriptFactoryTests, which looks for and releases any MBeanServers it finds but that caused a failure in JmxUtilsTests.testLocatePlatformMBeanServer. So clearly not a good fix. Furthermore the fact this is an environment-sensitive issue makes even more hesitant to go any further.



 Comments   
Comment by Chris Beams [ 06/Apr/12 ]

Rossen, I assume you meant that this affects version 3.2 M1, not 3.1.1?

Comment by Rossen Stoyanchev [ 06/Apr/12 ]

Yes I meant 3.2 M1

Comment by David Bright [ 13/Jun/12 ]

I ran in to this problem today. I'm not entirely sure what kind of solution you guys are looking for this problem, but here is the one I used that wasn't just disabling the assertion for this test.

In jmx/support/JmxUtils.java, I changed lines 112-114 to read

112 - ". Returning last from list.");
113 - }
114 - server = servers.get(servers.size()-1);

From my understanding, these are all internal tests, this shouldn't be a problem. Granted, it's not a permanent solution, but it works. This affected none of the other tests (at least in a negative fashion. I'm unsure if others after this one were throwing warnings as well ), and the build on my machine completed successfully.

Comment by Rob Winch [ 16/Jul/12 ]

This issue seems to be related to the order the tests are executed in. Eclipse will determine the order the tests are executed in differently than Gradle. I suspect that Gradle's test ordering is somewhat environment specific (which is why only some see the issue). To get some consistent behavior in an isolated fashion and within your IDE you can create a Test Suite. For example the following tests should pass:

@RunWith(Suite.class)
@Suite.SuiteClasses({ AnnotationMetadataAssemblerTests.class,
    MBeanServerFactoryBeanTests.class,
    JmxUtilsTests.class,
    AdvisedJRubyScriptFactoryTests.class})
public class Spr9288WorksTestSuite {
}

To see the issues appear you can create the following Test Suite.

@RunWith(Suite.class)
@Suite.SuiteClasses({ AdvisedJRubyScriptFactoryTests.class,
    AnnotationMetadataAssemblerTests.class,
    MBeanServerFactoryBeanTests.class,
    JmxUtilsTests.class})
public class Spr9288TestSuite {
}

You will notice there are similar issues within AnnotationMetadataAssemblerTests that have appeared on the forums. An example failure is:

AnnotationMetadataAssemblerTests.testWithCglibProxy(org.springframework.jmx.export.annotation.AnnotationMetadataAssemblerTests)
javax.management.InstanceNotFoundException: spring:bean=test,proxy=true

It appears the in AnnotationMetadataAssemblerTests are related to having multiple MBeanServer's running at the same time as well. Should I spawn a new JIRA for these additional failures or should we include these within the original JIRA?

Comment by Rossen Stoyanchev [ 16/Jul/12 ]

Modified title (was: "Test failure in MBeanServerFactoryBeanTests.testWithLocateExistingAndExistingServer")

I can confirm the test failures occur within Eclipse as well as long as AdvisedJRubyScriptFactoryTests is ahead of either AnnotationMetadataAssemblerTests or MBeanServerFactoryBeanTests.

In other words both of these fail:

@RunWith(Suite.class)
@Suite.SuiteClasses({ 
    AdvisedJRubyScriptFactoryTests.class,
    MBeanServerFactoryBeanTests.class
})
public class Spr9288WorksTestSuite {
}
 
@RunWith(Suite.class)
@Suite.SuiteClasses({ 
    AdvisedJRubyScriptFactoryTests.class,
    AnnotationMetadataAssemblerTests.class
})
public class Spr9288WorksTestSuite {
}

Comment by Rossen Stoyanchev [ 16/Jul/12 ]

Chris Beams confirmed the problem when using the above TestSuite. Normally, he doesn't see the issue when running the Gradle build, so we thought the failures were OS specific. But now it looks like the failures can be reproduced reliably on a Mac as well. So I've changed the issue to a "bug" since tests should not fail based on the order in which they're executed.

Comment by Rob Winch [ 16/Jul/12 ]

I probably should have explained why I included JmxUtilsTests in the examples I provided (sorry about that). The ordering to replicate the issue appears to be a bit more complex than ensuring AdvisedJRubyScriptFactoryTests is first if you include JmxUtilsTests into the mix. For example, the following works despite the fact that AdvisedJRubyScriptFactoryTests is first:

@RunWith(Suite.class)
@RunWith(Suite.class)
@Suite.SuiteClasses({AdvisedJRubyScriptFactoryTests.class,
    JmxUtilsTests.class,
    AnnotationMetadataAssemblerTests.class,
    MBeanServerFactoryBeanTests.class})
public class Spr9288WorksTestSuite {
}

You will notice the only difference from my previous failing example is that JmxUtilsTests is moved up. I mention this to hopefully make solving this a bit easier when it gets looked into. I should also note that there may be other tests that impact this issue, but I haven't dug that deep.

Comment by Chris Beams [ 16/Jul/12 ]

Promoting this to 3.2 M2 in the spirit of "never putting a bug in a backlog". Thanks for looking so deeply into this, both of you. The test classes posted above will help a lot in nailing this down.

Comment by Juergen Hoeller [ 28/Aug/12 ]

I wouldn't use the "Bug" label on issues like this one, since it's only really an issue with the test suite, and even there just for specific modes of running. Since we haven't really got a proper label for this kind of issue, I switched it to "Task"...

In any case, I'd prefer using "Bug" for actual issues within the framework only.

Juergen

Comment by Phil Webb [ 26/Nov/12 ]

commit 6ca71abf934ee689f227d5ff864e7a4c4d8ae9d5
Author: Phillip Webb <[email protected]>
Commit: Phillip Webb <[email protected]>
 
    Intermittent MBeanServerFactoryBeanTests failure
    
    Prior to this commit the testWithLocateExistingAndExistingServer method
    would fail if any preceding test called the ManagementFactory
    getPlatformMBeanServer() method. In such situations the platform
    server is located instead of the expected freshly created server.
    
    These failures are more likely to happen when compiling with JDK 7
    due to the fact that the reflection API no longer returns methods
    in a consistent order.
    
    Unfortunately there is no easy way to reset the platform MBean server
    so the new code must resort to using reflection to access the private
    static ManagementFactory.platformMBeanServer field.
    
    Issue: SPR-9288

Comment by Phil Webb [ 29/Nov/12 ]

commit 0d73d199ec645f6d332d3283b72a531b26575cf6
Author: Phillip Webb <[email protected]>
Commit: Phillip Webb <[email protected]>
 
    Reset MBean Servers after JRuby and JMX tests
    
    Refactor MBean Server reset code from MBeanServerFactoryBeanTests
    and reuse in AdvisedJRubyScriptFactoryTests and
    AbstractMBeanServerTests.
    
    Issue: SPR-9288

Generated at Sat Nov 25 11:07:11 UTC 2017 using JIRA 6.4.14#64029-sha1:ae256fe0fbb912241490ff1cecfb323ea0905ca5.