Skip to content
This repository has been archived by the owner on May 28, 2018. It is now read-only.

@PreDestroy not invoked on root resource #2254

Open
glassfishrobot opened this issue Jul 20, 2013 · 12 comments
Open

@PreDestroy not invoked on root resource #2254

glassfishrobot opened this issue Jul 20, 2013 · 12 comments

Comments

@glassfishrobot
Copy link

It seems that Jersey 2 no longer invokes @PreDestroy on a root resource when used with the JDK's bundled http server (JdkHttpServerFactory). @PostConstruct is properly as expected.

This was working as expected in Jersey 1.x. Is this no longer the case? Is there a work-around?

Affected Versions

[2.0]

@glassfishrobot
Copy link
Author

Reported by spamdaemon

@glassfishrobot
Copy link
Author

spamdaemon said:
I don't know how to attach anything here. So I'll just cut and paste a little example:

import java.net.HttpURLConnection;
import java.net.URI;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import com.sun.net.httpserver.HttpServer;

public class SimpleServer {

	private static AtomicInteger COUNTER = new AtomicInteger(0);

	@Path("/")
	public static class Endpoint {

		@GET
		public String get() {
			return "Hello, World";
		}

		@PreDestroy
		public void preDestroy() {
			System.err.println("preDestroy");
			COUNTER.decrementAndGet();
		}

		@PostConstruct
		public void postConstruct() {
			COUNTER.incrementAndGet();
			System.err.println("postConstruct");
		}

	};

	public static void main(String[] argv) throws Exception {
		String uri = "http://localhost:8080/"; 		ResourceConfig config = new ResourceConfig(Endpoint.class);

		HttpServer server = JdkHttpServerFactory.createHttpServer(
				URI.create(uri), config);

		for (int i = 0; i < 3; ++i) {
			HttpURLConnection con = (HttpURLConnection) URI.create(uri).toURL()
					.openConnection();
			System.err.println("ResponseCode : " + con.getResponseCode());
			con.disconnect();
		}
		server.stop(1);
		System.err.println("COUNTER :" + COUNTER.get());
		System.exit(COUNTER.get());
	}
}

@glassfishrobot
Copy link
Author

spamdaemon said:
Doesn't work with 2.2 either.

@glassfishrobot
Copy link
Author

spamdaemon said:
I tried this now with grizzly, but still no luck. Is there something else I need to do to get this to work in an embedded server??

@glassfishrobot
Copy link
Author

spamdaemon said:
I've finally worked around this using a WriterInterceptor. I made my root resources Closeable and simple close them in after the request has been written.
This seems to work fine for now.

@glassfishrobot
Copy link
Author

spamdaemon said:
So, the interceptor didn't work either,because it's not invoked when there is no content to be written.

After seriously searching I've realized this can no longer be done without relying on Jersey. The way to do this seems to be as described here: http://comments.gmane.org/gmane.comp.java.jersey.user/3087

@glassfishrobot
Copy link
Author

mfuksa said:
Jersey 2 does not call @PreDestroy nor @PostConstruct for standard resources. These methods are called for CDI beans and for Application class.

Check the org.glassfish.jersey.server.CloseableService. You can inject it to your resource method, resource or provider using @context annotation and then register your Closeable (using add() method) which will be called when request is finished.

@glassfishrobot
Copy link
Author

spamdaemon said:
Actually, it does call @PostConstruct (at least at the time of writing this issue) which I think should have been paired with a @PreDestroy.

At any rate, I did indeed go the route with the cleanup handler.

@glassfishrobot
Copy link
Author

mfuksa said:
You are right. For standard JAX-RS resources PostConstruct is called but not PreDestroy. This should be fixed and PreDestroy methods should also be called.

Note: when implementing please make sure to handle correctly singleton and request scopes.

@glassfishrobot
Copy link
Author

stephan202 said:
To be clear: this affects not just resources, but other JAX-RS @providers (such as ContainerResponseFilter implementations) as well. (I.e., @PostConstruct is called, but @PreDestroy isn't.)

@glassfishrobot
Copy link
Author

stephan202 said:
This issue was mostly resolved by #2846, but not completely: Feature instances are still "left out".

Tangentially related is the fact that the jersey-test-framework-provider-inmemory doesn't support @PreDestroy at all (while the Jetty and Grizzly providers do). Not a deal breaker, but unfortunate.

@glassfishrobot
Copy link
Author

This issue was imported from java.net JIRA JERSEY-1982

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants