# JPetStore 6: MyBatis reference app you can run on Tomcat, Docker or eight other servers

> JPetStore 6 is a full web application on MyBatis 3, Spring and Stripes, kept as a working reference for the MyBatis ecosystem. It builds a war, runs on a range of application servers through Maven profiles, and ships a Docker path that rebuilds the image from source on every start.

**mybatis/jpetstore-6** — A web application built on top of MyBatis 3, Spring 3 and Stripes

- Repository: https://github.com/mybatis/jpetstore-6
- Website: http://www.mybatis.org/spring/sample.html
- Stars: 607 · Forks: 1,771
- Language: Java
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/mybatis-jpetstore-6

## This is the MyBatis sample app, and the name tells you which one

JPetStore 6 is a full web application built on top of MyBatis 3, Spring and Stripes, and it exists to be a working reference rather than a product. The repository holds the application, its build, its container definition and its tests, with a src/ directory at the root and Maven files including pom.xml, the mvnw wrapper and its .mvn/ directory, plus a format.xml, a renovate.json and a NOTICE file alongside the LICENSE. The README also lists other versions of the sample that may interest you, which is the fastest way to understand the design space. There is a JPetstore on Spring, Spring MVC, MyBatis 3 and Spring Security in a separate repository, one with Vaadin and Spring Boot with Java Config, and one on the MyBatis Spring Boot Starter. The differences between those variants are the whole point of the sample, since the same domain model can be presented through different web and persistence stacks, and this repository is the one that uses Stripes for the web layer and no Spring Security. The homepage for the project is the MyBatis sample page, and there is a documentation site at mybatis.org/jpetstore-6.

## Building a war and running it under Tomcat is the documented path

The application server instructions start with cloning the repository and building the war:

```bash
  $ git clone https://github.com/mybatis/jpetstore-6.git
```

```bash
  $ cd jpetstore-6
  $ ./mvnw clean package
```

Then the cargo-maven2-plugin starts Tomcat and deploys the application:

```bash
  $ ./mvnw cargo:run -P tomcat9
```

Once it is up, the README says to open http://localhost:8080/jpetstore/ in a browser, and to press Ctrl-C to stop the server. The use of the Maven wrapper rather than a system mvn is worth noticing, because it pins the Maven version the build expects rather than using whatever happens to be on your machine. The container variant is the shortest route if you just want to see it working. The Dockerfile is based on openjdk:25, copies the whole tree into /usr/src/myapp, runs the Maven package build there, and starts the application through the same cargo command with the tomcat9 profile:

```dockerfile
FROM openjdk:25
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN ./mvnw clean package
CMD ./mvnw cargo:run -P tomcat9
```

The compose file builds from the same context, maps 8080 to 8080, sets the container name to jpetstore and sets restart to always, with the compose file declaring version 3.9.

## The Docker path rebuilds from source, it does not pull an image

The two documented Docker commands look like the usual container workflow but behave differently, and that is worth understanding before you rely on it. The first pair is a build and a run:

```bash
docker build . -t jpetstore
docker run -p 8080:8080 jpetstore
```

The second is a compose invocation:

```bash
docker compose up -d
```

What the Dockerfile shows is that the image build runs the full Maven package inside the container, so a docker build is really a Java build. The base is openjdk:25, and there is no prebuilt artefact copied in, no layer of compiled classes in the image, and no external artefact repository step. The practical consequences are worth spelling out. The build needs network access to resolve Maven dependencies, and it is slow, because the whole dependency graph and the compile happen on your machine during the image build. The image also ends up large, since it carries the JDK and the Maven cache alongside the application. On the positive side, the container you run is built from the source in the working tree, so there is no question of the image being out of date with your checkout, and the compose file's restart: always means a container that dies is brought back. For a sample application that is a reasonable trade. For something you intend to run repeatedly in CI, the honest comparison is with a prebuilt image, which this project does not provide.

## Eight server profiles, and two of them constrain your JDK

The README lists Maven profiles per application server, which is the most useful piece of configuration in the project. The table names tomcat9 as preferred, running under Tomcat 9.0, and then glassfish5 under GlassFish 5, jetty12-ee8 under Jetty 12, liberty26-ee8 under WebSphere Liberty, payara5 under Payara 5, resin4 under Resin 4, tomee8 under TomEE 8.0 and wildfly26 under WildFly 26. Two notes below the table explain the friction. When using glassfish5, it must run under Java 8 because it does not work with newer versions, and the code is set to a Windows path, D:/jdk/jdk-1.8.0.501, which the README acknowledges will differ for you, so you call it with -Dcargo.java.home=PATH-TO-JDK8. When using payara, the full Maven build must run under Java 17, which the README says is unlike glassfish5 because of how it connects with cargo, and in that case you use -Denforcer.skip=true to accomplish it. So the profiles are not interchangeable in terms of your local toolchain, and a build that works on one will fail on another for reasons that are about the server rather than about the application. The names also suggest the project tracks current server generations, with the numbering reflecting major versions such as Jetty 12 and WildFly 26.

