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

Maven War support #1068

Merged
merged 4 commits into from
Oct 4, 2018
Merged

Conversation

CyrilleH
Copy link
Contributor

@CyrilleH CyrilleH commented Sep 29, 2018

Towards #431, here's my proposal to support "WAR" project with Jib and Maven.

This PR is based from #923.
Once #923 is merged, I will rebase on master. So, please review only the last commit.

@CyrilleH CyrilleH changed the title Maven war support Maven War support Sep 30, 2018
Copy link
Member

@chanseokoh chanseokoh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, @CyrilleH. Thanks a lot for your continued non-trivial contributions! Looks generally good at a high level, and a few things I found in my first quick pass.

/** The standard directory name containing libs and snapshot-libs in a War Project */
public static final String WEB_INF_LIB_RELATIVE_PATH = WEB_INF_RELATIVE_PATH + "/lib/";
/** The standard directory name containing classes and some resources in a War Project */
public static final String WEB_INF_CLASSES_RELATIVE_PATH = WEB_INF_RELATIVE_PATH + "/classes/";
Copy link
Member

@chanseokoh chanseokoh Oct 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think just embedding these constants (except for DEFAULT_WEB_APP_ROOT) has more benefits in this case than declaring as fields here. (#1072 (comment))

BTW, WEBAPP--> WEB_APP

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -46,6 +47,25 @@
*/
static JavaLayerConfigurations getForProject(
MavenProject project, Path extraDirectory, AbsoluteUnixPath appRoot) throws IOException {
// Since 'jar' is the default packaging type it is not required, so it can be null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's OK to do "war".equals(project.getPackaging()) here and remove the null check and the comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

layerBuilder::addDependencyFile);

// Gets the classes files in the 'WEB-INF/classes' output directory.
Predicate<Path> isClassFile = path -> path.toString().endsWith(CLASS_EXTENSION);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I'm thinking path.getFileName().toString() is safer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

boolean inWebInfLib =
path.startsWith(
explodedWarPath.resolve(JavaLayerConfigurations.WEB_INF_LIB_RELATIVE_PATH));
boolean isClass = path.toString().endsWith(CLASS_EXTENSION);
Copy link
Member

@chanseokoh chanseokoh Oct 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsClassFile above, so no need here.

Maybe we can have this predicate as a static class method and share it with getForProject too. On second thought, a static method might be an overkill for this simple code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

MavenProjectProperties projectProperties)
throws MojoExecutionException {

List<String> entrypoint = jibPluginConfiguration.getEntrypoint();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the changes here which I think is more readable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -41,13 +43,13 @@

private DockerContextMojo mojo;
private String appRoot = "/app";
private File outputFolder;
@Mock MavenProject project;
@Mock Build build;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private for these two fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -48,6 +48,6 @@ public void testAuthDefaults() {
Assert.assertEquals(
"<to><auth><password>",
testPluginConfiguration.getTargetImageAuth().getPasswordPropertyDescriptor());
Assert.assertEquals("/app", testPluginConfiguration.getAppRoot());
Assert.assertEquals(null, testPluginConfiguration.getAppRoot());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert.assertNull

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

configuration.getClassLayerEntries());
assertExtractionPathsUnordered(
Arrays.asList("/a/b/bar", "/c/cat", "/foo"), configuration.getExtraFilesLayerEntries());
assert_nonDefaultAppRoot(configuration);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertNonDefaultAppRoot

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

assert_nonDefaultAppRoot(configuration);
}

private void assert_nonDefaultAppRoot(JavaLayerConfigurations configuration) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be private static? If so, change it to static and move the method code above any non-static methods or fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

MavenProject project, Path extraDirectory, AbsoluteUnixPath appRoot) throws IOException {

Path explodedWarPath =
Paths.get(project.getBuild().getDirectory()).resolve(project.getBuild().getFinalName());
Copy link
Member

@chanseokoh chanseokoh Oct 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I think getFinalName() may not work (admittedly in rare cases), because the exploded WAR directory is configurable with <webappDirectory> in the Maven WAR plugin, although the default is ${project.build.directory}/${project.build.finalName}. For example,

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.2.2</version>
        <configuration>
          <webappDirectory>${project.build.directory}/my-webapp</webappDirectory>
        </configuration>
      </plugin>
$ ls target
classes/  generated-sources/  helloworld-1.war  maven-archiver/  maven-status/  my-webapp/

But since we will eventually unzip the WAR file, I think it's OK for now to use finalName().

@chanseokoh chanseokoh mentioned this pull request Oct 1, 2018
// Some files in WEB-INF need to be in resources directory (e.g. web.xml, ...)
Path webinfOutputDirectory =
explodedWarPath.resolve(JavaLayerConfigurations.WEB_INF_RELATIVE_PATH);
try (Stream<Path> fileStream = Files.list(webinfOutputDirectory)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need to check the directory existence for WEB-INF, WEB-INF/lib, and WEB-INF/classes. (See #1074.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@CyrilleH
Copy link
Contributor Author

CyrilleH commented Oct 1, 2018

Since #923 is merged, I have rebased on master.

I have to add some unit tests to check it works correctly if "WEB-INF" is not present (and "WEB-INF/lib" and "WEB-INF/classes").
Sorry for this mistake.

@chanseokoh
Copy link
Member

No problem. We can always fix bugs later.

@@ -139,7 +135,7 @@ public void set(String image) {

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

@Parameter private String appRoot = JavaLayerConfigurations.DEFAULT_APP_ROOT;
@Nullable @Parameter private String appRoot;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember the Gradle counterpart set this to an empty string ("") instead of null. Can we be consistent? is there some reason they cannot be consistent? Not sure whether an empty string or null is better though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

@@ -71,7 +90,7 @@ static JavaLayerConfigurations getForProject(
Path classesOutputDirectory = Paths.get(project.getBuild().getOutputDirectory());

// Gets the classes files in the 'classes' output directory.
Predicate<Path> isClassFile = path -> path.toString().endsWith(".class");
Predicate<Path> isClassFile = path -> path.toString().endsWith(CLASS_EXTENSION);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'm fine with embedding the string .class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

* @param jibPluginConfiguration the Jib plugin configuration
* @return true if the maven packaging type is "war"
*/
private static boolean isWarPackaging(JibPluginConfiguration jibPluginConfiguration) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style nit: in our codebase, private static methods go below (package-private) static methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

* @return the entrypoint
* @throws MojoExecutionException if the http timeout system property is misconfigured
*/
static List<String> computeEntrypoint(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style nit: static methods go above non-static fields or methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@chanseokoh chanseokoh requested a review from a team October 2, 2018 19:19
@chanseokoh
Copy link
Member

Thanks, @CyrilleH. I think this looks good. Merging with master, fixing one or two nits, and I think we're good to go.

Adds unit tests on WEB-INF, WEB-INF/classes, WEB-INF/lib existence
@CyrilleH
Copy link
Contributor Author

CyrilleH commented Oct 3, 2018

Great, @chanseokoh
I rebased my branch on master.
Please tell me if I missed something or if I have to squash the branch into one commit.

Copy link
Member

@chanseokoh chanseokoh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! I think we can merge this. I can take care of some very minor cleanups. Thanks again!

@chanseokoh chanseokoh merged commit 1171796 into GoogleContainerTools:master Oct 4, 2018
@CyrilleH CyrilleH deleted the maven-war-support branch October 4, 2018 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants