30

I'm trying configure an application in Spring Boot with two differents ports, but I haven't got still. My first approximation has been with two controllers and I have defined a @Bean inside the two controller with container.setPort(8080); And my second approximation has been add the actuator dependency and change the port of the management, but my application don't run. It shows:

Address already in use: bind 

How can I confiure an application with two ports? I want one port for admin and the other port is for consults of my api.

Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158
nole
  • 1,422
  • 4
  • 20
  • 32
  • 2
    Which of the following responses did you consider *the answer*? Could you mark it as such when you get a chance? Click on the flag next to this comment and mark this comment for deletion. Thank you. – PatS Feb 21 '22 at 13:42

5 Answers5

34

As is has been mentioned before, server.port and management.port along with management.context-path properties could be set to make the embedded container to listen on different ports (management-related properties to access Actuator endpoints).

To listen on ports other than server.port and management.port:

@Configuration
public class EmbeddedTomcatConfiguration {

    @Value("${server.additionalPorts}")
    private String additionalPorts;

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        Connector[] additionalConnectors = this.additionalConnector();
        if (additionalConnectors != null && additionalConnectors.length > 0) {
            tomcat.addAdditionalTomcatConnectors(additionalConnectors);
        }
        return tomcat;
    }

    private Connector[] additionalConnector() {
        if (StringUtils.isBlank(this.additionalPorts)) {
            return null;
        }
        String[] ports = this.additionalPorts.split(",");
        List<Connector> result = new ArrayList<>();
        for (String port : ports) {
            Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
            connector.setScheme("http");
            connector.setPort(Integer.valueOf(port));
            result.add(connector);
        }
        return result.toArray(new Connector[] {});
    }
}

application.yml

server:
  port: ${appPort:8800}
  additionalPorts: 8881,8882

Application.java

@SpringBootApplication
@ComponentScan(...)
@Import(EmbeddedTomcatConfiguration.class)
public Application {

    public static void main(String[] args) {
        SpringApplication.run(Application .class, args);
    }
}

I recently blogged about this topic at:

Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158
ootero
  • 3,235
  • 2
  • 16
  • 22
  • 4
    Just as addition, there is Spring Boot 2.0 modification - https://stackoverflow.com/questions/47554023/spring-boot-2-0-multiply-ports-listening?rq=1 – Betlista Feb 08 '18 at 13:30
  • 3
    How do you now differentiate localhost:port1 -> serve index page for admin localhost:port2 -> serve index page for other – obey Oct 25 '18 at 11:36
8

Since springboot 2, EmbeddedServletContainerFactory mentioned in ootero solution is no longer available, so you should use either TomcatServletWebServerFactory or TomcatReactiveWebServerFactory according to your context.

The solution stays the same aside from the factory injection :

@Bean
public TomcatServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
    Connector[] additionalConnectors = this.additionalConnector();
    if (additionalConnectors != null && additionalConnectors.length > 0) {
        tomcat.addAdditionalTomcatConnectors(additionalConnectors);
    }
    return tomcat;
}
Camille Vienot
  • 727
  • 8
  • 6
4

To change Actuator management port you can use property

management.port=8081

See full list of properties here

Update: Actuator creates one more Embedded Tomcat(servlet container) instance in this case. See here and here

Community
  • 1
  • 1
Dennis R
  • 1,769
  • 12
  • 13
  • yes, i know, but is possible to do this: management.port =8081 and server.port=8080 ? and have two differents ports in the same application?7 – nole Apr 01 '16 at 16:39
  • server port is 8080 by default. 2 different ports mean 2 different sockets listening on different ports. – Dennis R Apr 01 '16 at 16:43
  • thank you, I know that is a posibility but we dont want have our admin application in the actuator port, we need a different port. – nole Apr 05 '16 at 08:54
1

To run 2 or more applications within a single project or change the default port, you can perform the action like this

@SpringBootApplication
public class NewApplication {
     public static void main(String[] args) {
         SpringApplication app = new SpringApplication(NewApplication .class);
         app.setDefaultProperties(Collections.singletonMap("server.port", "8083"));
         app.run(args);
     }
}
Agung Pramono
  • 429
  • 4
  • 7
0

If only one additional port is to be opened, the following is sufficient (Kotlin):

@Configuration
class AdditionalEndpointConfig {

    @Bean
    @ConditionalOnProperty(PORT_PROPERTY)
    fun tomcatServletWebServerFactory(@Value("\${$PORT_PROPERTY}") additionalPort: Int) =
        TomcatServletWebServerFactory().apply {
            addAdditionalTomcatConnectors(
                Connector("org.apache.coyote.http11.Http11NioProtocol").apply {
                    scheme = "http"
                    port = additionalPort
                })
        }

    companion object {
        const val PORT_PROPERTY = "server.additional.port"
    }
}