Today I landed in a stackoverflow question about how to access the JavaMelody UI using a port other than the one used by the APIs. I went ahead I answered the question with some initial code I had for another blog post I’m working on but then decided to make it its own post.
While this could certainly be accomplished adding a couple of Spring Boot configuration properties: management.context-path and management.port to application.yml for instance, and reuse the same path used for actuator endpoints (/admin/info, /admin/health, …), there might be some cases where having the servlet container listening on a port other that the two mentioned earlier might make sense, maybe for monitoring, traffic analysis, firewall rules, etc..
In this post I’ll add support for configuring embedded Tomcat to listen on multiple ports and configure JavaMelody to exclusively use one of those ports to display its reports using Spring Boot.
This command will create a Maven project in a folder named springboot-tomcat-multiple-ports with most of the dependencies used in the accompanying source code.
Alternatively, it can also be generated using Spring Initializr tool then selecting Actuator and Web dependencies.
Application.java, the entry point to the application looks like:
It scans for @Component-based annotated classes in the specified package and more interesting, will instantiate the beans defined in the imported classes via @Import annotation.
3.1. CONFIGURING TOMCAT
EmbeddedTomcatConfiguration.java, imported in Application.java is where embedded Tomcat is added support to listen on multiple and configurable ports:
This class adds an additional Tomcat connector for each port from server.additionalPortsconfiguration property excluding ports that were set in server.port and management.port.
The relevant configuration properties used in conjunction with EmbeddedTomcatConfiguration.java are included in application.yml:
The embedded Tomcat instance powering this application will listen on 8880 for all the requests except for Spring Boot actuator endpoints which will be exposed on 8881 through /admin path. Notice the custom property server.additionalPorts, this is used in EmbeddedTomcatConfiguration.java to add more connectors to Tomcat, in fact, the endpoints reachable using port 8880 will be reachable through ports 8882 and 8883.
This is a sample log once this application is started:
But this setup would expose the JavaMelody UI on ports 8880, 8882 and 8883, lets fix that by adding another servlet filter and a configuration property to application.yml:
FiltersConfiguration.java imported in Application.java too looks like:
This servlet filter verifies if the requests to the JavaMelody UI should be exclusively accepted using the configured port, if so, and the request comes from a different port, it sends back a 404, otherwise it chains the request to the next servlet filter.
4. RUNNING THE DEMO APP
Sending a request to a resource implemented in DemoResource.java (not reviewed here but included in the source code):
Sending a request to a Spring Boot actuator endpoint on the management port:
Sending a couple of requests on non-allowed ports to JavaMelody:
Loading JavaMelody UI in a browser using configured port 8883:
JavaMelody on an additional Tomcat port
As it can be seen JavaMelody UI can only be accessed through port 8883, a similar approach might be taken to restrict access to the API, which wasn’t done in this demo.
Thanks for reading and as always, feedback is very much appreciated. If you found this post helpful and would like to receive updates when content like this gets published, sign up to the newsletter.
5. SOURCE CODE
Accompanying source code for this blog post can be found at:
Orlando L Otero is a Sr Software Engineer Consultant focusing on integration, modernization, cloud adoption and migration, microservices, API design and implementation, and agile delivery.