Blog

New in Java 18: Simple Web Server (part 1)

Use jwebserver like a pro

A lot of developers work on writing or debugging web applications daily. Sometimes that work involves writing our application’s backend and sometimes consuming other web resources, whether they are APIs or “normal” web pages. Other programming languages recognised the need for having a “quick and dirty” way of serving resources over HTTP(S) protocol during development. Good people who developed JDK 18 gave us the opportunity to have that in Java too, so we don’t have to look at Node.js, Python or PHP developers with envy anymore when they brag how simple it is to start serving resources in their languages. Let’s see the basic usage of Simple Web Server (SWS) in action!

Two faces of SWS

Not only can we use SWS in Java, but we can do so in two flavours: as a new CLI tool jwebserver, or programmatically as a proper API. This article covers the first usage. The programmatic one is covered in part 2.

jwebserver

Start SWS by typing jwebserver in the shell/terminal. You should see output similar to this one:

$ jwebserver
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /Users/ivanmilosavljevic/Documents/swsdemo and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/

It informs us that it uses the loopback interface and that it listens on port 8000. We can immediately visit http://localhost:8000 in the browser and we’ll see a directory listing of the directory in which we’ve started SWS. Neat! At the same time, in the terminal we’ll find a log that contains information about the remote host address, date and time of a request, HTTP method, requested resource, version and status code:

127.0.0.1 - - [30/Mar/2022:19:39:27 +0200] "GET / HTTP/1.1" 200 -

There are two things to note here. The first one is, if we have an index.html file in the directory in which we’ve started our server, then the contents of that file will be served and not the directory listing. The second one is the visibility of the server — if you start it with -b 0.0.0.0 it will bind to all interfaces and will be accessible from all hosts on your network. Depending on your use-case, this might be either a desired behaviour or a totally unacceptable one.

Of course, we can’t start another instance of SWS on the same port even if we launch it from a different directory. If we try, SWS will greet us with:

$ jwebserver
Error: server config failed: java.net.BindException: Address already in use

The solution is to change the port it listens to by using the --port option:

$ jwebserver --port 8001
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /Users/ivanmilosavljevic/Documents/anotherdir and subdirectories on 127.0.0.1 port 8001
URL http://127.0.0.1:8001/

If we want to serve files from a directory different than the one we start SWS from, we must add the --directory option:

$ jwebserver --directory ~/tmp
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /Users/ivanmilosavljevic/tmp and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/

Various options can be used together, of course, like jwebserver --port 8001 --directory ~/tmp. We can stop a running SWS with the usual Ctrl+C or by sending it a SIGINT signal. We can view all supported options by typing jwebserver --help.

Gotchas and caveats

While the normal usage of SWS from the command line is very straightforward, there are a few details you should take care of:

  • it only serves a single directory hierarchy and only static files
  • only HTTP/1.1 is supported, no HTTPS, HTTP/2 or HTTP/3
  • only GET and HEAD requests are served; everything else will receive either 405 or 501
  • MIME types are automatically assigned
  • symlinks and hidden files are not served

Official JEP specification

I’ll cover programmatic usage of SWS in part 2. In the meantime, if you want to dive deeply into the specification of this feature, you may find it in JEP 408.

Dear fellow developer, thank you for reading this article about Simple Web Server in Java. Until next time, TheJavaGuy salutes you 👋!

You've learned something? Share with the world:

© 2022-2026 Ivan Milosavljević (TheJavaGuy)

Built with Astro using modified Astrofy template