diff --git a/Dockerfile b/Dockerfile index 8c29f94..4368c91 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,7 @@ RUN apt-get update \ WORKDIR /app COPY --chown=qqq:qqq qqq-all-app/target/qqq-all-app.jar /app/qqq-all.jar +COPY --chown=qqq:qqq LICENSE NOTICE /app/ USER 10001:10001 EXPOSE 8080 ENV QQQ_ALL_DATA_DIR=/app/data diff --git a/README.md b/README.md index 784a4c0..fb9bb38 100644 --- a/README.md +++ b/README.md @@ -46,3 +46,8 @@ The [4.1.0 release procedure](docs/release.md) describes the separate Maven pare ## Contributing and license See [CONTRIBUTING.md](CONTRIBUTING.md), the [Code of Conduct](CODE_OF_CONDUCT.md), and the [security policy](SECURITY.md). Licensed under Apache-2.0; see [LICENSE](LICENSE) and [NOTICE](NOTICE). + +The application JAR includes exact copies of these project documents under +`META-INF/qqq-all/`, separate from dependency notices. The container also includes +them at `/app/LICENSE` and `/app/NOTICE`. `PackagedNoticesIT` checks the shaded JAR's +project documents against the root files during the existing `mvn verify` lifecycle. diff --git a/qqq-all-app/pom.xml b/qqq-all-app/pom.xml index 0fc3f52..ae616c4 100644 --- a/qqq-all-app/pom.xml +++ b/qqq-all-app/pom.xml @@ -60,6 +60,20 @@ qqq-all-app + + + src/main/resources + + + ${project.basedir}/.. + META-INF/qqq-all + false + + LICENSE + NOTICE + + + org.apache.maven.plugins @@ -93,6 +107,7 @@ ${project.build.directory}/${project.build.finalName}.jar + ${project.basedir}/.. diff --git a/qqq-all-app/src/test/java/com/kingsrook/qqq/all/PackagedNoticesIT.java b/qqq-all-app/src/test/java/com/kingsrook/qqq/all/PackagedNoticesIT.java new file mode 100644 index 0000000..6af4204 --- /dev/null +++ b/qqq-all-app/src/test/java/com/kingsrook/qqq/all/PackagedNoticesIT.java @@ -0,0 +1,40 @@ +/* + * Copyright 2026 Kingsrook, LLC + * 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 https://www.apache.org/licenses/LICENSE-2.0 + */ +package com.kingsrook.qqq.all; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.jar.JarFile; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** Verifies this project's notices in the actual shaded application archive. */ +class PackagedNoticesIT +{ + @ParameterizedTest + @ValueSource(strings = {"LICENSE", "NOTICE"}) + void packagedProjectDocumentMatchesRoot(String document) throws Exception + { + Path rootDocument = Path.of(System.getProperty("qqqAllRoot"), document); + try(JarFile jar = new JarFile(System.getProperty("qqqAllJar"))) + { + String name = "META-INF/qqq-all/" + document; + var entry = jar.getJarEntry(name); + assertNotNull(entry, "Missing project document: " + name); + assertEquals(1L, jar.stream().filter(candidate -> candidate.getName().equals(name)).count(), + "Project document must occur exactly once: " + name); + try(var input = jar.getInputStream(entry)) + { + assertArrayEquals(Files.readAllBytes(rootDocument), input.readAllBytes(), + "Packaged document must preserve root bytes: " + document); + } + } + } +}