Skip to content

Commit 9f72720

Browse files
committed
Build with Java21
Get rid of animal-sniffer Build Maven plugin for Java11 leveraging new API Remove dependencies to Apache Commons IO/Lang
1 parent 7470070 commit 9f72720

File tree

6 files changed

+91
-82
lines changed

6 files changed

+91
-82
lines changed

.github/workflows/maven.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ jobs:
99
steps:
1010
- name: Git Clone
1111
uses: actions/checkout@v3
12-
- name: Set up JDK 1.8
13-
uses: actions/setup-java@v3
12+
- name: Set up JDK 21
13+
uses: actions/setup-java@v4
1414
with:
1515
distribution: 'temurin'
16-
java-version: 11
16+
java-version: 21
1717
server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml
1818
server-username: MAVEN_USERNAME # env variable for username in deploy
1919
server-password: MAVEN_PASSWORD # env variable for token in deploy

aem-classification-maven-plugin/pom.xml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
</site>
2424
</distributionManagement>
2525

26+
<properties>
27+
<maven.compiler.release>11</maven.compiler.release> <!-- used for compiler and javadoc plugin -->
28+
</properties>
29+
2630
<build>
2731
<!-- https://blog.soebes.de/blog/2015/06/12/making-github-page-for-mojohaus/ -->
2832
<pluginManagement>
@@ -121,16 +125,6 @@
121125
<artifactId>aem-classification-validator</artifactId>
122126
<version>1.1.1</version>
123127
</dependency>
124-
<dependency>
125-
<groupId>commons-lang</groupId>
126-
<artifactId>commons-lang</artifactId>
127-
<version>2.5</version>
128-
</dependency>
129-
<dependency>
130-
<groupId>commons-io</groupId>
131-
<artifactId>commons-io</artifactId>
132-
<version>2.7</version>
133-
</dependency>
134128
<!-- for the JSON parser -->
135129
<dependency>
136130
<groupId>org.apache.felix</groupId>

aem-classification-maven-plugin/src/main/java/biz/netcentric/filevault/validator/aem/classification/mojo/DownloadContentClassificationMojo.java

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@
1414
*/
1515

1616
import java.io.File;
17-
import java.io.FileInputStream;
1817
import java.io.FileOutputStream;
1918
import java.io.IOException;
2019
import java.io.InputStream;
21-
import java.net.HttpURLConnection;
22-
import java.net.URL;
20+
import java.io.OutputStream;
21+
import java.net.URI;
2322
import java.net.URLEncoder;
23+
import java.net.http.HttpClient;
24+
import java.net.http.HttpRequest;
25+
import java.net.http.HttpResponse;
2426
import java.nio.charset.StandardCharsets;
27+
import java.nio.file.Files;
28+
import java.nio.file.Path;
2529
import java.util.Base64;
2630
import java.util.Date;
2731
import java.util.EnumSet;
@@ -31,10 +35,9 @@
3135
import java.util.jar.JarEntry;
3236
import java.util.jar.JarOutputStream;
3337
import java.util.jar.Manifest;
38+
import java.util.stream.Collectors;
39+
import java.util.stream.StreamSupport;
3440

