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

mvn spring-boot:build-image fails when 'classifier' is set to non-default value #26721

Open
kdvolder opened this issue May 31, 2021 · 11 comments
Labels
type: bug A general bug
Milestone

Comments

@kdvolder
Copy link
Member

kdvolder commented May 31, 2021

Spring-boot version: 2.5.0 (also originally this happened to me with version 2.4.3, but I reproduced in 2.5.0 to file this bug).

Steps:

First create a new empty maven project with start.spring.io

Then add a 'classifier' to the spring-boot maven plugin configuration:

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<classifier>exec</classifier>
				</configuration>
			</plugin>
		</plugins>
	</build>

Then run

$ ./mvnw spring-boot:build-image

Relevant error excerpt (full output end of this issue):

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.5.0:build-image (default-cli) 
   on project bug-example: 
      Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:2.5.0:build-image failed: 
         Original source 
           '/home/kdvolder/workspaces/tanzu-starter-service/bug-example/target/bug-example-0.0.1-SNAPSHOT-exec.jar.original' 
          is required for building an image -> [Help 1]

It seems like the build-image task is confused by the changes in config affecting the 'repackage' operation. It is looking for the 'original' (i.e. prior to repackaging) jar in the wrong place.

Perhaps this is something I am doing wrong? It is entirely possible. If so I apologise.

However, this feels like a bug to me as it seems reasonable to expect the repackage and the build-image tasks to be aware of eachother. They are both part of the same spring-boot maven plugin and the docs seem to even suggest they are tightly coupled and are supposed to work together.

So far the only workaround that I have found for this problem is to simply refrain from configuring a classifier.

Full output:

kdvolder@dellicioso:~/workspaces/tanzu-starter-service/bug-example$ ./mvnw spring-boot:build-image
OpenJDK 64-Bit Server VM warning: Ignoring option MaxPermSize; support was removed in 8.0
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------------------< com.example:bug-example >-----------------------
[INFO] Building bug-example 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] >>> spring-boot-maven-plugin:2.5.0:build-image (default-cli) > package @ bug-example >>>
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ bug-example ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ bug-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ bug-example ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] skip non existing resourceDirectory /home/kdvolder/workspaces/tanzu-starter-service/bug-example/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ bug-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ bug-example ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.vmware.tss.engine.core.BugExampleApplicationTests
14:06:55.552 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
14:06:55.562 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
14:06:55.593 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.vmware.tss.engine.core.BugExampleApplicationTests] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
14:06:55.602 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.vmware.tss.engine.core.BugExampleApplicationTests], using SpringBootContextLoader
14:06:55.606 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.vmware.tss.engine.core.BugExampleApplicationTests]: class path resource [com/vmware/tss/engine/core/BugExampleApplicationTests-context.xml] does not exist
14:06:55.606 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.vmware.tss.engine.core.BugExampleApplicationTests]: class path resource [com/vmware/tss/engine/core/BugExampleApplicationTestsContext.groovy] does not exist
14:06:55.607 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.vmware.tss.engine.core.BugExampleApplicationTests]: no resource found for suffixes {-context.xml, Context.groovy}.
14:06:55.607 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.vmware.tss.engine.core.BugExampleApplicationTests]: BugExampleApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
14:06:55.640 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.vmware.tss.engine.core.BugExampleApplicationTests]
14:06:55.685 [main] DEBUG org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider - Identified candidate component class: file [/home/kdvolder/workspaces/tanzu-starter-service/bug-example/target/classes/com/vmware/tss/engine/core/BugExampleApplication.class]
14:06:55.686 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration com.vmware.tss.engine.core.BugExampleApplication for test class com.vmware.tss.engine.core.BugExampleApplicationTests
14:06:55.760 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - @TestExecutionListeners is not present for class [com.vmware.tss.engine.core.BugExampleApplicationTests]: using defaults.
14:06:55.760 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.event.ApplicationEventsTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener]
14:06:55.768 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [javax/servlet/ServletContext]
14:06:55.770 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [org/springframework/transaction/TransactionDefinition]
14:06:55.770 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
14:06:55.771 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@63a270c9, org.springframework.test.context.event.ApplicationEventsTestExecutionListener@37c7595, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@3ed242a4, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@1199fe66, org.springframework.test.context.support.DirtiesContextTestExecutionListener@614df0a4, org.springframework.test.context.event.EventPublishingTestExecutionListener@1fdf1c5, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@2d96543c, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@73a2e526, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@7d64e326, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@13f95696, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@cd1d761, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener@68be8808]
14:06:55.774 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: context [DefaultTestContext@6e35bc3d testClass = BugExampleApplicationTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1cdc4c27 testClass = BugExampleApplicationTests, locations = '{}', classes = '{class com.vmware.tss.engine.core.BugExampleApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@aba625, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@4b520ea8, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@7eecb5b8, org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@4dc27487, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@798162bc, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@1df82230], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]], class annotated with @DirtiesContext [false] with mode [null].
14:06:55.785 [main] DEBUG org.springframework.test.context.support.DependencyInjectionTestExecutionListener - Performing dependency injection for test context [[DefaultTestContext@6e35bc3d testClass = BugExampleApplicationTests, testInstance = com.vmware.tss.engine.core.BugExampleApplicationTests@1d730606, testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1cdc4c27 testClass = BugExampleApplicationTests, locations = '{}', classes = '{class com.vmware.tss.engine.core.BugExampleApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@aba625, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@4b520ea8, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@7eecb5b8, org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@4dc27487, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@798162bc, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@1df82230], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]].
14:06:55.807 [main] DEBUG org.springframework.test.context.support.TestPropertySourceUtils - Adding inlined properties to environment: {spring.jmx.enabled=false, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.0)

2021-05-31 14:06:56.022  INFO 28090 --- [           main] c.v.t.e.core.BugExampleApplicationTests  : Starting BugExampleApplicationTests using Java 11.0.8 on dellicioso with PID 28090 (started by kdvolder in /home/kdvolder/workspaces/tanzu-starter-service/bug-example)
2021-05-31 14:06:56.024  INFO 28090 --- [           main] c.v.t.e.core.BugExampleApplicationTests  : No active profile set, falling back to default profiles: default
2021-05-31 14:06:56.380  INFO 28090 --- [           main] c.v.t.e.core.BugExampleApplicationTests  : Started BugExampleApplicationTests in 0.571 seconds (JVM running for 1.345)
2021-05-31 14:06:56.382  INFO 28090 --- [           main] o.s.b.a.ApplicationAvailabilityBean      : Application availability state LivenessState changed to CORRECT
2021-05-31 14:06:56.383  INFO 28090 --- [           main] o.s.b.a.ApplicationAvailabilityBean      : Application availability state ReadinessState changed to ACCEPTING_TRAFFIC
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.126 s - in com.vmware.tss.engine.core.BugExampleApplicationTests
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ bug-example ---
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.5.0:repackage (repackage) @ bug-example ---
[INFO] Attaching repackaged archive /home/kdvolder/workspaces/tanzu-starter-service/bug-example/target/bug-example-0.0.1-SNAPSHOT-exec.jar with classifier exec
[INFO] 
[INFO] <<< spring-boot-maven-plugin:2.5.0:build-image (default-cli) < package @ bug-example <<<
[INFO] 
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.5.0:build-image (default-cli) @ bug-example ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.354 s
[INFO] Finished at: 2021-05-31T14:06:57-07:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.5.0:build-image (default-cli) on project bug-example: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:2.5.0:build-image failed: Original source '/home/kdvolder/workspaces/tanzu-starter-service/bug-example/target/bug-example-0.0.1-SNAPSHOT-exec.jar.original' is required for building an image -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException
@snicoll
Copy link
Member

snicoll commented Jun 1, 2021

@kdvolder Using a goal like that in isolation is not working great with Maven. It really is supposed to be invoked using a phase, not a goal. We're trying to do our best with what Maven allows us to do but it is far from perfect. If you run mvn package spring-boot:build-image, that builds the image properly. I agree it is confusing and perhaps there's something we can fix still.

First create a new empty maven project with start.spring.io

Going forward, please push the sample project on GitHub and share the link. You describing the steps and us following them is really a waste of time for everybody compared to cloning a project and running a command.

@snicoll snicoll added for: team-attention An issue we'd like other members of the team to review status: waiting-for-triage An issue we've not yet triaged labels Jun 1, 2021
@kdvolder
Copy link
Member Author

kdvolder commented Jun 1, 2021

I tried ./mvnw package spring-boot:build-image and can confirm it works for me as well. So that's a good workaround for the issue. Thanks for the tip. Strangely when I run the two steps in separate commands instead it still fails. I'm not quite sure how that's even possible, but I guess you have to really be familiar with the internals of spring-boot-maven plugin to make sense of that.

Sorry about not attaching a sample. I did my best to describe the issue as clearly as possible, so that the steps would be easy to reproduce. And there really isn't anything in the sample project except what initializer generated and a few lines of extra xml. So it seemed a bit pointless to me to attach this.

But anyhow, I'll keep in mind for the next time. And I still have the project here so I'll attach it now:

bug-example.zip

@snicoll
Copy link
Member

snicoll commented Jun 1, 2021

Strangely when I run the two steps in separate commands instead it still fails.

Thanks, that's an interesting piece of information.

Sorry about not attaching a sample. I did my best to describe the issue as clearly as possible, so that the steps would be easy to reproduce. And there really isn't anything in the sample project except what initializer generated and a few lines of extra xml. So it seemed a bit pointless to me to attach this.

The point I was trying to make is that the time you spent describing what you did and the time we spent to read and replicate what you've described can be eliminated by providing the project. Surely it still requires some description but we're reducing greatly the chances of making a mistake while trying to replicate the description in our own project. Thanks for sharing the sample project.

@kdvolder
Copy link
Member Author

kdvolder commented Jun 1, 2021

Point about sample project taken. I guess I didn't think about it that way. The steps in themselves seem interesting to me as they clearly document what exactly is interesting about the sample (i.e. it only has one small change from a 'run of the mill' project, and surely that would be a good clue as to what the cause of the problem might be. But I could have given these steps as well as attached the sample, and it would have made the bug report strictly better and even easier to reproduce. So I should have thought of that.

@wilkinsona wilkinsona added type: bug A general bug and removed for: team-attention An issue we'd like other members of the team to review status: waiting-for-triage An issue we've not yet triaged labels Jul 26, 2021
@wilkinsona wilkinsona added this to the 2.4.x milestone Jul 26, 2021
@dsyer
Copy link
Member

dsyer commented Jul 27, 2021

I suggest that since it works without the "classifier" configuration, there might be a bug in Spring Boot and we should be able to fix it. You can easily reproduce this with any app downloaded from start.spring.io, by adding the classifier to the Spring Boot Maven plugin config, and then running ./mvnw clean spring-boot:build-image.

@snicoll
Copy link
Member

snicoll commented Jul 27, 2021

@dsyer this is already triaged as a bug...

@wilkinsona wilkinsona modified the milestones: 2.4.x, 2.5.x Nov 17, 2021
@wilkinsona wilkinsona modified the milestones: 2.5.x, 2.6.x May 19, 2022
@asandoval95
Copy link

If you change the spring-boot-maven-plugin plugin configuration from

this:

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<configuration>
				<classifier>exec</classifier>
			</configuration>
		</plugin>
	</plugins>
</build>

to this:

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<executions>
				<execution>
					<id>repackage</id>
					<goals>
						<goal>repackage</goal>
					</goals>
					<configuration>
						<classifier>exec</classifier>
					</configuration>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

then it works. Maybe this will help to understand the problem

@hamza-elyaaqoubi
Copy link

@asandoval95 It's seems that your suggestion does not work as expected.

With your configuration, the generated image size is about 230MB. It's greater than the first generated image when executing the command mvn package spring-boot:build-image

But this issue is tagged as a bug.

@wilkinsona wilkinsona modified the milestones: 2.6.x, 2.7.x Nov 24, 2022
@cforce
Copy link

cforce commented Jan 2, 2023

Is this fixed in 3.x?

@dsyer
Copy link
Member

dsyer commented Jan 2, 2023

Since it’s still open, I doubt it. The workaround should still be fine though.

@philwebb philwebb modified the milestones: 2.7.x, 3.1.x Nov 8, 2023
@mhalbritter
Copy link
Contributor

mhalbritter commented Apr 26, 2024

When running spring-boot:build-image without package, MavenProject.getArtifact() returns an Artifact whose getFile() returns null (this is used in org.springframework.boot.maven.BuildImageMojo#getBackupFile). When running package spring-boot:build-image, MavenProject.getArtifact().getFile() returns the location to the original JAR file.

I don't have enough Maven expertise to tell if we can change that somehow.

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

No branches or pull requests

9 participants