diff --git a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/builder/BuildStepsIntegrationTest.java b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/builder/BuildStepsIntegrationTest.java
index 218c48fdb3..979e7fa32c 100644
--- a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/builder/BuildStepsIntegrationTest.java
+++ b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/builder/BuildStepsIntegrationTest.java
@@ -21,6 +21,7 @@
import com.google.cloud.tools.jib.cache.CacheDirectoryNotOwnedException;
import com.google.cloud.tools.jib.cache.CacheMetadataCorruptedException;
import com.google.cloud.tools.jib.cache.Caches;
+import com.google.cloud.tools.jib.frontend.ExposedPortsParser;
import com.google.cloud.tools.jib.image.ImageReference;
import com.google.cloud.tools.jib.registry.LocalRegistry;
import java.io.IOException;
@@ -56,7 +57,9 @@ public void testSteps_forBuildToDockerRegistry()
.setTargetImage(ImageReference.of("localhost:5000", "testimage", "testtag"))
.setMainClass("HelloWorld")
.setJavaArguments(Collections.singletonList("An argument."))
- .setExposedPorts(Arrays.asList("1000", "2000-2002/tcp", "3000/udp"))
+ .setExposedPorts(
+ ExposedPortsParser.parse(
+ Arrays.asList("1000", "2000-2002/tcp", "3000/udp"), logger))
.setAllowHttp(true)
.build();
@@ -100,7 +103,9 @@ public void testSteps_forBuildToDockerDaemon()
.setTargetImage(ImageReference.of(null, "testdocker", null))
.setMainClass("HelloWorld")
.setJavaArguments(Collections.singletonList("An argument."))
- .setExposedPorts(Arrays.asList("1000", "2000-2002/tcp", "3000/udp"))
+ .setExposedPorts(
+ ExposedPortsParser.parse(
+ Arrays.asList("1000", "2000-2002/tcp", "3000/udp"), logger))
.build();
Path cacheDirectory = temporaryCacheDirectory.newFolder().toPath();
diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildConfiguration.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildConfiguration.java
index 6cdf828266..2f12cf059e 100644
--- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildConfiguration.java
+++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildConfiguration.java
@@ -21,17 +21,13 @@
import com.google.cloud.tools.jib.image.json.BuildableManifestTemplate;
import com.google.cloud.tools.jib.image.json.V22ManifestTemplate;
import com.google.cloud.tools.jib.registry.credentials.RegistryCredentials;
-import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.lang.model.SourceVersion;
@@ -40,13 +36,6 @@ public class BuildConfiguration {
public static class Builder {
- /**
- * Pattern used for parsing information out of exposed port configurations.
- *
- *
Examples: 100, 200-210, 1000/tcp, 2000/udp, 500-600/tcp
- */
- private static final Pattern portPattern = Pattern.compile("(\\d+)(?:-(\\d+))?(/tcp|/udp)?");
-
// All the parameters below are set to their default values.
@Nullable private ImageReference baseImageReference;
@Nullable private String baseImageCredentialHelperName;
@@ -212,7 +201,7 @@ public BuildConfiguration build() {
ImmutableList.copyOf(javaArguments),
ImmutableList.copyOf(jvmFlags),
ImmutableMap.copyOf(environmentMap),
- expandPortRanges(exposedPorts),
+ ImmutableList.copyOf(exposedPorts),
targetFormat,
applicationLayersCacheConfiguration,
baseImageLayersCacheConfiguration,
@@ -240,63 +229,6 @@ public BuildConfiguration build() {
throw new IllegalStateException(errorMessage.toString());
}
}
-
- /**
- * TODO: Move this to a class in frontend
- *
- *
Converts/validates a list of ports with ranges to an expanded form without ranges.
- *
- *
Example: ["1000/tcp", "2000-2002/tcp"] -> ["1000/tcp", "2000/tcp", "2001/tcp", "2002/tcp"]
- *
- * @param ports the list of port numbers/ranges
- * @return the ports as a list of integers
- * @throws NumberFormatException if any of the ports are in an invalid format or out of range
- */
- @VisibleForTesting
- ImmutableList expandPortRanges(List ports) throws NumberFormatException {
- ImmutableList.Builder result = new ImmutableList.Builder<>();
-
- for (String port : ports) {
- Matcher matcher = portPattern.matcher(port);
-
- if (!matcher.matches()) {
- throw new NumberFormatException(
- "Invalid port configuration: '"
- + port
- + "'. Make sure the port is a single number or a range of two numbers separated "
- + "with a '-', with or without protocol specified (e.g. '/tcp' or "
- + "'/udp').");
- }
-
- // Parse protocol
- int min = Integer.parseInt(matcher.group(1));
- int max = min;
- if (!Strings.isNullOrEmpty(matcher.group(2))) {
- max = Integer.parseInt(matcher.group(2));
- }
- String protocol = matcher.group(3);
-
- // Error if configured as 'max-min' instead of 'min-max'
- if (min > max) {
- throw new NumberFormatException(
- "Invalid port range '" + port + "'; smaller number must come first.");
- }
-
- // Warn for possibly invalid port numbers
- if (min < 1 || max > 65535) {
- // TODO: Add details/use HelpfulSuggestions for these warnings
- buildLogger.warn("Port number '" + port + "' is out of usual range (1-65535).");
- }
-
- // Add all numbers in range to list
- for (int portNum = min; portNum <= max; portNum++) {
- // TODO: Use a class w/ port number and protocol instead of a string
- result.add(portNum + (protocol == null ? "" : protocol));
- }
- }
-
- return result.build();
- }
}
/**
diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/configuration/PortWithProtocol.java b/jib-core/src/main/java/com/google/cloud/tools/jib/configuration/PortWithProtocol.java
new file mode 100644
index 0000000000..fbeff6580b
--- /dev/null
+++ b/jib-core/src/main/java/com/google/cloud/tools/jib/configuration/PortWithProtocol.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 Google LLC. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.cloud.tools.jib.configuration;
+
+/** Holds port number and protocol for an exposed port. */
+public class PortWithProtocol {
+
+ /** Represents the protocol portion of the port. */
+ public enum Protocol {
+ TCP("tcp"),
+ UDP("udp");
+
+ private final String stringRepresentation;
+
+ Protocol(String stringRepresentation) {
+ this.stringRepresentation = stringRepresentation;
+ }
+
+ @Override
+ public String toString() {
+ return stringRepresentation;
+ }
+ }
+
+ private final int port;
+ private final Protocol protocol;
+
+ public PortWithProtocol(int port, Protocol protocol) {
+ this.port = port;
+ this.protocol = protocol;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public Protocol getProtocol() {
+ return protocol;
+ }
+}
diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/ExposedPortsParser.java b/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/ExposedPortsParser.java
new file mode 100644
index 0000000000..845466cbf2
--- /dev/null
+++ b/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/ExposedPortsParser.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2018 Google LLC. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.cloud.tools.jib.frontend;
+
+import com.google.cloud.tools.jib.builder.BuildLogger;
+import com.google.cloud.tools.jib.configuration.PortWithProtocol;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ExposedPortsParser {
+
+ /**
+ * Pattern used for parsing information out of exposed port configurations.
+ *
+ * Examples: 100, 200-210, 1000/tcp, 2000/udp, 500-600/tcp
+ */
+ private static final Pattern portPattern = Pattern.compile("(\\d+)(?:-(\\d+))?(/tcp|/udp)?");
+
+ /**
+ * TODO: Return list of {@link PortWithProtocol}s instead of strings
+ *
+ *
Converts/validates a list of ports with ranges to an expanded form without ranges.
+ *
+ *
Example: {@code ["1000/tcp", "2000-2002/tcp"] -> ["1000/tcp", "2000/tcp", "2001/tcp",
+ * "2002/tcp"]}
+ *
+ * @param ports the list of port numbers/ranges
+ * @param buildLogger used to log warning messages
+ * @return the ports as a list of integers
+ * @throws NumberFormatException if any of the ports are in an invalid format or out of range
+ */
+ @VisibleForTesting
+ public static ImmutableList parse(List ports, BuildLogger buildLogger)
+ throws NumberFormatException {
+ ImmutableList.Builder result = new ImmutableList.Builder<>();
+
+ for (String port : ports) {
+ Matcher matcher = portPattern.matcher(port);
+
+ if (!matcher.matches()) {
+ throw new NumberFormatException(
+ "Invalid port configuration: '"
+ + port
+ + "'. Make sure the port is a single number or a range of two numbers separated "
+ + "with a '-', with or without protocol specified (e.g. '/tcp' or "
+ + "'/udp').");
+ }
+
+ // Parse protocol
+ int min = Integer.parseInt(matcher.group(1));
+ int max = min;
+ if (!Strings.isNullOrEmpty(matcher.group(2))) {
+ max = Integer.parseInt(matcher.group(2));
+ }
+ String protocol = matcher.group(3);
+
+ // Error if configured as 'max-min' instead of 'min-max'
+ if (min > max) {
+ throw new NumberFormatException(
+ "Invalid port range '" + port + "'; smaller number must come first.");
+ }
+
+ // Warn for possibly invalid port numbers
+ if (min < 1 || max > 65535) {
+ // TODO: Add details/use HelpfulSuggestions for these warnings
+ buildLogger.warn("Port number '" + port + "' is out of usual range (1-65535).");
+ }
+
+ // Add all numbers in range to list
+ String portString = (protocol == null ? "" : protocol);
+ for (int portNum = min; portNum <= max; portNum++) {
+ result.add(portNum + portString);
+ }
+ }
+
+ return result.build();
+ }
+
+ private ExposedPortsParser() {}
+}
diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/builder/BuildConfigurationTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/builder/BuildConfigurationTest.java
index f816eee51a..22875d8b91 100644
--- a/jib-core/src/test/java/com/google/cloud/tools/jib/builder/BuildConfigurationTest.java
+++ b/jib-core/src/test/java/com/google/cloud/tools/jib/builder/BuildConfigurationTest.java
@@ -31,16 +31,10 @@
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.junit.MockitoJUnitRunner;
-@RunWith(MockitoJUnitRunner.class)
public class BuildConfigurationTest {
- @Mock private BuildLogger mockLogger;
-
@Test
public void testBuilder() {
String expectedBaseImageServerUrl = "someserver";
@@ -202,61 +196,4 @@ public void testValidJavaClassRegex() {
Assert.assertFalse(BuildConfiguration.isValidJavaClass("{class}"));
Assert.assertFalse(BuildConfiguration.isValidJavaClass("not valid"));
}
-
- @Test
- public void testExpandPortList() {
- List goodInputs =
- Arrays.asList("1000", "2000-2003", "3000-3000", "4000/tcp", "5000/udp", "6000-6002/tcp");
- ImmutableList expected =
- new ImmutableList.Builder()
- .add(
- "1000",
- "2000",
- "2001",
- "2002",
- "2003",
- "3000",
- "4000/tcp",
- "5000/udp",
- "6000/tcp",
- "6001/tcp",
- "6002/tcp")
- .build();
- BuildConfiguration.Builder builder = BuildConfiguration.builder(mockLogger);
- ImmutableList result = builder.expandPortRanges(goodInputs);
- Assert.assertEquals(expected, result);
-
- List badInputs = Arrays.asList("abc", "/udp", "1000/abc", "a100/tcp", "20/udpabc");
- for (String input : badInputs) {
- try {
- builder.expandPortRanges(Collections.singletonList(input));
- Assert.fail();
- } catch (NumberFormatException ex) {
- Assert.assertEquals(
- "Invalid port configuration: '"
- + input
- + "'. Make sure the port is a single number or a range of two numbers separated "
- + "with a '-', with or without protocol specified (e.g. '/tcp' or "
- + "'/udp').",
- ex.getMessage());
- }
- }
-
- try {
- builder.expandPortRanges(Collections.singletonList("4002-4000"));
- Assert.fail();
- } catch (NumberFormatException ex) {
- Assert.assertEquals(
- "Invalid port range '4002-4000'; smaller number must come first.", ex.getMessage());
- }
-
- builder.expandPortRanges(Collections.singletonList("0"));
- Mockito.verify(mockLogger).warn("Port number '0' is out of usual range (1-65535).");
- builder.expandPortRanges(Collections.singletonList("70000"));
- Mockito.verify(mockLogger).warn("Port number '70000' is out of usual range (1-65535).");
- builder.expandPortRanges(Collections.singletonList("0-400"));
- Mockito.verify(mockLogger).warn("Port number '0-400' is out of usual range (1-65535).");
- builder.expandPortRanges(Collections.singletonList("1-70000"));
- Mockito.verify(mockLogger).warn("Port number '1-70000' is out of usual range (1-65535).");
- }
}
diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/ExposedPortsParserTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/ExposedPortsParserTest.java
new file mode 100644
index 0000000000..e44e8c0d66
--- /dev/null
+++ b/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/ExposedPortsParserTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2018 Google LLC. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.cloud.tools.jib.frontend;
+
+import com.google.cloud.tools.jib.builder.BuildLogger;
+import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+/** Tests for {@link ExposedPortsParser}. */
+@RunWith(MockitoJUnitRunner.class)
+public class ExposedPortsParserTest {
+
+ @Mock private BuildLogger mockLogger;
+
+ @Test
+ public void testExpandPortList() {
+ List goodInputs =
+ Arrays.asList("1000", "2000-2003", "3000-3000", "4000/tcp", "5000/udp", "6000-6002/tcp");
+ ImmutableList expected =
+ new ImmutableList.Builder()
+ .add(
+ "1000",
+ "2000",
+ "2001",
+ "2002",
+ "2003",
+ "3000",
+ "4000/tcp",
+ "5000/udp",
+ "6000/tcp",
+ "6001/tcp",
+ "6002/tcp")
+ .build();
+ ImmutableList result = ExposedPortsParser.parse(goodInputs, mockLogger);
+ Assert.assertEquals(expected, result);
+
+ List badInputs = Arrays.asList("abc", "/udp", "1000/abc", "a100/tcp", "20/udpabc");
+ for (String input : badInputs) {
+ try {
+ ExposedPortsParser.parse(Collections.singletonList(input), mockLogger);
+ Assert.fail();
+ } catch (NumberFormatException ex) {
+ Assert.assertEquals(
+ "Invalid port configuration: '"
+ + input
+ + "'. Make sure the port is a single number or a range of two numbers separated "
+ + "with a '-', with or without protocol specified (e.g. '/tcp' or "
+ + "'/udp').",
+ ex.getMessage());
+ }
+ }
+
+ try {
+ ExposedPortsParser.parse(Collections.singletonList("4002-4000"), mockLogger);
+ Assert.fail();
+ } catch (NumberFormatException ex) {
+ Assert.assertEquals(
+ "Invalid port range '4002-4000'; smaller number must come first.", ex.getMessage());
+ }
+
+ ExposedPortsParser.parse(Collections.singletonList("0"), mockLogger);
+ Mockito.verify(mockLogger).warn("Port number '0' is out of usual range (1-65535).");
+ ExposedPortsParser.parse(Collections.singletonList("70000"), mockLogger);
+ Mockito.verify(mockLogger).warn("Port number '70000' is out of usual range (1-65535).");
+ ExposedPortsParser.parse(Collections.singletonList("0-400"), mockLogger);
+ Mockito.verify(mockLogger).warn("Port number '0-400' is out of usual range (1-65535).");
+ ExposedPortsParser.parse(Collections.singletonList("1-70000"), mockLogger);
+ Mockito.verify(mockLogger).warn("Port number '1-70000' is out of usual range (1-65535).");
+ }
+}
diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java
index 14c8f054fb..9db4605648 100644
--- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java
+++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java
@@ -22,6 +22,7 @@
import com.google.cloud.tools.jib.docker.DockerClient;
import com.google.cloud.tools.jib.frontend.BuildStepsExecutionException;
import com.google.cloud.tools.jib.frontend.BuildStepsRunner;
+import com.google.cloud.tools.jib.frontend.ExposedPortsParser;
import com.google.cloud.tools.jib.frontend.HelpfulSuggestions;
import com.google.cloud.tools.jib.http.Authorization;
import com.google.cloud.tools.jib.image.ImageReference;
@@ -108,7 +109,8 @@ public void buildDocker() throws InvalidImageReferenceException {
.setMainClass(mainClass)
.setJavaArguments(jibExtension.getArgs())
.setJvmFlags(jibExtension.getJvmFlags())
- .setExposedPorts(jibExtension.getExposedPorts())
+ .setExposedPorts(
+ ExposedPortsParser.parse(jibExtension.getExposedPorts(), gradleBuildLogger))
.setAllowHttp(jibExtension.getAllowInsecureRegistries());
CacheConfiguration applicationLayersCacheConfiguration =
CacheConfiguration.forPath(gradleProjectProperties.getCacheDirectory());
diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java
index 44241fb666..61e92b8177 100644
--- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java
+++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java
@@ -21,6 +21,7 @@
import com.google.cloud.tools.jib.configuration.CacheConfiguration;
import com.google.cloud.tools.jib.frontend.BuildStepsExecutionException;
import com.google.cloud.tools.jib.frontend.BuildStepsRunner;
+import com.google.cloud.tools.jib.frontend.ExposedPortsParser;
import com.google.cloud.tools.jib.frontend.HelpfulSuggestions;
import com.google.cloud.tools.jib.http.Authorization;
import com.google.cloud.tools.jib.image.ImageReference;
@@ -110,7 +111,8 @@ public void buildImage() throws InvalidImageReferenceException {
.setMainClass(mainClass)
.setJavaArguments(jibExtension.getArgs())
.setJvmFlags(jibExtension.getJvmFlags())
- .setExposedPorts(jibExtension.getExposedPorts())
+ .setExposedPorts(
+ ExposedPortsParser.parse(jibExtension.getExposedPorts(), gradleBuildLogger))
.setTargetFormat(jibExtension.getFormat())
.setAllowHttp(jibExtension.getAllowInsecureRegistries());
CacheConfiguration applicationLayersCacheConfiguration =
diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java
index 0bedfc3b58..8defaed68c 100644
--- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java
+++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java
@@ -17,6 +17,7 @@
package com.google.cloud.tools.jib.gradle;
import com.google.cloud.tools.jib.docker.DockerContextGenerator;
+import com.google.cloud.tools.jib.frontend.ExposedPortsParser;
import com.google.common.base.Preconditions;
import com.google.common.io.InsecureRecursiveDeleteException;
import java.io.IOException;
@@ -105,6 +106,10 @@ public void generateDockerContext() {
String targetDir = getTargetDir();
try {
+ // Validate port input, but don't save the output because we don't want the ranges expanded
+ // here.
+ ExposedPortsParser.parse(jibExtension.getExposedPorts(), gradleBuildLogger);
+
new DockerContextGenerator(gradleProjectProperties.getSourceFilesConfiguration())
.setBaseImage(jibExtension.getBaseImage())
.setJvmFlags(jibExtension.getJvmFlags())
diff --git a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildDockerMojo.java b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildDockerMojo.java
index ebc45847d6..c4c275f637 100644
--- a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildDockerMojo.java
+++ b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildDockerMojo.java
@@ -22,6 +22,7 @@
import com.google.cloud.tools.jib.docker.DockerClient;
import com.google.cloud.tools.jib.frontend.BuildStepsExecutionException;
import com.google.cloud.tools.jib.frontend.BuildStepsRunner;
+import com.google.cloud.tools.jib.frontend.ExposedPortsParser;
import com.google.cloud.tools.jib.frontend.HelpfulSuggestions;
import com.google.cloud.tools.jib.image.ImageReference;
import com.google.cloud.tools.jib.registry.RegistryClient;
@@ -88,7 +89,7 @@ public void execute() throws MojoExecutionException {
.setJavaArguments(getArgs())
.setJvmFlags(getJvmFlags())
.setEnvironment(getEnvironment())
- .setExposedPorts(getExposedPorts())
+ .setExposedPorts(ExposedPortsParser.parse(getExposedPorts(), mavenBuildLogger))
.setAllowHttp(getAllowInsecureRegistries());
CacheConfiguration applicationLayersCacheConfiguration =
CacheConfiguration.forPath(mavenProjectProperties.getCacheDirectory());
diff --git a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildImageMojo.java b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildImageMojo.java
index 84c8ae0e86..a01315ece6 100644
--- a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildImageMojo.java
+++ b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildImageMojo.java
@@ -21,6 +21,7 @@
import com.google.cloud.tools.jib.configuration.CacheConfiguration;
import com.google.cloud.tools.jib.frontend.BuildStepsExecutionException;
import com.google.cloud.tools.jib.frontend.BuildStepsRunner;
+import com.google.cloud.tools.jib.frontend.ExposedPortsParser;
import com.google.cloud.tools.jib.frontend.HelpfulSuggestions;
import com.google.cloud.tools.jib.image.ImageFormat;
import com.google.cloud.tools.jib.image.ImageReference;
@@ -104,7 +105,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
.setJavaArguments(getArgs())
.setJvmFlags(getJvmFlags())
.setEnvironment(getEnvironment())
- .setExposedPorts(getExposedPorts())
+ .setExposedPorts(ExposedPortsParser.parse(getExposedPorts(), mavenBuildLogger))
.setTargetFormat(ImageFormat.valueOf(getFormat()).getManifestTemplateClass())
.setAllowHttp(getAllowInsecureRegistries());
CacheConfiguration applicationLayersCacheConfiguration =
diff --git a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java
index a72cb03a8b..39ce5c4484 100644
--- a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java
+++ b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java
@@ -17,6 +17,7 @@
package com.google.cloud.tools.jib.maven;
import com.google.cloud.tools.jib.docker.DockerContextGenerator;
+import com.google.cloud.tools.jib.frontend.ExposedPortsParser;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.io.InsecureRecursiveDeleteException;
@@ -58,6 +59,10 @@ public void execute() throws MojoExecutionException, MojoFailureException {
String mainClass = mavenProjectProperties.getMainClass(this);
try {
+ // Validate port input, but don't save the output because we don't want the ranges expanded
+ // here.
+ ExposedPortsParser.parse(getExposedPorts(), mavenBuildLogger);
+
new DockerContextGenerator(mavenProjectProperties.getSourceFilesConfiguration())
.setBaseImage(getBaseImage())
.setJvmFlags(getJvmFlags())