First some (very basic) sample code to illustrate my problem:
final java.util.concurrent.atomic.AtomicLong previousId = new java.util.concurrent.atomic.AtomicLong();
final com.sun.net.httpserver.HttpServer server = com.sun.net.httpserver.HttpServer.create(new java.net.InetSocketAddress(8666), 0);
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
server.createContext("/", exchange -> {
final long id = previousId.incrementAndGet();
System.out.println(String.format("#%s: id attribute=%s", id, exchange.getAttribute("id")));
exchange.setAttribute("id", id);
while (true) {
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
System.out.println(String.format("#%s: id attribute=%s", id, exchange.getAttribute("id")));
}
});
server.start();
While running this program (on Java SE 1.8.0_171), if I make two consecutive requests to http://localhost:8666
, I get the following log:
#1: id attribute=null
#1: id attribute=1
#1: id attribute=1
#2: id attribute=1
#1: id attribute=2
#2: id attribute=2
#1: id attribute=2
#2: id attribute=2
For request #1, the attribute is initially null
, as expected. For request #2 though, the attribute is initially 1
, which seems to imply that the initial value is inherited from the other request. Worse, as you can see, changing the value to 2
for request #2 also changes the value to 2
for request #1. It seems that the attributes are shared between HttpExchange
instances, which is not what I would expect.
Am I missing something or are HttpExchange
attributes broken?
Looking at the source code, it’s perfectly clear that HttpExchange
attributes are shared by all the instances on the same HttpContext
. I find it misleading though that setAttribute
and getAttribute
methods are defined on HttpExchange
. The Javadoc doesn’t help either in my opinion:
Filter modules may store arbitrary objects with HttpExchange instances as an out-of-band communication mechanism.
I have sent an email to the net-dev mailing list and filed a bug. I will update this answer as soon as I get some news.