35-
import org.apache.commons.io.FilenameUtils;
36-
import org.apache.commons.io.IOUtils;
37-
import org.apache.commons.lang.StringUtils;
3841
import org.apache.felix.utils.json.JSONParser;
3942
import org.apache.maven.plugin.AbstractMojo;
4043
import org.apache.maven.plugin.MojoExecutionException;
@@ -64,7 +67,7 @@ public class DownloadContentClassificationMojo extends AbstractMojo {
6467
* the base URL where AEM is deployed
6568
*/
6669
@Parameter(property="baseUrl", defaultValue="http://localhost:4502")
67-
URL baseUrl;
70+
URI baseUrl;
6871

6972
/**
7073
* the user name to access the {@link baseUrl}
@@ -84,12 +87,13 @@ public class DownloadContentClassificationMojo extends AbstractMojo {
8487
*/
8588
@Parameter(property="relativeFileNameInJar", required = false)
8689
File relativeFileNameInJar;
87-
90+
8891
@Override
8992
public void execute() throws MojoExecutionException, MojoFailureException {
9093
Log log = getLog();
94+
HttpClient httpClient = HttpClient.newHttpClient();
9195
try {
92-
String aemVersion = getAemVersion();
96+
String aemVersion = getAemVersion(httpClient);
9397

9498
log.warn("Make sure that the relevant search index definitions are deployed on AEM at " + baseUrl + ". Otherwise this goal will fail!");
9599
log.info("Start retrieving the classification and deprecation data from " + baseUrl);
@@ -102,31 +106,34 @@ public void execute() throws MojoExecutionException, MojoFailureException {
102106
if (classification.isLabelMixin() == false) {
103107
continue;
104108
}
105-
retrieveClassificationForMixin(classification, map);
109+
retrieveClassificationForMixin(httpClient, classification, map);
106110
}
107111

108112
// 2. update map with deprecation entries
109-
retrieveDeprecatedResourceTypes(map);
113+
retrieveDeprecatedResourceTypes(httpClient, map);
110114

111115
// 3. persist the map
112-
File outputFile = File.createTempFile("contentclassification", ".map");
113-
try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile)) {
116+
Path outputFile = Files.createTempFile("contentclassification", ".map");
117+
try (OutputStream fileOutputStream = Files.newOutputStream(outputFile)) {
114118
map.write(fileOutputStream);
115119
}
116120
log.info("Written classification map to " + outputFile + " containing " + map.size() + " entries.");
117121

118122
// 4. optionally wrap in a JAR
119123
if (relativeFileNameInJar != null) {
120-
File jarFile = createJarWrapper(outputFile, relativeFileNameInJar);
124+
File jarFile = createJarWrapper(outputFile, relativeFileNameInJar.toPath());
121125
log.info("Written wrapper jar to " + jarFile);
122126
}
127+
} catch (InterruptedException e) {
128+
Thread.currentThread().interrupt();
129+
throw new MojoFailureException("Could not retrieve classification metadata: " + e.getMessage(), e);
123130
} catch(IOException|IllegalStateException e) {
124-
throw new MojoFailureException("Could not generate classification JAR:" + e.getMessage(), e);
131+
throw new MojoFailureException("Could not retrieve classification metadata: " + e.getMessage(), e);
125132
}
126133
}
127134

