Tornado Server

Tornado Server 6.1.x

100% Java application server and web development framework. Includes installer and embedded relational database. Install and setup in less than 2 minutes! This release requires Java 1.5 or above. Some API changes, your apps may need to be updated. Customers who download this product often download the Vortex IDE for developing Tornado applications




  • - When a connection sat idle past HTTPKeepAliveTimeout (3 s), or never sent a request within HTTPPortTimeout, Puakma closed it with a normal close (FIN). - Because the server closed first, the server kept that address and port pair in TIME_WAIT for 60 s. - Clients behind NAT reuse public ports within seconds. When a new connection attempt (SYN) arrived on a port pair still in TIME_WAIT, with a TCP timestamp that compared as older (clients randomise timestamps for each connection), Linux's check for stray old packets (PAWS) silently dropped it. - The client saw a connection stall of 10–30 s or a failure.


  • Updated to pmaThreadPoolManager and associated classed to ensure threads are more reliable and pool is cleaned


  • Update Util.base64Encode() and Util.base64Decode() to use the built in java base64 coder. This means minimum JVM level is now 8.


  • Fix http byte-range serving bugs, and add http performance improvements.


  • Add ActionRunner.setHttpReplyCode(int) and ActionRunner.setHttpReplyText(String) to allow the action to send a specific http reply code to the browser without direct streaming


  • #: 1 Problem: Idle keep-alive connections each held a worker thread for up to 10s Change: Between requests on a reused connection, a worker now waits only HTTPKeepAliveTimeout (default 3000ms). The Keep-Alive: timeout= header advertises the same value. ──────────────────────────────────────── #: 2 Problem: The TLS handshake ran on the single accept thread with no timeout Change: It now runs on the worker thread, bounded by HTTPPortTimeout, and the socket is closed if the handshake fails. ──────────────────────────────────────── #: 3 Problem: Every 15KB chunk sent took a server-wide lock to rebuild the status line Change: The byte counter no longer locks, and the status line refreshes at most once a second. This also fixes a thread-safety bug in the number formatting. ──────────────────────────────────────── #: 4 Problem: Every design cache lookup scanned the whole cache and took a lock for its counters Change: The full scan runs at most every 5s, and each hit checks its own entry's expiry, so a stale entry is never returned. The counters no longer lock. This affects every Cache, including BOOSTER's. ──────────────────────────────────────── #: 5 Problem: A full thread pool was polled every 200ms, and workers could look busy when they weren't Change: Free workers now wake the waiting accept thread directly, with the same overall timeout. The worker flags are volatile. ──────────────────────────────────────── #: 6 Problem: Small static files were re-read, re-gzipped and re-hashed on every request Change: They're now cached with their ETag (new StaticFileCacheItem.java). The cache key includes the file's modified time, length and whether the client accepts gzip, so an edited file is picked up straight away. ──────────────────────────────────────── #: 7 Problem: Finding an action's class scanned every cached class under a per-app lock Change: It's now a direct lookup by design name. ──────────────────────────────────────── #: 8 Problem: A log entry was built for every response even with logging off Change: That's skipped when no request logging is enabled.


  • ConcurrentModificationException was caused by TornadoServerInstance.getAllLoadedApplications() returning the live, shared applications table to callers that iterate it without synchronization — a concurrent app load could mutate it mid-iteration. Fixed by returning a synchronized snapshot copy


  • Update logic for db connection tracking. Server was incorrectly logging eg: 26' connections were not released correctly from 'PostgreSQL,PostgreSQL,PostgreSQL,PostgreSQL,PostgreSQL'. Check your source code.


  • Do not compress http replies smaller than 1024 bytes


  • Reset error flag for each http request loop


  • Update pmaDefaultAuthenticator to prevent NPE


  • Update/reduce synchronization in TornadoServerInstance and SessionContext


  • The server now returns 503 with Retry-After when overloaded, instead of leaving connections hanging.


  • Fixed a connection-pool deadlock that could make the server stop responding until restarted


  • Fix a typo in TornadoApplication where dburloptions were not being correctly returned


  • ServiceLoader-based discovery was broken in both pmaClassLoader and SharedActionClassLoader because neither overrode findResources(), so META-INF/services/javax.script.ScriptEngineFactory inside nashorn-core-15.6.jar was invisible regardless of the classes themselves loading fine.


  • Fix race condition while building internal design element and parsing pages. In rare cases, this caused page corruption


  • Remove "Content Length Required" check


  • Fix NPE in TornadoServerInstance where appid does not exist


  • Add Keyword caching to TornadoApplication


  • Internal optimizations in HTMLDocument, HTMLItem, HTMLControl


  • Add ThreadLocal NumberFormat to reduce object creation in Util class


  • Update TornadoApplication.getDesignElement() so that the db connect is not held open when createCompositeDesignElement() is called. May cause db connection starvation


  • Change getConnection() to ensure all connections have cx.setAutoCommit(true) so that callers get a consistent object state


  • Update Util.trimChar() to avoid unnecessary object creation


  • Update Util.closeJDBC() to catch Throwable, also improve close logic


  • Add ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY to additional JDBC statements


  • Add "httpOnly" to session cookie and Lpta cookie


  • WEBSSOCookieSecure=1 Ensure that Ltpa token cooke is sent with "secure" option


  • Add extra check so that 500 pages are not processed recursively when a GlobalOpen Action throws an Exception


  • Add early check in ClassData for 0xCAFEBABE header. If header not present, do not keep parsing file.


  • Improve internal byte buffer handling for http action replies (reduce System.arrayCopy calls)


  • Fix performance bottleneck when serving very large files (eg more than 2GB) from the filesystem


  • Improve user role checking when accessing an app.


  • Update ClassData class to understand newer class file format. Tag bytes 15-20 https://en.wikipedia.org/wiki/Java_class_file


  • Update TableManager to allow for not returning generated keys t.insertRow("");


  • Update HTTP server to no longer show errors when closing connections.


  • puakma.config setting: AuthenticatorsShowLoginErrors=0 This prevents the default authenticator displaying login not found etc errors


  • Ensure getDataConnection() adds connection to internal connection tracking table.


  • Fix HTTPSessionContext error message when releasing a connection by appId


  • Add new method to TableManager public boolean insertRow(String sGeneratedKeyFieldName) This allows retrieving a specific column as the generated key. eg Postgresql returns the entire row after insert


  • New task to automatically clean up temp files. This prevents a busy server with long uptime from running out of disk space.


  • New config parameter HTTPSlowActionMS=5000 This new parameter will output an error to the log when an action exceeds this number of milliseconds to run. This helps find slow running actions on a busy server


  • Updated TableManager to support postgresql JSON column types


  • Changed the way TableManager outputs Dates in JSON. Dates now use column name and ISO format, rather than an object containing the different date formats/parts


  • Fix an issue in HTMLView and TableManager where queries using an alias were not displaying the alias column name, eg SELECT Name as fname FROM PERSON Would result in the fieldname "Name" being returned rather than "fname"


  • Synchronize access to removing finished actions from queue. Update dead action thread cleaner to look for completed actions as well as those with errors


  • Added new method in ActionRunner: public void streamToClient(byte[] buf, boolean bFlush) throws IOException This allows data to be streamed to a client, with independent buffer flushing


  • Fix issue in mailer task, incorrect join on mailheader/mailbody caused mailer to use excessive cpu when many pending emails


  • Add new functionality to allow a specific keystore to be bound to a specific HTTP SSL port. HTTPSSLKeyRing8443=../config/yourstore.jks HTTPSSLKeyRingPW8443=######


  • Fix an issue in DocumentMultiItem where if the first value in a multi-valued control contained a comma, it was split into individual values.


  • Added ISO date format to JSON output from TableManager (datefieldname.iso)


  • Fix an issue in url parsing where parameters contained an unescaped "://"


  • Fix an issue in AGENDA which would cause the task to abort when cleaning dead actions. 2021-09-17:17:16:41 Exception in thread "Thread-6" 2021-09-17:17:16:41 java.lang.ArrayIndexOutOfBoundsException: 0 >= 0 2021-09-17:17:16:41 at java.util.Vector.elementAt(Unknown Source) 2021-09-17:17:16:41 at puakma.addin.agenda.AGENDA.cleanDeadThreads(AGENDA.java:535)


  • Update mail sending code to not send single LF characters for compliance with RFC 822bis. Reported error: "550 5.6.11 SMTPSEND.BareLinefeedsAreIllegal; message contains bare linefeeds, which cannot be sent via DATA and receiving system does not support BDAT"


  • Added new class to allow BOOSTER to talk TLSv1.2 to back end servers


  • Altered Util.splitString() to return an ArrayList rather than a Vector to improve performance


  • Changed StringBuffers to StringBuilders to improve performance