Wilson Mar bio photo

Wilson Mar


Calendar YouTube Github


Sample Java Spring app for your abuse and amusement

US (English)   Norsk (Norwegian)   Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Estonian   اَلْعَرَبِيَّةُ (Egypt Arabic)   Napali   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean


The app was originally created for learning Java Spring v5 and exploring JVM tools MyBatis3, Stripes.

Several performance testing tool vendors use JPetstore6 as a sample app under test in demos and documentation:

WARNING: There are several obsolete versions of JPetstore on the internet, such as v4 on Sourceforge.

This article describes the various ways to get hands-on with it:

VIDEO: How to install JPetStore locally for Performance Testing

Install locally using Docker

  1. If you have Docker daemon installed and running, a simple way is to have auto-pull when running a Docker image from the public DockerHub (https://hub.docker.com):

    docker run -d -p 8099:8080 jloisel/jpetstore6:latest

    NOTE: “8099” is the local port remapping port 8080 specified in the container. Change to another local port to avoid “failed: port is already allocated” error.

    The response showing progress:

    Unable to find image 'jloisel/jpetstore6:latest' locally
    latest: Pulling from jloisel/jpetstore6
    f8efbffe7b95: Downloading [===========================>   ]  28.74MB/51.36MB
    bd3fd4907f3c: Pull complete
    Digest: sha256:de40afbc5f494d99154f806f4b50ee5347c7df2ab0a1a3fa2841aab36b6f9e42
    Status: Downloaded newer image for jloisel/jpetstore6:latest
  2. View the JPetstore6 landing page:


    A landing page showing a green parrot (below) should be returned.

  3. Continue with content below. Then after you’re done, return here to stop the Docker process and remote the docker image to save disk space, memory, and other resources:

    CONTAINER_ID=$( docker ps | grep "jloisel/jpetstore6" | cut -d " " -f 1 )
    docker stop $CONTAINER_ID
    docker rmi jloisel/jpetstore6 --force
  4. Confirm:

    docker ps
    docker images

UI assessment

The app provides a e-commerce shopping cart because that is a common use case on the internet. Different items within several categories (of pets) are available for browing and purchase.

Landing page (Main Menu)

jpetstore6 main menu

The page has 3 columns under a header. The image above was adjusted to the smallest width without wrapping. The page design is HTML4 transitional, not HTML5 “responsive” for mobile, which is an SEO issue.

Thankfully, one company has it running all the time at http://demo.kieker-monitoring.net/jpetstore/actions/Catalog.action

At one time, the page rated 90/100 for Desktop on Google Page Speed and 83/100 for Mobile. Google recommends these changes to make the page faster:

Use case loops

An explanation of the UI actions is available by clicking the (?) on the heading, at

This site map is from the comparison by Clinton Begin (of Alberta):

jpetstore6 site map

Imposing transaction load

To impose artificial load, define performance test scripts this a set of loops, each of which can be run separately to measure a different potential issue:

  1. Landing page and Info (?) page for network variability measurement.

  2. Browsing through items (without login or buying) to specifically stress the web server.

    Rather than coding to click specific items, this activity is often specified by a file with the test program iterates through.

  3. Register to see how many the system can accommodate when the system is widely announced to the public. How many new users can jump in at once without the system degrading? That answer informs the throttling of publicity so new people come in at a pattern the system can accomodate.

    QUESTION: j2ee is the default user? What’s the password?

    The user registration link is not on the landing page (Main Menu), reached after a click of Sign In.

    TODO: Variations in registration data from a file to load various types of users.

  4. Login to see what happens when everyone arrives at the same time (such as at a call center during start of shift).

  5. Log-off

  6. Search form usage, especially for form fields that return an autocomplete list for user ease-of-use.

  7. Add to cart from an item listing, which adds to the database for each unique user, specifically to stress the database.

  8. View cart.

  9. Purchase to ensure that payment gateways can keep up with a lot of people buying at once.

    Except the JPetStore app does not connect with a payment gateway. So this is a mute point.

    Checkout for user to provide payment details and billing address:


    When “Continue” is pressed, a page is shown to “Confirm”.

    Clicking “Confirm” would result in a “submitted” page.

  10. End-to-end with all the above to ensure that the system can handle a pattern of work during scalability testing (to emulate a mention on Reddit or Hacker News that causes a buying frenzy).

  11. My Orders lists order history for a user, by reading from the database. A link to it is at the bottom of the User Information page after a user is logged in and has completed an order.

Additionally, there are error responses to each of the above, created by “negative” tests:

  1. Server unavailable (Apache Tomcat/NGINX).

  2. Registration error (such as bad email, user already defined, etc.).

  3. Login error, such as forgotten password change.

  4. Item not available (out of stock) during browsing. Ideally, there is a checkbox to eliminate from display items not in inventory (for advanced users).

  5. Search not found.


Options for performance testing apps

Since JPeterStore was built for developers, missing are some features in the WebTours app Mercury/HP built to use as a sample app during demos and training for LoadRunner.

Pattern of iteration

To mimic real-life load across the various pages, not every iteration would invoke “My Orders”. So the automation scripts would need to use a percentage chance when the action is performed.

Ideally, we would have a data-driven approach where a file external to the code specifies the pattern of invocation. This approach would not require a re-compile after changes.

Reset data

QUESTION: How to reset the Orders data for a user?


On the Main Menu, there are links to category lists from the text at the left, the headings at the top, and icons at the center.

  • Fish
  • Dogs
  • Cats
  • Reptiles
  • Birds

User Registration


On the heading, when a user is signed in, “Sign In” changes to “My Account”.

User Profile Options

These change behavior, which automation scripts need to respond to:

  • Enable MyList

  • Enable MyBanner

Local Installation


I created a bootstrap Bash script to install this natively as a localhost on a MacOS at https://github.com/wilsonmar/mac-setup

To use the script, clone the repo and edit file secrets.sh such that variable LOCALHOSTS contains the value “jpetstore-6”. Then run the script ./mac-setup-all.sh See the repo’s README.


MyBatis has packaged up http://www.mybatis.org/jpetstore-6/dependency-info.html

  • Java 1.6 and above (1.8.11 at January 2017)

  • Spring 4

  • Stripes - https://github.com/StripesFramework

  • MyBatis 3 SQL mapping framework for Java

    MyBatis mappers and dependency injection lets you build applications without dependencies. Thus, the source has no code to deal with JDBC, to create objects or bind them or to handle transactions.

    (There is a port to .NET)

    The iBATIS Database Layer uses simple XML descriptor filesto describe the inputs and outputs of each SQL statement. It allows the programmer to simply pass a JavaBean into a MappedStatement as a parameter (input) and receive a JavaBean as a result (output).

  • Formatter Tag Library by Tak Yoshida of ibatis.

  • Tomcat web server from the Apache Foundation.

  • JUnit for Mokito

    Used by tests

Rather than downloading a release zip file, use a Git client, as the readme recommends the following, which the mac-setup-all.sh script does:

  1. Create a folder to hold. I prefer to have a container folder (jpetstore) because there are multiple repositories:

    ~/gits/your acct/jpetstore-6

    ~/gits/you acct/jpetstore/mybatis-spring-boot-jpetstore
    is an alternative from Kazuki Shimizu (of Japan).

    It is implemented using Thymeleaf 3.0 templating.

  2. In a Terminal, fork the repository and obtain your own version of the whole repository. The example here was forked by my account, wilsonmar. Yours will be different:

    git clone https://github.com/wilsonmar/jpetstore-6.git --depth=1
    cd jpetstore-6
    git remote add upstream https://github.com/mybatis/jpetstore-6.git 

    ”–depth=1” can be used here to limit download to just the latest commit of the master branch because we’re not using previous commits or other branches.

  3. Have Maven download and install dependencies defined in pom.xml:

    mvn clean package

    JPetStore-6 should run in any Servlet 2.5 y JSP 2.1 compliant Java server.

    Eclipse is not needed. You can run the sample from your favorite IDE or the command line.

    Change port

  4. To change the port from the default 8080 to something else, edit file:

    "tomcat9x" will eventually be incremented.
  5. Scroll down to the line:


  6. Change port=”8080” to port=”$JPETSTORE_PORT”.
  7. Save the file.

    https://github.com/blackburntech/jpetstore-sample suggests additional steps.

    Start server

  8. Startup the Tomcat server and deploy web application using the Cargo Maven plug-in

    mvn cargo:run

    The pom.xml file has several versions of Tomcat loaded.

  9. In a browser, use the app as a user:


    You should now see the entry screen:

    jpetstore6 enter store

  10. Click “Enter the store” for the main menu.


Online Solution http://demo.kieker-monitoring.net/

Java Code

JPetStore v6 is vendor-independent open source freeware first released in 2002 in 3,154 lines of code. It uses the Jakarta Struts Model-View-Controller based presentation layer. It has NO SQL in code nor stored procedures running in a database, so is independent of database vendors (Oracle SQL in particular). PostgreSQL is free.

It has no generated code, nor HTML in the database.

Eclipse is not required, but there is a MyBatis plug-in

Docs at http://www.mybatis.org/jpetstore-6 say:

The purpose of JPetStore 6 is to demonstrate how to build a web application with very few classes and no advanced coding skills. You just need to know plain Java and SQL.

Java source code is in the src/mainjava/org/mybatis/jpetstore folder.


Sun created a J2EE Pet Store, in a massive 15,000 lines, as a demonstration of various coding features (not for benchmarking).

Microsoft contracted with Vertigo Software to create a sample .Net Pet Shop when it orginally debuted its .NET framework. The repo had 3,484 lines of code and was tuned for benchmarking speed rather than coding best practices.

So it’s not really fair to make judgements about the speed of the underlying technologies by comparing their sample apps since they were made for different purposes.

More on IoT

This is one of a series on IoT:

  1. IoT Acronymns and Abbreviations on Quizlet

  2. IoT Home Assistant system

  3. IoT Apprentice school curriculum
  4. IoT use cases
  5. IoT reminders prevent dead mobile battery
  6. IoT barn feeder

  7. IoT text to speech synthesis
  8. IoT AWS button
  9. Intel IoT
  10. IoT Raspberry hardware
  11. IoT Raspberry installation

  12. IoT Clouds
  13. Samsung IoT Cloud

NOTE: Pages about GE’s Predix have been removed.