Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.6.0-M1/M2: play.test.WithApplication#stopPlay does not call ApplicationLifecycle-Hooks anymore #7073

Closed
domdorn opened this issue Mar 13, 2017 · 5 comments

Comments

@domdorn
Copy link
Member

domdorn commented Mar 13, 2017

I'm having troubles with my Unit/Integration Tests while moving to Play 2.6.0 M1/M2.
My tests are extending the play.test.WithApplication class and the play.test.WithApplication#stopPlay is also invoked correctly.

However, the Stop method in play.api.Play#stop does not invoke the ApplicationLifecycle Callbacks anymore.
This leaves my app in an inconsistent state, as I cannot invoke cleanup actions, like closing httpClients that I acquired by doing wsClient.getUnderlying or stopping schedulers in actors.

Especially, this leaves a thread hanging around for (almost) every test I execute, printing the remaining open connections in
/Users/domdorn/.ivy2/cache/com.typesafe.play/shaded-asynchttpclient/jars/shaded-asynchttpclient-1.0.0-M4.jar!/play/shaded/ahc/org/asynchttpclient/netty/channel/DefaultChannelPool.class:289

@marcospereira
Copy link
Member

Hi @domdorn, this is a Java project, right?

Looking at the current code, we are calling the ApplicationLifecycle callbacks. Navigating through WithApplication.stop -> Helpers.stop -> play.api.Play.stop we end up at this stop method:

https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/Play.scala#L128-L128

It calls Application.stop and then, if you are not overriding WithApplication.provideApplication method, should return an instance of play.DefaultApplication which wraps a play.api.DefaultApplication. Then stop method is calling ApplicationLifecycle.stop:

https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/Application.scala#L242-L242

Is it possible to have a project that reproduces the problem?

@domdorn
Copy link
Member Author

domdorn commented Mar 13, 2017

hmm...
the (base) test-class we have does indeed override provideApplication like this

    @Override
    public Application provideApplication() {
        return provideApplicationBuilder().build();
    }

    private GuiceApplicationBuilder provideApplicationBuilder() {
        final List<Binding> bindings = provideOverrideBindings();
        GuiceApplicationBuilder applicationBuilder = new GuiceApplicationBuilder()
                .loadConfig(new Configuration(ConfigFactory.load(provideConfiguration())))
                .overrides(bindings.toArray(new Binding[bindings.size()]))
                .configure("play.http.router", provideRouter())
                .in(Environment.simple());
        final GuiceableModule[] modulesToLoad = provideLoadedModules();
        if (modulesToLoad.length > 0) {
            applicationBuilder = applicationBuilder.load(modulesToLoad);
        }
        return applicationBuilder;
    }

yes, its a java project. I'll try to debug further into it tomorrow and see if I can extract a test-project that reproduces the issue (its already quite late here).

is provideApplication() called a second time? then I'd probably have to store the instance in a field instead of creating a new one in provideApplication()

@marcospereira
Copy link
Member

is provideApplication() called a second time?

It is called once per test case. So, if your test class has 10 test cases, it will called 10 times. Of course, stop will be called for each test case too.

@domdorn
Copy link
Member Author

domdorn commented Mar 23, 2017

Ok, looks like this is from another issue. I had my tests running with "fork in Test := false".
So at one point, the MetaSpace ran out, which prevented the stop hooks from being called, which then prevented thread cleanup.
I've created this issue sbt/junit-interface#77 to properly cleanup the metaspace after each testclass. I think if that one is fixed, also the issue seen here will disappear. For now, running tests in fork mode works.

@marcospereira
Copy link
Member

@domdorn I think we can close this then?

@domdorn domdorn closed this as completed Mar 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants