Title: Support Tornado web server
Type: Severity: normal
Components: Versions: Jython 2.7
Milestone: Jython 2.7.2
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: amak, darjus, jeff.allen, zyasoft
Priority: high Keywords:

Created on 2016-02-02.14:57:54 by zyasoft, last changed 2018-03-05.20:09:22 by jeff.allen.

msg10691 (view) Author: Jim Baker (zyasoft) Date: 2016-02-02.14:57:53
Tornado should run on Jython, and it does not appear to really rely on fcntl (#1943). Instead, Tornado mainly seems to be missing some functionality in our ssl implementation, likely minor.

Apply the following diff to a clone of

$ git diff
diff --git a/tornado/platform/ b/tornado/platform/
index 449b634..6d0f435 100644
--- a/tornado/platform/
+++ b/tornado/platform/
@@ -35,6 +35,10 @@ if 'APPENGINE_RUNTIME' in os.environ:
 elif == 'nt':
     from tornado.platform.common import Waker
     from import set_close_exec
+elif == 'java':
+    from tornado.platform.common import Waker
+    def set_close_exec(fd):
+        pass
     from tornado.platform.posix import set_close_exec, Waker

set_close_exec can be a no-op on Jython because Java opens files such that the file descriptors are closed on exec; see

After installing dependencies (backports-abc, singledispatch), $ jython -m tornado.test.runtests. But see its tox.ini for more options. Many tests curerently pass, but Tornado is failing in some aspects of using SSL, such as missing attributes on SSL sockets and possibly exception handling.
msg10693 (view) Author: Jim Baker (zyasoft) Date: 2016-02-02.15:22:46
One more change is required to run Tornado's hello, world application (, due to #2406:

$ git diff tornado/
diff --git a/tornado/ b/tornado/
index b249945..5dbd94e 100644
--- a/tornado/
+++ b/tornado/
@@ -181,7 +181,7 @@ def bind_sockets(port, address=None, family=socket.AF_UNSPEC,
             # ipv6 sockets and use a separate ipv4 socket when needed.
             # Python 2.x on windows doesn't have IPPROTO_IPV6.
-            if hasattr(socket, "IPPROTO_IPV6"):
+            if hasattr(socket, "IPPROTO_IPV6") and != "java":
                 sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)

         # automatic port allocation with port=None

With Apache Benchmark using ab -k -c 20 -n 50000 localhost:8888/

Percentage of the requests served within a certain time (ms)
  50%     16
  66%     17
  75%     21
  80%     22
  90%     28
  95%     42
  98%     48
  99%     54
 100%    247 (longest request)

Not the fastest event loop (see Fireside running on Jetty with, but quite likely it can be made much faster if the event loop was based on Netty instead of the emulation with socket/ssl/select.
msg10695 (view) Author: Jim Baker (zyasoft) Date: 2016-02-02.15:40:49
Tornado on CPython, same Apache Benchmark settings:

  50%      8
  66%      8
  75%      8
  80%      8
  90%      8
  95%      8
  98%      8
  99%      9
 100%     26 (longest request)

Still not as fast as Fireside, but significantly less overhead than Tornado/Jython currently. Of course this is timing the event loop - we are only doing small requests.
msg11744 (view) Author: Jeff Allen (jeff.allen) Date: 2018-03-05.20:09:22
Is this in the trunk or just a private experiment? That is, should it be closed? Is #2604 formally a dependency?

If we have a bunch of SSL and IPv6 things to deal with, then is suggest it is for beyond 2.7.2.
Date User Action Args
2018-03-05 20:09:22jeff.allensetnosy: + jeff.allen
messages: + msg11744
2016-02-08 15:52:22zyasoftsetpriority: high
milestone: Jython 2.7.2
2016-02-05 17:44:10amaksetnosy: + amak
2016-02-02 15:40:50zyasoftsetmessages: + msg10695
2016-02-02 15:22:47zyasoftsetmessages: + msg10693
2016-02-02 14:57:54zyasoftcreate