## Integration tests check screen transitions, not the whole stack

The test section is short and specific. The README calls them integration tests for screen transition, run with a single command:

```bash
$ ./mvnw clean verify -P tomcat9
```

The scope is narrower than the name might suggest. Screen transition means the navigation between pages of the web application, which is the part of a Stripes application that is easy to get wrong and hard to eyeball, since a broken action binding shows up as a page that does not do what you expected rather than as an error. Running the verify phase under the tomcat9 profile means the application is packaged and started in the same server configuration used for the run instructions, so the test exercises the deployment path as well as the navigation. The repository also carries a CI workflow badge for Java and a separate support workflow badge, and a coveralls coverage badge, so the coverage number is published rather than kept private. The pom.xml and the .mvn/ directory are where the test configuration lives, and the repository also has a format.xml, which is a formatter configuration kept in the tree so that formatting is reproducible across contributors.

## Apache 2.0, and a repository that tracks its dependencies with renovate

The licence is Apache-2.0, and the repository carries both a LICENSE file and a NOTICE file plus a LICENSE_HEADER file, which is the standard Apache 2.0 pattern of recording both the licence text and the required header. Every source file in the project carries the Apache header, and the same header appears at the top of the Dockerfile and the compose file, with a copyright line covering 2010 to 2026. For a sample application the licence choice matters less than it would for a dependency, but this repository is also a reference that people copy from, and the header in the files is what makes copying code from it straightforward under those terms. The renovate.json at the root is the interesting operational detail. Renovate is a dependency update bot, and keeping its configuration in the repository means dependency upgrades arrive as pull requests with the tool's own conventions rather than as manual edits. That is a large part of why a sample application stays current against a moving set of server and framework versions. The release history supports the same point, with jpetstore-6.4.0 on 2026-08-16, jpetstore-6.3.0 on 2026-07-09 and jpetstore-6.2.0 on 2026-01-01, and the last push to the repository on 2026-10-17.

## Conclusion

JPetStore 6 suits developers who want a complete, running MyBatis application to read, fork or use as a test bed, and teams who want a container image they can rebuild from source rather than pull from a registry. It is the wrong choice as a starting skeleton for a new production system, because the sample domain is a pet store and the project is maintained as a demonstration, and it is the wrong choice if you need Spring MVC or Spring Security, which this variant does not include. Verify first which application server profile you intend to use and read the JDK constraints attached to it, since glassfish5 and payara5 need different Java versions, and check the container path builds rather than assuming a prebuilt image exists.

## FAQ

### How do I build and run JPetStore 6?

Clone the repository, run ./mvnw clean package to build the war, then start it with ./mvnw cargo:run -P tomcat9 and open http://localhost:8080/jpetstore/ in a browser. Press Ctrl-C to stop the server.

### Which application servers does JPetStore 6 support?

The README lists Maven profiles for tomcat9 as the preferred option, plus glassfish5, jetty12-ee8, liberty26-ee8, payara5, resin4, tomee8 and wildfly26. Some impose JDK constraints, with glassfish5 needing Java 8 and payara needing a Java 17 build.

### Does the Docker image come prebuilt?

No. The Dockerfile copies the source into the image and runs ./mvnw clean package during the build, so docker build performs a full Java build. The compose file builds from the same context and sets restart to always.

### How do I run the JPetStore 6 integration tests?

The README documents a single command, ./mvnw clean verify -P tomcat9, for integration tests covering screen transition, so the application is built and started in the same configuration as the run instructions.

## Sources

- [License: Apache-2.0](https://github.com/mybatis/jpetstore-6/blob/master/LICENSE)
- [mybatis/jpetstore-6 on GitHub](https://github.com/mybatis/jpetstore-6)
- [Project website](http://www.mybatis.org/spring/sample.html)
- [README](https://github.com/mybatis/jpetstore-6/blob/master/README.md)
- [Releases](https://github.com/mybatis/jpetstore-6/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mybatis-jpetstore-6
