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

jib maven plugin 3.0.0 does not impose mainClass property while 3.1.0 does; but I just want to run a jar file #3313

Closed
WesternGun opened this issue Jun 22, 2021 · 5 comments

Comments

@WesternGun
Copy link

WesternGun commented Jun 22, 2021

I have defined this pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>foo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>app</artifactId>
    <properties>
        <docker.registry>some-repo</docker.registry>
        <docker.base.image>${docker.registry}/base/openjdk11:latest</docker.base.image>
        <docker.image>app</docker.image>
        <https.port>8443</https.port>
        <work.dir>/home/wiremock</work.dir>
        <jar>wiremock-jre8-standalone-${wiremock.standalone.version}.jar</jar>
        <full.path>${work.dir}/${jar}</full.path>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.github.tomakehurst</groupId>
            <artifactId>wiremock-jre8-standalone</artifactId>
            <version>${wiremock.standalone.version}</version>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>${maven.dependency.plugin.version}</version>
                <executions>
                    <execution>
                        <!-- make sure the phase here is before the phase to which jib build is attached to -->
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.basedir}/libs</outputDirectory>
                            <includeArtifactIds>wiremock-jre8-standalone</includeArtifactIds>
                        </configuration>
                    </execution>
                </executions>

            </plugin>
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>${jib.plugin.version}</version> <!-- <---------- here we can define 3.0.0 and 3.1.0, which leads to build success/build error -->
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <from>
                        <image>${docker.base.image}</image>
                    </from>
                    <to>
                        <image>${docker.image}</image>
                        <tags>
                            <tag>latest</tag>
                        </tags>
                    </to>
                    <extraDirectories>
                        <paths>
                            <path>
                                <from>libs/*.jar</from>
                                <into>${work.dir}</into>
                            </path>
                            <path>
                                <from>src/main/resources/stubs/__files</from>
                                <into>${work.dir}/__files</into>
                            </path>
                            <path>
                                <from>src/main/resources/stubs/mappings</from>
                                <into>${work.dir}/mappings</into>
                            </path>
                        </paths>
                        <permissions>
                            <permission>
                                <file>${work.dir}/**/*.*</file>
                                <mode>744</mode>
                            </permission>
                        </permissions>
                    </extraDirectories>
                    <container>
                        <appRoot>${work.dir}</appRoot>
                        <workingDirectory>${work.dir}</workingDirectory>
                        <ports>
                            <port>8080</port>
                            <port>${https.port}</port>
                        </ports>
                        <entrypoint>java,-jar,${full.path},--https-port,${https.port},--verbose</entrypoint>
                    </container>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

What I want to do, is to run java -jar wiremock-xxx.jar in my image.

When the plugin version is 3.0.0, the build and run succeeds. But, when I change to 3.1.0, mvn jib:dockerBuild errors out:

[ERROR] Failed to execute goal com.google.cloud.tools:jib-maven-plugin:3.1.0:dockerBuild (default-cli) on project app: Main class was not found, perhaps you should add a `mainClass` configuration to jib-maven-plugin -> [Help 1]

I know running a jar is not the most recommended way of using jib, but I think jib should allows it. And 3.0.0 to 3.1.0 is a minor version upgrade, there should not be any breaking change.

@WesternGun WesternGun changed the title Maven plugin 3.0.0 does not impose mainClass property while 3.1.0 does; but I just want to run a jar file jib maven plugin 3.0.0 does not impose mainClass property while 3.1.0 does; but I just want to run a jar file Jun 22, 2021
@chanseokoh
Copy link
Member

Sorry for the trouble. It's a regression introduced in 3.1.0. Use 3.1.1, you should be all good.

Closing as a dup of #3295.

@chanseokoh
Copy link
Member

BTW, you don't need <tags>. They are actually "additional tags". (I know the naming choice was not good.) <image>${docker.image}</image> already implies <image>${docker.image}:latest</image>.

                        <image>${docker.image}</image>
-                       <tags>
-                           <tag>latest</tag>
-                       </tags>

And I think there will be quite an inefficiency in your built image. Seems like you're copying all the dependency JARs and the app JAR yourself, which is what Jib is already doing. You're duplicate all these JARs. If you have to use a JAR, why don't you just do <containerizingMode>packaged and then perhaps you should be able to remove the <extraDirectories> that copies the JARs?

@WesternGun
Copy link
Author

WesternGun commented Jun 28, 2021

Thanks for correcting this.
Actually what this image does is not the normal "build my classes to a jar"; it uses the dependency Wiremock-standalone jar and runs it, because it is executable. __files and mappings in extraDirectories are xml and json files, they are definitions files for Wiremock. So there's no my code to run.
What I don't know is if running with maven, can I just run my dependency jar with packaged mode or not, haven't tried that. Can jib do this?

@chanseokoh
Copy link
Member

chanseokoh commented Jun 28, 2021

I looked at your pom.xml again, and here's what is happening exactly.

The following is not working as you intended and is being ignored. <from> must be a directory and cannot be a glob pattern. You should remove this copy configuration. Believe me, it's being ignored and thus unnecessary.

                            <path>
                                <from>libs/*.jar</from>
                                <into>${work.dir}</into>
                            </path>

Therefore, it's also unnecessary to define maven-dependency-plugin like below, whose intention I believe was to prepare <project>/libs for the broken <extraDirectories> copy above.

                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>${maven.dependency.plugin.version}</version>
                <executions>
                    <execution>
                        <!-- make sure the phase here is before the phase to which jib build is attached to -->
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.basedir}/libs</outputDirectory>
                            <includeArtifactIds>wiremock-jre8-standalone</includeArtifactIds>
                        </configuration>
                    </execution>
                </executions>

At the same time, Jib is copying all the project dependencies to <appRoot>/libs (including wiremock-jre8-standalone-<version>.jar), which in your case is /home/wiremock/libs. (If you haven't known, <appRoot>/libs, <appRoot>/classes, and <appRoot>/resoureces are the hard-coded directories where Jib copies dependencies, .class files, and resources, respectively.) That is, the wiremock-jre8-standalone-<version>.jar is at /home/wiremock/libs, not /home/wiremock. I actually confirmed this using your pom.xml. Therefore, java -jar in the entrypoint is pointing to a wrong location:

<full.path>${work.dir}/${jar}</full.path>
...
<entrypoint>java,-jar,${full.path}

The <full.path> should be <full.path>${work.dir}/libs/${jar}</full.path>.

You can use the dive tool to examine the contents of your build image, so check it out. It's very handy.


What I don't know is if running with maven, can I just run my dependency jar with packaged mode or not, haven't tried that.

By now, you should have figured it out, but the mode doesn't matter. Jib always copies all the dependency JARs (including wiremock-jre8-standalone-<version>.jar) into <appRoot>/libs. The mode is only for your application JAR, not dependencies.

@WesternGun
Copy link
Author

That explains what I saw in my image; I always have a "libs" layer in my image and I didn't know why. Thanks a lot! Very grateful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants