Search code examples
javacom.sun.net.httpserver

Are com.sun.net.httpserver.HttpExchange attributes broken?


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?


Solution

  • 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.