Skip to content

Commit 6bd5b20

Browse files
committed
Make generate-service-descriptor thread-safe again
SimpleDateFormat is not thread-safe which causes plugin to fail with the cryptic errors like `For input string: "E.404E2"`
1 parent 439d751 commit 6bd5b20

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

src/main/java/io/trino/maven/ServiceDescriptorGenerator.java

+19-11
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@
2828
import java.io.IOException;
2929
import java.net.URL;
3030
import java.net.URLClassLoader;
31-
import java.text.DateFormat;
32-
import java.text.ParseException;
33-
import java.text.SimpleDateFormat;
31+
import java.time.LocalDateTime;
32+
import java.time.OffsetDateTime;
33+
import java.time.ZoneOffset;
34+
import java.time.format.DateTimeParseException;
35+
import java.time.temporal.ChronoUnit;
3436
import java.util.ArrayList;
3537
import java.util.List;
3638
import java.util.jar.JarEntry;
@@ -49,7 +51,6 @@ public class ServiceDescriptorGenerator
4951
extends AbstractMojo
5052
{
5153
private static final String LS = System.lineSeparator();
52-
private static final DateFormat OUTPUT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
5354

5455
@Parameter(defaultValue = "io.trino.spi.Plugin")
5556
private String pluginClassName;
@@ -100,18 +101,12 @@ public void execute()
100101

101102
Class<?> pluginClass = pluginClasses.get(0);
102103
byte[] servicesFileData = (pluginClass.getName() + "\n").getBytes(UTF_8);
103-
104104
try (FileOutputStream out = new FileOutputStream(servicesJar);
105105
JarOutputStream jar = new JarOutputStream(out)) {
106106

107107
JarEntry jarEntry = new JarEntry("META-INF/services/" + pluginClassName);
108108
if (outputTimestamp != null && !outputTimestamp.isBlank()) {
109-
try {
110-
jarEntry.setTime(OUTPUT_DATE_FORMAT.parse(outputTimestamp).getTime());
111-
}
112-
catch (ParseException e) {
113-
throw new RuntimeException("Could not parse outputTimestamp: " + outputTimestamp, e);
114-
}
109+
jarEntry.setTimeLocal(parseOutputTimestamp(outputTimestamp));
115110
}
116111

117112
jar.putNextEntry(jarEntry);
@@ -168,6 +163,19 @@ private static void mkdirs(File file)
168163
}
169164
}
170165

166+
private static LocalDateTime parseOutputTimestamp(String outputTimestamp)
167+
{
168+
try {
169+
return OffsetDateTime.parse(outputTimestamp)
170+
.withOffsetSameInstant(ZoneOffset.UTC)
171+
.truncatedTo(ChronoUnit.SECONDS)
172+
.toLocalDateTime();
173+
}
174+
catch (DateTimeParseException e) {
175+
throw new IllegalArgumentException("Invalid project.build.outputTimestamp value '" + outputTimestamp + "'", e);
176+
}
177+
}
178+
171179
private static boolean isImplementation(Class<?> clazz, Class<?> pluginClass)
172180
{
173181
return pluginClass.isAssignableFrom(clazz) && !isAbstract(clazz.getModifiers()) && !isInterface(clazz.getModifiers());

0 commit comments

Comments
 (0)