128-
String getAemVersion() throws IOException {
129-
try (InputStream input = getHttpConnectionInputStream("/libs/granite/operations/content/systemoverview/export.json")) {
135+
String getAemVersion(HttpClient httpClient) throws IOException, InterruptedException {
136+
try (InputStream input = downloadFromAem(httpClient, "/libs/granite/operations/content/systemoverview/export.json")) {
130137
JSONParser parser = new JSONParser(input);
131138
Map<String, Object> response = parser.getParsed();
132139
getLog().debug("Received JSON response " + response);
@@ -142,15 +149,15 @@ String getAemVersion() throws IOException {
142149
}
143150

144151
@SuppressWarnings({ "unchecked", "rawtypes" })
145-
void retrieveClassificationForMixin(ContentClassification classification, MutableContentClassificationMap map) throws IOException {
152+
void retrieveClassificationForMixin(HttpClient httpClient, ContentClassification classification, MutableContentClassificationMap map) throws IOException, InterruptedException {
146153
// Uses the crxde search to find the current classification
147154
// (http://localhost:8080/crx/de/query.jsp?_dc=1536334082630&_charset_=utf-8&type=JCR_SQL2&stmt=SELECT%20*%20FROM%20%5Bgranite%3AInternalArea%5D%0A&showResults=true)
148155
// the index is crucial for that though (property index limited to properties jcr:primaryType and jcr:mixinTypes)
149156
// for AEM 6.4 we talk about roughly 300 entries
150157
String query = "SELECT * FROM [" + classification.getLabel() + "]";
151158
StringBuilder urlParameters = new StringBuilder();
152159
urlParameters.append("_dc=").append(new Date().getTime()).append("&_charset_=utf-8&type=JCR-SQL2&stmt=").append(URLEncoder.encode(query, "ASCII")).append("&showResults=true");
153-
try (InputStream input = getHttpConnectionInputStream( "/crx/de/query.jsp?" + urlParameters)) {
160+
try (InputStream input = downloadFromAem(httpClient, "/crx/de/query.jsp?" + urlParameters)) {
154161
JSONParser parser = new JSONParser(input);
155162
Map<String, Object> response = parser.getParsed();
156163
getLog().debug("Received JSON response " + response);
@@ -171,7 +178,7 @@ void retrieveClassificationForMixin(ContentClassification classification, Mutabl
171178
}
172179
for (Map<String, Object> result : (List<Map<String, Object>>)results) {
173180
String resourceType = (String)result.get("path");
174-
if (StringUtils.isNotBlank(resourceType)) {
181+
if (resourceType != null) {
175182
map.put(resourceType, classification, null);
176183
}
177184
}
@@ -181,11 +188,11 @@ void retrieveClassificationForMixin(ContentClassification classification, Mutabl
181188
}
182189

183190
@SuppressWarnings("unchecked")
184-
void retrieveDeprecatedResourceTypes(MutableContentClassificationMap map) throws IOException {
191+
void retrieveDeprecatedResourceTypes(HttpClient httpClient, MutableContentClassificationMap map) throws IOException, InterruptedException {
185192
// uses query builder api to retrieve all deprecation metadata
186193
String query = "1_property=cq:deprecated&1_property.operation=exists&p.limit=-1&p.hits=selective&p.properties=" + URLEncoder.encode("jcr:mixinTypes jcr:path cq:deprecated cq:deprecatedReason", "ASCII");
187194
EnumSet<ContentUsage> allContentUsages = EnumSet.allOf(ContentUsage.class);
188-
try (InputStream input = getHttpConnectionInputStream( "/bin/querybuilder.json?" + query)) {
195+
try (InputStream input = downloadFromAem(httpClient, "/bin/querybuilder.json?" + query)) {
189196
JSONParser parser = new JSONParser(input);
190197
Map<String, Object> response = parser.getParsed();
191198
getLog().debug("Received JSON response " + response);
@@ -211,31 +218,37 @@ void retrieveDeprecatedResourceTypes(MutableContentClassificationMap map) throws
211218
}
212219

213220
@SuppressWarnings("java:S2647") // basic auth is ok in this context
214-
private InputStream getHttpConnectionInputStream(String path) throws IOException {
215-
URL url = new URL(baseUrl, path);
216-
getLog().debug("Connecting to " + url + "...");
217-
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
221+
private InputStream downloadFromAem(HttpClient httpClient, String path) throws IOException, InterruptedException {
218222
String credentials = username+":"+password;
219-
// use basic auth
220-
String encoded = Base64.getEncoder().encodeToString(credentials.getBytes(StandardCharsets.UTF_8)); //Java 8
221-
connection.setRequestProperty("Authorization", "Basic "+encoded);
222-
return connection.getInputStream();
223+
String encoded = Base64.getEncoder().encodeToString(credentials.getBytes(StandardCharsets.UTF_8));
224+
URI uri = baseUrl.resolve(path);
225+
HttpRequest request = HttpRequest.newBuilder()
226+
.uri(uri)
227+
// preemptive-auth only natively supported once authentication in cache (after first successful request), https://stackoverflow.com/a/58612586
228+
.header("Authorization", "Basic "+encoded)
229+
.build();
230+
getLog().debug("Connecting to " + uri + "...");
231+
HttpResponse<InputStream> response = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
232+
return response.body();
223233
}
224234

225-
File createJarWrapper(File sourceFile, File relativeFileNameInJar) throws IOException {
235+
File createJarWrapper(Path sourceFile, Path relativeFileNameInJar) throws IOException {
226236
Manifest manifest = new Manifest();
227237
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
228238
File outputFile = File.createTempFile("contentclassification", ".jar");
229239
try (JarOutputStream target = new JarOutputStream(new FileOutputStream(outputFile), manifest)) {
230-
// convert to forward slashes
231-
JarEntry entry = new JarEntry(FilenameUtils.separatorsToUnix(relativeFileNameInJar.getPath()));
232-
entry.setTime(sourceFile.lastModified());
240+
JarEntry entry = new JarEntry(getPathWithUnixSeparators(relativeFileNameInJar));
241+
entry.setTime(Files.getLastModifiedTime(sourceFile).toMillis());
233242
target.putNextEntry(entry);
234-
try (InputStream input = new FileInputStream(sourceFile)) {
235-
IOUtils.copy(input, target);
243+
try (InputStream input = Files.newInputStream(sourceFile)) {
244+
input.transferTo(target);
236245
}
237246
target.closeEntry();
238247
}
239248
return outputFile;
240249
}
250+
251+
static String getPathWithUnixSeparators(Path path) {
252+
return StreamSupport.stream(path.spliterator(), false).map(Path::toString).collect(Collectors.joining("/"));
253+
}
241254
}

aem-classification-maven-plugin/src/site/site.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
<skin>
5252
<groupId>org.apache.maven.skins</groupId>
5353
<artifactId>maven-fluido-skin</artifactId>
54+
<version>1.12.0</version>
5455
</skin>
5556

5657
<custom>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package biz.netcentric.filevault.validator.aem.classification.mojo;
2+
3+
/*-
4+
* #%L
5+
* AEM Classification Maven Plugin
6+
* %%
7+
* Copyright (C) 2024 Cognizant Netcentric
8+
* %%
9+
* All rights reserved. This program and the accompanying materials
10+
* are made available under the terms of the Eclipse Public License v1.0
11+
* which accompanies this distribution, and is available at
12+
* http://www.eclipse.org/legal/epl-v10.html
13+
* #L%
14+
*/
15+
16+
import static org.junit.jupiter.api.Assertions.assertEquals;
17+
18+
import java.nio.file.Path;
19+
import java.nio.file.Paths;
20+
21+
import org.junit.jupiter.api.Test;
22+
23+
class DownloadContentClassificationMojoTest {
24+
25+
@Test
26+
void testGetPathWithUnixSeparators() {
27+
Path path = Paths.get("my", "test", "path");
28+
assertEquals("my/test/path", DownloadContentClassificationMojo.getPathWithUnixSeparators(path));
29+
}
30+
31+
}

pom.xml

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@
5353

5454
<properties>
5555
<maven.version>3.3.9</maven.version>
56-
<java.target.version>8</java.target.version> <!-- used for compiler plugin and animal-sniffer, for compatibility reasons with Java 9 only the values 6,7,8 and 9 is allowed -->
57-
<maven.compiler.target>1.${java.target.version}</maven.compiler.target>
58-
<maven.compiler.source>${maven.compiler.target}</maven.compiler.source>
56+
<maven.compiler.release>8</maven.compiler.release> <!-- used for compiler and javadoc plugin -->
5957
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
6058
<junit.jupiter.version>5.9.0</junit.jupiter.version>
6159
</properties>
@@ -142,13 +140,6 @@
142140
<plugin>
143141
<artifactId>maven-site-plugin</artifactId>
144142
<version>3.12.0</version>
145-
<dependencies>
146-
<dependency>
147-
<groupId>org.apache.maven.skins</groupId>
148-
<artifactId>maven-fluido-skin</artifactId>
149-
<version>1.11.1</version>
150-
</dependency>
151-
</dependencies>
152143
</plugin>
153144
<plugin>
154145
<artifactId>maven-scm-publish-plugin</artifactId>
@@ -230,7 +221,7 @@
230221
<configuration>
231222
<rules>
232223
<requireJavaVersion>
233-
<version>1.${java.target.version}</version>
224+
<version>21</version>
234225
</requireJavaVersion>
235226
<requireMavenVersion>
236227
<version>${maven.version}</version>
@@ -240,27 +231,6 @@
240231
</execution>
241232
</executions>
242233
</plugin>
243-
<!-- check with animal sniffer (http://www.mojohaus.org/animal-sniffer/), should only be used in JDKs prior version 9 -->
244-
<plugin>
245-
<groupId>org.codehaus.mojo</groupId>
246-
<artifactId>animal-sniffer-maven-plugin</artifactId>
247-
<configuration>
248-
<signature>
249-
<groupId>org.codehaus.mojo.signature</groupId>
250-
<artifactId>java1${java.target.version}</artifactId>
251-
<version>1.0</version>
252-
</signature>
253-
</configuration>
254-
<executions>
255-
<execution>
256-
<id>check-java-compatibility</id>
257-
<phase>process-classes</phase>
258-
<goals>
259-
<goal>check</goal>
260-
</goals>
261-
</execution>
262-
</executions>
263-
</plugin>
264234
<!-- always generate javadoc -->
265235
<plugin>
266236
<groupId>org.apache.maven.plugins</groupId>
@@ -380,7 +350,7 @@
380350
<plugin>
381351
<groupId>org.jacoco</groupId>
382352
<artifactId>jacoco-maven-plugin</artifactId>
383-
<version>0.8.8</version>
353+
<version>0.8.12</version>
384354
<executions>
385355
<execution>
386356
<id>prepare-jacoco-agent</id>

0 commit comments

Comments
 (0)