Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to add paths to the computed classpath #1642

Merged
merged 11 commits into from
Apr 23, 2019
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,10 @@ private BuildConfiguration.Builder getBuildConfigurationBuilder(
ContainerConfiguration containerConfiguration =
ContainerConfiguration.builder()
.setEntrypoint(
JavaEntrypointConstructor.makeDefaultEntrypoint(
AbsoluteUnixPath.get("/app"), Collections.emptyList(), "HelloWorld"))
JavaEntrypointConstructor.makeEntrypoint(
JavaEntrypointConstructor.defaultClasspath(AbsoluteUnixPath.get("/app")),
Collections.emptyList(),
"HelloWorld"))
.setProgramArguments(Collections.singletonList("An argument."))
.setEnvironment(ImmutableMap.of("env1", "envvalue1", "env2", "envvalue2"))
.setExposedPorts(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,11 @@ public class JavaEntrypointConstructor {
public static final RelativeUnixPath DEFAULT_RELATIVE_DEPENDENCIES_PATH_ON_IMAGE =
RelativeUnixPath.get("libs");

public static List<String> makeDefaultEntrypoint(
AbsoluteUnixPath appRoot, List<String> jvmFlags, String mainClass) {
return makeEntrypoint(
Arrays.asList(
appRoot.resolve(DEFAULT_RELATIVE_RESOURCES_PATH_ON_IMAGE).toString(),
appRoot.resolve(DEFAULT_RELATIVE_CLASSES_PATH_ON_IMAGE).toString(),
appRoot.resolve(DEFAULT_RELATIVE_DEPENDENCIES_PATH_ON_IMAGE).resolve("*").toString()),
jvmFlags,
mainClass);
public static List<String> defaultClasspath(AbsoluteUnixPath appRoot) {
return Arrays.asList(
appRoot.resolve(DEFAULT_RELATIVE_RESOURCES_PATH_ON_IMAGE).toString(),
appRoot.resolve(DEFAULT_RELATIVE_CLASSES_PATH_ON_IMAGE).toString(),
appRoot.resolve(DEFAULT_RELATIVE_DEPENDENCIES_PATH_ON_IMAGE).resolve("*").toString());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,60 +17,33 @@
package com.google.cloud.tools.jib.frontend;

import com.google.cloud.tools.jib.filesystem.AbsoluteUnixPath;
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;

/** Tests for {@link JavaEntrypointConstructor}. */
public class JavaEntrypointConstructorTest {

@Test
public void testDefaultClasspath() {
List<String> classpath =
JavaEntrypointConstructor.defaultClasspath(AbsoluteUnixPath.get("/dir"));
Assert.assertEquals(
ImmutableList.of("/dir/resources", "/dir/classes", "/dir/libs/*"), classpath);
}

@Test
public void testMakeEntrypoint() {
String expectedResourcesPath = "/app/resources";
String expectedClassesPath = "/app/classes";
String expectedDependenciesPath = "/app/libs/*";
List<String> expectedJvmFlags = Arrays.asList("-flag", "anotherFlag");
String expectedMainClass = "SomeMainClass";

List<String> entrypoint =
JavaEntrypointConstructor.makeEntrypoint(
Arrays.asList(expectedResourcesPath, expectedClassesPath, expectedDependenciesPath),
expectedJvmFlags,
expectedMainClass);
Arrays.asList("/d1", "/d2", "/d3"), expectedJvmFlags, expectedMainClass);
Assert.assertEquals(
Arrays.asList(
"java",
"-flag",
"anotherFlag",
"-cp",
"/app/resources:/app/classes:/app/libs/*",
"SomeMainClass"),
Arrays.asList("java", "-flag", "anotherFlag", "-cp", "/d1:/d2:/d3", "SomeMainClass"),
entrypoint);

// Checks that this is also the default entrypoint.
Assert.assertEquals(
JavaEntrypointConstructor.makeDefaultEntrypoint(
AbsoluteUnixPath.get("/app"), expectedJvmFlags, expectedMainClass),
entrypoint);
}

@Test
public void testMakeDefaultEntrypoint_classpathString() {
// Checks that this is also the default entrypoint.
List<String> entrypoint =
JavaEntrypointConstructor.makeDefaultEntrypoint(
AbsoluteUnixPath.get("/app"), Collections.emptyList(), "MyMain");
Assert.assertEquals("/app/resources:/app/classes:/app/libs/*", entrypoint.get(2));
}

@Test
public void testMakeDefaultEntrypoint_classpathStringWithNonDefaultAppRoot() {
// Checks that this is also the default entrypoint.
List<String> entrypoint =
JavaEntrypointConstructor.makeDefaultEntrypoint(
AbsoluteUnixPath.get("/my/app"), Collections.emptyList(), "Main");
Assert.assertEquals("/my/app/resources:/my/app/classes:/my/app/libs/*", entrypoint.get(2));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ private static void assertWorkingDirectory(String expected, String imageReferenc
.trim());
}

private static void assertEntrypoint(String expected, String imageReference)
throws IOException, InterruptedException {
Assert.assertEquals(
expected,
new Command("docker", "inspect", "-f", "{{.Config.Entrypoint}}", imageReference)
.run()
.trim());
}

private static void assertLayerSizer(int expected, String imageReference)
throws IOException, InterruptedException {
Command command =
Expand Down Expand Up @@ -184,6 +193,9 @@ public void testBuild_simple() throws IOException, InterruptedException, DigestE
assertDockerInspect(targetImage);
assertSimpleCreationTimeIsAfter(beforeBuild, targetImage);
assertWorkingDirectory("/home", targetImage);
assertEntrypoint(
"[java -cp /d1:/d2:/app/resources:/app/classes:/app/libs/* com.test.HelloWorld]",
targetImage);
assertLayerSizer(8, targetImage);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class ContainerParameters {
private List<String> jvmFlags = Collections.emptyList();
private Map<String, String> environment = Collections.emptyMap();
@Nullable private List<String> entrypoint;
private List<String> extraClasspath = Collections.emptyList();
@Nullable private String mainClass;
@Nullable private List<String> args;
private ImageFormat format = ImageFormat.Docker;
Expand Down Expand Up @@ -107,6 +108,21 @@ public void setEnvironment(Map<String, String> environment) {
this.environment = environment;
}

@Input
@Optional
public List<String> getExtraClasspath() {
if (System.getProperty(PropertyNames.CONTAINER_EXTRA_CLASSPATH) != null) {
return ConfigurationPropertyValidator.parseListProperty(
System.getProperty(PropertyNames.CONTAINER_EXTRA_CLASSPATH));
}

return extraClasspath;
}

public void setExtraClasspath(List<String> classpath) {
this.extraClasspath = classpath;
}

@Input
@Nullable
@Optional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ public Optional<List<String>> getProgramArguments() {
return Optional.ofNullable(jibExtension.getContainer().getArgs());
}

@Override
public List<String> getExtraClasspath() {
return jibExtension.getContainer().getExtraClasspath();
}

@Override
public Optional<String> getMainClass() {
return Optional.ofNullable(jibExtension.getContainer().getMainClass());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ private static void clearProperties() {
System.clearProperty("jib.container.args");
System.clearProperty("jib.container.entrypoint");
System.clearProperty("jib.container.environment");
System.clearProperty("jib.container.extraClasspath");
System.clearProperty("jib.container.format");
System.clearProperty("jib.container.jvmFlags");
System.clearProperty("jib.container.labels");
Expand Down Expand Up @@ -112,6 +113,8 @@ public void testTo() {
public void testContainer() {
Assert.assertEquals(Collections.emptyList(), testJibExtension.getContainer().getJvmFlags());
Assert.assertEquals(Collections.emptyMap(), testJibExtension.getContainer().getEnvironment());
Assert.assertEquals(
Collections.emptyList(), testJibExtension.getContainer().getExtraClasspath());
Assert.assertNull(testJibExtension.getContainer().getMainClass());
Assert.assertNull(testJibExtension.getContainer().getArgs());
Assert.assertSame(ImageFormat.Docker, testJibExtension.getContainer().getFormat());
Expand All @@ -124,6 +127,7 @@ public void testContainer() {
container.setJvmFlags(Arrays.asList("jvmFlag1", "jvmFlag2"));
container.setEnvironment(ImmutableMap.of("var1", "value1", "var2", "value2"));
container.setEntrypoint(Arrays.asList("foo", "bar", "baz"));
container.setExtraClasspath(Arrays.asList("/d1", "/d2", "/d3"));
container.setMainClass("mainClass");
container.setArgs(Arrays.asList("arg1", "arg2", "arg3"));
container.setPorts(Arrays.asList("1000", "2000-2010", "3000"));
Expand All @@ -136,6 +140,7 @@ public void testContainer() {
Assert.assertEquals(Arrays.asList("jvmFlag1", "jvmFlag2"), container.getJvmFlags());
Assert.assertEquals(
ImmutableMap.of("var1", "value1", "var2", "value2"), container.getEnvironment());
Assert.assertEquals(ImmutableList.of("/d1", "/d2", "/d3"), container.getExtraClasspath());
Assert.assertEquals("mainClass", testJibExtension.getContainer().getMainClass());
Assert.assertEquals(Arrays.asList("arg1", "arg2", "arg3"), container.getArgs());
Assert.assertEquals(Arrays.asList("1000", "2000-2010", "3000"), container.getPorts());
Expand Down Expand Up @@ -194,6 +199,9 @@ public void testProperties() {
Assert.assertEquals(
ImmutableMap.of("env1", "val1", "env2", "val2"),
testJibExtension.getContainer().getEnvironment());
System.setProperty("jib.container.extraClasspath", "/d1,/d2,/d3");
Assert.assertEquals(
ImmutableList.of("/d1", "/d2", "/d3"), testJibExtension.getContainer().getExtraClasspath());
System.setProperty("jib.container.format", "OCI");
Assert.assertSame(ImageFormat.OCI, testJibExtension.getContainer().getFormat());
System.setProperty("jib.container.jvmFlags", "flag1,flag2,flag3");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ jib {
extraDirectory {
path = file('src/main/custom-extra-dir')
}
container {
extraClasspath = ['/d1','/d2']
briandealwis marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ public void set(String image) {
/** Configuration for {@code container} parameter. */
public static class ContainerParameters {

// Note: `entrypoint` and `args` are @Nullable to handle inheriting values from the base image

@Parameter private boolean useCurrentTimestamp = false;

@Nullable @Parameter private List<String> entrypoint;
Expand All @@ -162,6 +164,8 @@ public static class ContainerParameters {

@Parameter private Map<String, String> environment = Collections.emptyMap();

@Parameter private List<String> extraClasspath = Collections.emptyList();

@Nullable @Parameter private String mainClass;

@Nullable @Parameter private List<String> args;
Expand Down Expand Up @@ -384,6 +388,19 @@ Map<String, String> getEnvironment() {
return container.environment;
}

/**
* Gets the extra classpath elements.
*
* @return the extra classpath elements
*/
List<String> getExtraClasspath() {
String property = getProperty(PropertyNames.CONTAINER_EXTRA_CLASSPATH);
if (property != null) {
return ConfigurationPropertyValidator.parseListProperty(property);
}
return container.extraClasspath;
}

/**
* Gets the name of the main class.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ public Optional<List<String>> getProgramArguments() {
return Optional.ofNullable(jibPluginConfiguration.getArgs());
}

@Override
public List<String> getExtraClasspath() {
return jibPluginConfiguration.getExtraClasspath();
}

@Override
public Optional<String> getMainClass() {
return Optional.ofNullable(jibPluginConfiguration.getMainClass());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,15 @@ private static void assertWorkingDirectory(String expected, String imageReferenc
.trim());
}

private static void assertEntrypoint(String expected, String imageReference)
throws IOException, InterruptedException {
Assert.assertEquals(
expected,
new Command("docker", "inspect", "-f", "{{.Config.Entrypoint}}", imageReference)
.run()
.trim());
}

private static void assertLayerSizer(int expected, String imageReference)
throws IOException, InterruptedException {
Command command =
Expand Down Expand Up @@ -445,6 +454,9 @@ public void testExecute_complex()
buildAndRunComplex(
targetImage, "testuser2", "testpassword2", localRegistry2, "pom-complex.xml"));
assertWorkingDirectory("", targetImage);
assertEntrypoint(
"[java -Xms512m -Xdebug -cp /other:/app/resources:/app/classes:/app/libs/* com.test.HelloWorld]",
targetImage);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public void execute() {}
public void testDefaults() {
Assert.assertEquals("", testPluginConfiguration.getAppRoot());
Assert.assertNull(testPluginConfiguration.getWorkingDirectory());
Assert.assertTrue(testPluginConfiguration.getExtraClasspath().isEmpty());
}

@Test
Expand Down Expand Up @@ -110,6 +111,9 @@ public void testSystemProperties() {
Assert.assertEquals("myUser", testPluginConfiguration.getUser());
sessionProperties.put("jib.container.workingDirectory", "working directory");
Assert.assertEquals("working directory", testPluginConfiguration.getWorkingDirectory());
sessionProperties.put("jib.container.extraClasspath", "/foo,/bar");
Assert.assertEquals(
ImmutableList.of("/foo", "/bar"), testPluginConfiguration.getExtraClasspath());

sessionProperties.put("jib.extraDirectory.path", "custom-jib");
Assert.assertEquals(
Expand Down Expand Up @@ -172,6 +176,9 @@ public void testPomProperties() {
Assert.assertEquals("myUser", testPluginConfiguration.getUser());
project.getProperties().setProperty("jib.container.workingDirectory", "working directory");
Assert.assertEquals("working directory", testPluginConfiguration.getWorkingDirectory());
project.getProperties().setProperty("jib.container.extraClasspath", "/foo,/bar");
Assert.assertEquals(
ImmutableList.of("/foo", "/bar"), testPluginConfiguration.getExtraClasspath());

project.getProperties().setProperty("jib.extraDirectory.path", "custom-jib");
Assert.assertEquals(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
<arg>An argument.</arg>
</args>
<mainClass>com.test.HelloWorld</mainClass>
<extraClasspath><path>/other</path></extraClasspath>
<jvmFlags>
<jvmFlag>-Xms512m</jvmFlag>
<jvmFlag>-Xdebug</jvmFlag>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -247,13 +248,19 @@ static PluginConfigurationProcessor processCommonConfiguration(
static List<String> computeEntrypoint(
RawConfiguration rawConfiguration, ProjectProperties projectProperties)
throws MainClassInferenceException, InvalidAppRootException, IOException {
AbsoluteUnixPath appRoot =
getAppRootChecked(rawConfiguration, projectProperties.isWarProject());

Optional<List<String>> rawEntrypoint = rawConfiguration.getEntrypoint();
List<String> rawExtraClasspath = rawConfiguration.getExtraClasspath();
if (rawEntrypoint.isPresent() && !rawEntrypoint.get().isEmpty()) {
if (rawConfiguration.getMainClass().isPresent()
|| !rawConfiguration.getJvmFlags().isEmpty()) {
|| !rawConfiguration.getJvmFlags().isEmpty()
|| !rawExtraClasspath.isEmpty()) {
new DefaultEventDispatcher(projectProperties.getEventHandlers())
.dispatch(
LogEvent.warn("mainClass and jvmFlags are ignored when entrypoint is specified"));
LogEvent.warn(
"mainClass, extraClasspath, and jvmFlags are ignored when entrypoint is specified"));
}

if (rawEntrypoint.get().size() == 1 && "INHERIT".equals(rawEntrypoint.get().get(0))) {
Expand All @@ -266,13 +273,13 @@ static List<String> computeEntrypoint(
return null;
}

AbsoluteUnixPath appRoot =
getAppRootChecked(rawConfiguration, projectProperties.isWarProject());
List<String> classpath = new ArrayList<>(rawExtraClasspath);
classpath.addAll(JavaEntrypointConstructor.defaultClasspath(appRoot));
String mainClass =
MainClassResolver.resolveMainClass(
rawConfiguration.getMainClass().orElse(null), projectProperties);
return JavaEntrypointConstructor.makeDefaultEntrypoint(
appRoot, rawConfiguration.getJvmFlags(), mainClass);
return JavaEntrypointConstructor.makeEntrypoint(
classpath, rawConfiguration.getJvmFlags(), mainClass);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class PropertyNames {
public static final String TO_AUTH_PASSWORD = "jib.to.auth.password";
public static final String CONTAINER_APP_ROOT = "jib.container.appRoot";
public static final String CONTAINER_ARGS = "jib.container.args";
public static final String CONTAINER_EXTRA_CLASSPATH = "jib.container.extraClasspath";
public static final String CONTAINER_ENTRYPOINT = "jib.container.entrypoint";
public static final String CONTAINER_ENVIRONMENT = "jib.container.environment";
public static final String CONTAINER_FORMAT = "jib.container.format";
Expand Down
Loading