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

Adapt plugin for Java 21 #258

Merged
merged 5 commits into from
Aug 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ buildPlugin(
useContainerAgent: true,
// Show failures on all configurations
failFast: false,
// Test Java 11 and Java 17
// Test Java 11, 17, and 21
configurations: [
[platform: 'linux', jdk: '17'], // Linux first for coverage report on ci.jenkins.io
[platform: 'linux', jdk: '21', jenkins: '2.414'],
[platform: 'windows', jdk: '11'],
]
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
import hudson.util.FormValidation;
import java.text.DateFormat;
import java.text.ParseException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.GlobalConfiguration;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
Expand All @@ -18,9 +26,27 @@
@Extension
@Symbol("scheduleBuild")
public class ScheduleBuildGlobalConfiguration extends GlobalConfiguration {
// defaultScheduleTime is a misuse of a Date object. Used for the
// time portion (hours, minutes, seconds, etc.) while the date
// portion is ignored.
private Date defaultScheduleTime;
private String timeZone;

private static final Logger LOGGER = Logger.getLogger(ScheduleBuildGlobalConfiguration.class.getName());

private static final LocalDate EPOCH = LocalDate.of(1970, 1, 1);
private static final ZoneId ZONE = ZoneId.systemDefault();
private static final DateTimeFormatter[] FORMATTERS = {
DateTimeFormatter.ofPattern("H:m:s a"), // Original format required by DateFormat
DateTimeFormatter.ofPattern("h:m:s a"),
DateTimeFormatter.ofPattern("H:m a"),
DateTimeFormatter.ofPattern("h:m a"),
DateTimeFormatter.ofPattern("H:m:s"),
DateTimeFormatter.ofPattern("h:m:s"),
DateTimeFormatter.ofPattern("H:m"),
DateTimeFormatter.ofPattern("h:m"),
};

@DataBoundConstructor
public ScheduleBuildGlobalConfiguration() {
this.defaultScheduleTime = new Date(0, 0, 0, 22, 0);
Expand All @@ -34,7 +60,29 @@ public String getDefaultScheduleTime() {

@DataBoundSetter
public void setDefaultScheduleTime(String defaultScheduleTime) throws ParseException {
this.defaultScheduleTime = getTimeFormat().parse(defaultScheduleTime);
try {
this.defaultScheduleTime = getTimeFormat().parse(defaultScheduleTime);
} catch (ParseException parseException) {
/* Try each of the formatters with the user provided data, return first success */
/* Java 21 changed DateFormat to not accept strings with only a time component */
/* DateTimeFormatter parsing allows Java 11, 17, and 21 to accept several time string formats */
for (DateTimeFormatter formatter : FORMATTERS) {
try {
LocalTime localTime = LocalTime.parse(defaultScheduleTime, formatter);
Instant instant = localTime.atDate(EPOCH).atZone(ZONE).toInstant();
this.defaultScheduleTime = Date.from(instant);
// LOGGER.log(Level.FINEST, "Parsed '" + defaultScheduleTime + "' with formatter " + formatter);
return;
} catch (DateTimeParseException dtex) {
LOGGER.log(
Level.FINE,
"Did not parse '" + defaultScheduleTime + "' with formatter " + formatter,
dtex);
}
}
/* Throw the original exception if no match is found */
throw parseException;
}
}

public String getTimeZone() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -89,7 +90,7 @@ public void testSchedule() throws Exception {

@Test
public void testGetDefaultDate() throws Exception {
assertThat(scheduleBuildAction.getDefaultDate(), endsWith(" 10:00:00 PM"));
assertThat(scheduleBuildAction.getDefaultDate(), matchesPattern(".* 10:00:00\\hPM"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.matchesPattern;
import static org.junit.Assert.assertThrows;

import java.time.ZoneId;
Expand Down Expand Up @@ -30,7 +31,7 @@ public void setUp() {
@Test
public void configRoundTripTestNoChanges() throws Exception {
assertThat(globalConfig, is(not(nullValue())));
assertThat(globalConfig.getDefaultScheduleTime(), is("10:00:00 PM"));
assertThat(globalConfig.getDefaultScheduleTime(), matchesPattern("10:00:00\\hPM"));
assertThat(globalConfig.getTimeZone(), is(TimeZone.getDefault().getID()));

// Submit the global configuration page with no changes
Expand All @@ -39,7 +40,7 @@ public void configRoundTripTestNoChanges() throws Exception {
ScheduleBuildGlobalConfiguration newGlobalConfig =
GlobalConfiguration.all().getInstance(ScheduleBuildGlobalConfiguration.class);
assertThat(newGlobalConfig, is(not(nullValue())));
assertThat(newGlobalConfig.getDefaultScheduleTime(), is("10:00:00 PM"));
assertThat(newGlobalConfig.getDefaultScheduleTime(), matchesPattern("10:00:00\\hPM"));
assertThat(newGlobalConfig.getTimeZone(), is(TimeZone.getDefault().getID()));
}

Expand All @@ -57,7 +58,25 @@ public void configRoundTripTestWithChanges() throws Exception {
ScheduleBuildGlobalConfiguration newGlobalConfig =
GlobalConfiguration.all().getInstance(ScheduleBuildGlobalConfiguration.class);
assertThat(newGlobalConfig, is(not(nullValue())));
assertThat(newGlobalConfig.getDefaultScheduleTime(), is(newScheduleTime));
assertThat(newGlobalConfig.getDefaultScheduleTime(), matchesPattern("1:23:45\\hPM"));
assertThat(newGlobalConfig.getTimeZone(), is(newTimeZone));
}

@Test
public void configRoundTripTestWithChangesSimpleTime() throws Exception {
// Adjust global configuration values
String newScheduleTime = "2:34";
String newTimeZone = "Europe/Rome";
globalConfig.setDefaultScheduleTime(newScheduleTime);
globalConfig.setTimeZone(newTimeZone);

// Submit the global configuration page, will not change adjusted values
j.configRoundtrip();

ScheduleBuildGlobalConfiguration newGlobalConfig =
GlobalConfiguration.all().getInstance(ScheduleBuildGlobalConfiguration.class);
assertThat(newGlobalConfig, is(not(nullValue())));
assertThat(newGlobalConfig.getDefaultScheduleTime(), matchesPattern("2:34:00\\hAM"));
assertThat(newGlobalConfig.getTimeZone(), is(newTimeZone));
}

Expand All @@ -79,14 +98,14 @@ public void testDoCheckTimeZone() throws Exception {

@Test
public void testGetDefaultScheduleTime() {
assertThat(globalConfig.getDefaultScheduleTime(), is("10:00:00 PM"));
assertThat(globalConfig.getDefaultScheduleTime(), matchesPattern("10:00:00\\hPM"));
}

@Test
public void testSetDefaultScheduleTime() throws Exception {
String defaultScheduleTime = "12:34:56 PM";
globalConfig.setDefaultScheduleTime(defaultScheduleTime);
assertThat(globalConfig.getDefaultScheduleTime(), is(defaultScheduleTime));
assertThat(globalConfig.getDefaultScheduleTime(), matchesPattern("12:34:56\\hPM"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
unclassified:
scheduleBuild:
defaultScheduleTime: "12:34:56 AM"
defaultScheduleTime: "12:34:56"
timeZone: "Europe/Rome"