Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/WASdev/sample.daytrader7/llms.txt

Use this file to discover all available pages before exploring further.

The Web Primitives in DayTrader 7 are a suite of micro-benchmark servlets that exercise individual Java EE components in isolation. Each primitive targets a single layer of the stack — the servlet container, JDBC, the EJB container, CDI, JMS, WebSocket, or the Concurrency Utilities — and returns a simple response that proves the operation completed. They are automatically installed with the DayTrader application and are accessible at http://localhost:9082/daytrader/web_prmtv.html.

Purpose

While the full DayTrader workload measures end-to-end throughput across the entire Java EE stack, Web Primitives let you isolate a single component. This is useful for two distinct tasks:
  • Bottleneck identification. If total DayTrader throughput is lower than expected, primitives let you drill down: Is the servlet container the constraint? The EJB container? JDBC? CDI? Running each primitive under load and comparing their throughput tells you which tier is limiting overall performance.
  • Feature validation. When tuning a specific feature — for example, verifying that switching from synchronous to asynchronous servlet processing improves throughput under your workload — primitives let you test that single feature without the noise of the other components.
Note that some primitives support multiple iterations per request, controlled by the primIterations setting in the DayTrader configuration page (http://localhost:9082/daytrader/config). Setting primIterations to a value greater than 1 (default: 1) reduces the relative overhead of the web container and shifts more work to the component under test — useful for stressing JDBC or EJB without generating proportionally more HTTP traffic.

Web Primitive categories

Servlet and Web Container Primitives

These primitives measure the servlet container, HTTP session management, JSP and JSF rendering, and related web tier features.
PrimitiveURLDescription
PingHtml/PingHtml.htmlBaseline static HTML response. Most basic operation — serves a simple “Hello World” page with no server-side processing.
PingServlet/servlet/PingServletBaseline servlet throughput. Writes a small HTML response via ServletOutputStream with no DB access. Measures raw servlet container overhead.
PingServletWriter/servlet/PingServletWriterSame as PingServlet but uses a PrintWriter for output instead of ServletOutputStream. Useful for comparing character encoding overhead.
PingServlet2Include/servlet/PingServlet2IncludeTests response inclusion: Servlet 1 includes the response of Servlet 2 via RequestDispatcher.include(). Supports primIterations.
PingServlet2Servlet/servlet/PingServlet2ServletTests request dispatching: Servlet 1 creates a JavaBean and forwards to Servlet 2 via RequestDispatcher.forward().
PingServlet2JSP/servlet/PingServlet2JspServlet creates a JavaBean with dynamic attributes and forwards the request to a JSP via RequestDispatcher. Tests the servlet-to-JSP dispatch pattern.
PingServlet2PDF/servlet/PingServlet2PDFServes a PDF document (~1 MB) through a servlet. Tests handling of large binary response payloads.
PingServlet2DB/servlet/PingServlet2DBServlet acquires a JDBC connection from the pool and releases it without executing a query. Isolates connection pool acquisition overhead.
PingServlet2JNDI/servlet/PingServlet2JNDIServlet allocates a JNDI InitialContext and performs a JNDI lookup of the JDBC DataSource on each request. Measures JNDI lookup overhead. Supports primIterations.
PingJSP/PingJsp.jspDirect call to a JavaServer Page. Tests server-side dynamic HTML generation through JSP scripting.
PingJSPEL/PingJspEL.jspTests a JSP using the JSP 2.0 Expression Language (EL). Measures the cost of EL evaluation in addition to JSP scripting.
PingJSF/PingJsf.facesTests a JSF Facelets page that performs a stock quote lookup. Measures the full JSF lifecycle overhead.
PingCDIJSF/PingCDIJSF.facesA CDI managed bean invoked from a JSF Facelets page. Tests the combined CDI + JSF lifecycle path.
PingHTTPSession1/servlet/PingSession1Creates a unique session ID per user and stores it in the HttpSession. Tests fundamental session creation and read access.
PingHTTPSession2/servlet/PingSession2Extends PingHTTPSession1 by invalidating the session every 5th request. Tests HttpSession create and destroy throughput.
PingHTTPSession3/servlet/PingSession3Creates and retrieves a large custom Java object (2,048 bytes) from the session on every request. Tests the server’s ability to manage and persist large HttpSession data objects.
PingUpgradeServlet/servlet/PingUpgradeServletTests a Servlet 3.1 HttpUpgradeHandler request. Requires JMeter for load testing (cannot be driven from a browser).

JDBC Primitives

These primitives measure the JDBC layer in isolation — connection pool acquisition, prepared statement execution, and read vs. write throughput directly from a servlet.
PrimitiveURLDescription
PingJDBCRead/servlet/PingJDBCReadSingle-row read from the quoteejb table via a prepared statement. Uses TradeDirect (direct JDBC) to call getQuote(symbol) for a randomly selected stock symbol. Supports primIterations.
PingJDBCRead2JSP/servlet/PingJDBCRead2JSPSame single-row JDBC read as PingJDBCRead, but forwards the result to a JSP for HTML rendering. Tests the JDBC-to-JSP path. Supports primIterations.
PingJDBCWrite/servlet/PingJDBCWritePerforms a JDBC read followed by a prepared-statement update, simulating a stock price change on the quoteejb table. Measures write throughput and connection pool contention under update workloads. Supports primIterations.

EJB Primitives

Located under the /ejb3/ path, these primitives measure EJB 3 container overhead: local and remote SLSB invocation latency, JPA entity access, JDBC through the session tier, JMS message dispatch to MDBs, and two-phase commit transactions.
PrimitiveURLDescription
PingServlet2Session/ejb3/PingServlet2SessionServlet calls a remote Stateless Session Bean (SLSB) which performs a simple calculation. Measures remote EJB invocation overhead. Supports primIterations.
PingServlet2SessionLocal/ejb3/PingServlet2SessionLocalServlet calls a local SLSB which performs a simple calculation. Measures local EJB invocation overhead with no database access. Supports primIterations.
PingServlet2Session2Entity/ejb3/PingServlet2Session2EntityFull servlet → SLSB → JPA entity path. Retrieves a single row from the database through the complete EJB stack. Supports primIterations.
PingServlet2Session2Entity2JSP/ejb3/PingServlet2Session2Entity2JSPSame as PingServlet2Session2Entity but displays the result in a JSP. Tests the complete servlet → EJB → entity → JSP path. Supports primIterations.
PingServlet2Session2EntityCollection/ejb3/PingServlet2Session2EntityCollectionCalls a Session EJB that uses a JPQL query returning a collection of entity objects. Each object is rendered by the servlet. Supports primIterations.
PingServlet2Session2CMROne2One/ejb3/PingServlet2Session2CMROne2OneTraverses a JPA one-to-one relationship between two entity types. Measures the cost of navigating a single-valued association. Supports primIterations.
PingServlet2Session2CMROne2Many/ejb3/PingServlet2Session2CMROne2ManyTraverses a JPA one-to-many relationship. Measures the cost of loading a collection-valued association. Supports primIterations.
PingServlet2Session2JDBC/ejb3/PingServlet2Session2JDBCFull servlet → Session EJB → JDBC path. Retrieves a single row from the database through the session tier using direct JDBC. Supports primIterations.
PingServlet2Session2JDBCCollection/ejb3/PingServlet2Session2JDBCCollectionExtends PingServlet2Session2JDBC by returning multiple rows from the database. Supports primIterations.
PingServlet2MDBQueue/ejb3/PingServlet2MDBQueueServlet posts a message to a JMS queue. The TradeBrokerMDB receives it asynchronously and prints delivery statistics every 100th message. Supports primIterations.
PingServlet2MDBTopic/ejb3/PingServlet2MDBTopicServlet publishes a message to a JMS topic. The TradeStreamerMDB (and any other subscribers) receives it asynchronously. Supports primIterations.
PingServlet2TwoPhase/ejb3/PingServlet2TwoPhaseDrives a SLSB that performs a JPA entity lookup (DB access) and posts a JMS queue message within a single global XA transaction (two-phase commit). Measures 2PC coordination overhead. Supports primIterations.
PingServlet2MDBQueue and PingServlet2MDBTopic are explicitly documented in the application as not intended for performance testing. They are provided for functional verification of the JMS/MDB path. Do not use them to derive throughput numbers.

CDI Primitives

These primitives measure CDI injection, bean invocation, and BeanManager lookup costs.
PrimitiveURLDescription
PingServletCDI/servlet/PingServletCDITests CDI injection into a servlet — multiple CDI injection points are resolved and invoked on every request.
PingServletCDIBeanManagerViaCDICurrent/servlet/PingServletCDIBeanManagerViaCDICurrentLooks up the CDI BeanManager using CDI.current() (the CDI 1.1 programmatic API).
PingServletCDIBeanManagerViaJNDI/servlet/PingServletCDIBeanManagerViaJNDILooks up the CDI BeanManager via JNDI (java:comp/BeanManager). Useful for comparing CDI API vs. JNDI lookup cost.

WebSocket Primitives

These primitives measure WebSocket endpoint throughput and encode/decode overhead. Each is backed by a @ServerEndpoint implementation.
PrimitiveEndpoint pageDescription
PingWebSocketTextSync/PingWebSocketTextSync.htmlSynchronous text WebSocket echo. The @OnMessage handler calls session.getBasicRemote().sendText() to echo a hit counter back to the client. Measures synchronous send latency.
PingWebSocketTextAsync/PingWebSocketTextAsync.htmlAsynchronous text WebSocket. Uses session.getAsyncRemote().sendText() to send the response asynchronously.
PingWebSocketBinary/PingWebSocketBinary.htmlBinary WebSocket ping. Tests binary frame encode/decode and transport overhead.
PingWebSocketJson/PingWebSocketJson.htmlWebSocket with a JSON encoder and decoder (javax.websocket.Encoder.Text / Decoder.Text). Measures JSON serialization overhead within the WebSocket path.
The WebSocket primitive HTML pages open a WebSocket connection in the browser and display the running hit count. For load testing, drive the WebSocket endpoint URL directly from JMeter using the WebSocket Samplers plugin.

Other Primitives

PrimitiveURLDescription
PingJSONP/servlet/PingJSONPGenerates and parses a JSON object using the javax.json (JSON-P) API. Measures JSON processing throughput without a WebSocket or HTTP client involved.
PingManagedExecutor/servlet/PingManagedExecutorSubmits work to a Java EE 7 ManagedExecutorService (Concurrency Utilities) inside an asynchronous servlet. Tests the concurrency utilities layer.
PingManagedThread/servlet/PingManagedThreadCreates a managed thread via ManagedThreadFactory inside an asynchronous servlet. Tests ManagedThreadFactory invocation overhead.
ExplicitGC/servlet/ExplicitGCInvokes System.gc() and reports heap statistics after collection completes. Use this to force a full GC before a measurement run to establish a clean heap baseline — not as a performance benchmark.

Running Web Primitives

The Web Primitives index page is installed automatically with the application. Open it at:
http://localhost:9082/daytrader/web_prmtv.html
Each primitive name on that page is a link that lets you invoke it once from the browser to verify it is working. For load testing, drive the individual primitive servlet URLs directly with any HTTP load tool:
# 10,000 requests, 50 concurrent connections, against PingServlet
ab -n 10000 -c 50 http://myserver:9082/daytrader/servlet/PingServlet
To increase the number of operations performed per HTTP request, change the primIterations value on the DayTrader configuration page (http://localhost:9082/daytrader/config). The default is 1. Raising this value reduces the relative cost of the HTTP transport and focuses the measurement on the component under test — particularly useful for EJB and JDBC primitives where the network round-trip would otherwise dominate.
Use the primitives as a diagnostic stack trace under load. Start at the top of the stack and work down: if PingServlet achieves the expected requests-per-second but PingJDBCRead does not, the bottleneck is in the JDBC layer or the database, not the servlet container. If PingJDBCRead is fast but PingServlet2Session2Entity is slow, the EJB container or JPA flush overhead is the constraint.

Build docs developers (and LLMs) love