diff --git a/api/maven-api-core/pom.xml b/api/maven-api-core/pom.xml index ae950fbb48..f713e2050f 100644 --- a/api/maven-api-core/pom.xml +++ b/api/maven-api-core/pom.xml @@ -59,6 +59,12 @@ org.apache.maven maven-api-di + + + org.junit.jupiter + junit-jupiter-api + test + diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java index dacf1ec6a2..a80fbd68f6 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java @@ -437,5 +437,13 @@ public final class Constants { @Config(type = "java.lang.Integer") public static final String MAVEN_DEPLOY_SNAPSHOT_BUILD_NUMBER = "maven.deploy.snapshot.buildNumber"; + /** + * User property used to store the build timestamp. + * + * @since 4.1.0 + */ + @Config(type = "java.time.Instant") + public static final String MAVEN_START_INSTANT = "maven.startInstant"; + private Constants() {} } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/MonotonicClock.java b/api/maven-api-core/src/main/java/org/apache/maven/api/MonotonicClock.java new file mode 100644 index 0000000000..5fa3de655c --- /dev/null +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/MonotonicClock.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.api; + +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; + +/** + * A Clock implementation that combines monotonic timing with wall-clock time. + *

+ * This class provides precise time measurements using {@link System#nanoTime()} + * while maintaining wall-clock time information in UTC. The wall-clock time + * is computed from the monotonic duration since system start to ensure consistency + * between time measurements. + *

+ * This implementation is singleton-based and always uses UTC timezone. The clock + * cannot be adjusted to different timezones to maintain consistent monotonic behavior. + * Users needing local time representation should convert the result of {@link #instant()} + * to their desired timezone: + *

{@code
+ * Instant now = MonotonicClock.now();
+ * ZonedDateTime local = now.atZone(ZoneId.systemDefault());
+ * }
+ * + * @see System#nanoTime() + * @see Clock + */ +public class MonotonicClock extends Clock { + private static final MonotonicClock CLOCK = new MonotonicClock(); + + private final long startNanos; + private final Instant startInstant; + + /** + * Private constructor to enforce singleton pattern. + * Initializes the clock with the current system time and nanoTime. + */ + private MonotonicClock() { + this.startNanos = System.nanoTime(); + this.startInstant = Clock.systemUTC().instant(); + } + + /** + * Returns the singleton instance of MonotonicClock. + * + * @return the monotonic clock instance + */ + public static MonotonicClock get() { + return CLOCK; + } + + /** + * Returns the current instant from the monotonic clock. + * This is a convenience method equivalent to {@code get().instant()}. + * + * @return the current instant using monotonic timing + */ + public static Instant now() { + return get().instant(); + } + + /** + * Returns a monotonically increasing instant. + *

+ * The returned instant is calculated by adding the elapsed nanoseconds + * since clock creation to the initial wall clock time. This ensures that + * the time never goes backwards and maintains a consistent relationship + * with the wall clock time. + * + * @return the current instant using monotonic timing + */ + @Override + public Instant instant() { + long elapsedNanos = System.nanoTime() - startNanos; + return startInstant.plusNanos(elapsedNanos); + } + + /** + * Returns the zone ID of this clock, which is always UTC. + * + * @return the UTC zone ID + */ + @Override + public ZoneId getZone() { + return ZoneOffset.UTC; + } + + /** + * Returns this clock since timezone adjustments are not supported. + *

+ * This implementation maintains UTC time to ensure monotonic behavior. + * The provided zone parameter is ignored. + * + * @param zone the target timezone (ignored) + * @return this clock instance + */ + @Override + public Clock withZone(ZoneId zone) { + // Monotonic clock is always UTC-based + return this; + } +} diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/ProtoSession.java b/api/maven-api-core/src/main/java/org/apache/maven/api/ProtoSession.java index 97ac59cb24..4b986da8d3 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/ProtoSession.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/ProtoSession.java @@ -106,7 +106,7 @@ public interface ProtoSession { * Returns new builder from scratch. */ static Builder newBuilder() { - return new Builder().withStartTime(Instant.now()); + return new Builder().withStartTime(MonotonicClock.now()); } class Builder { diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/event/ExecutionEventLogger.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/event/ExecutionEventLogger.java index 5c401ba7e0..791f81a15e 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/event/ExecutionEventLogger.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/event/ExecutionEventLogger.java @@ -20,9 +20,13 @@ package org.apache.maven.cling.event; import java.io.File; import java.nio.file.Path; +import java.time.Duration; +import java.time.Instant; +import java.time.ZoneId; import java.util.List; import java.util.Objects; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.api.services.MessageBuilder; import org.apache.maven.api.services.MessageBuilderFactory; import org.apache.maven.execution.AbstractExecutionListener; @@ -223,7 +227,7 @@ public class ExecutionEventLogger extends AbstractExecutionListener { } else if (buildSummary instanceof BuildSuccess) { buffer.append(builder().success("SUCCESS")); buffer.append(" ["); - String buildTimeDuration = formatDuration(buildSummary.getTime()); + String buildTimeDuration = formatDuration(buildSummary.getExecTime()); int padSize = MAX_PADDED_BUILD_TIME_DURATION_LENGTH - buildTimeDuration.length(); if (padSize > 0) { buffer.append(chars(' ', padSize)); @@ -233,7 +237,7 @@ public class ExecutionEventLogger extends AbstractExecutionListener { } else if (buildSummary instanceof BuildFailure) { buffer.append(builder().failure("FAILURE")); buffer.append(" ["); - String buildTimeDuration = formatDuration(buildSummary.getTime()); + String buildTimeDuration = formatDuration(buildSummary.getExecTime()); int padSize = MAX_PADDED_BUILD_TIME_DURATION_LENGTH - buildTimeDuration.length(); if (padSize > 0) { buffer.append(chars(' ', padSize)); @@ -266,15 +270,15 @@ public class ExecutionEventLogger extends AbstractExecutionListener { private void logStats(MavenSession session) { infoLine('-'); - long finish = System.currentTimeMillis(); + Instant finish = MonotonicClock.now(); - long time = finish - session.getRequest().getStartTime().getTime(); + Duration time = Duration.between(session.getRequest().getStartInstant(), finish); String wallClock = session.getRequest().getDegreeOfConcurrency() > 1 ? " (Wall Clock)" : ""; logger.info("Total time: {}{}", formatDuration(time), wallClock); - logger.info("Finished at: {}", formatTimestamp(finish)); + logger.info("Finished at: {}", formatTimestamp(finish.atZone(ZoneId.systemDefault()))); } @Override diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java index 667fc55623..6a6c2a9d27 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java @@ -22,7 +22,6 @@ import java.io.FileNotFoundException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -33,6 +32,7 @@ import java.util.regex.Pattern; import org.apache.maven.InternalErrorException; import org.apache.maven.Maven; import org.apache.maven.api.Constants; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.api.cli.InvokerRequest; import org.apache.maven.api.cli.Logger; import org.apache.maven.api.cli.mvn.MavenOptions; @@ -105,7 +105,7 @@ public abstract class MavenInvoker extends LookupInvoker mavenExecutionRequest.setIgnoreMissingArtifactDescriptor(true); mavenExecutionRequest.setRecursive(true); mavenExecutionRequest.setReactorFailureBehavior(MavenExecutionRequest.REACTOR_FAIL_FAST); - mavenExecutionRequest.setStartTime(new Date()); + mavenExecutionRequest.setStartInstant(MonotonicClock.now()); mavenExecutionRequest.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_INFO); mavenExecutionRequest.setDegreeOfConcurrency(1); mavenExecutionRequest.setBuilderId("singlethreaded"); diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/transfer/AbstractMavenTransferListener.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/transfer/AbstractMavenTransferListener.java index b07abab37e..4cba621f55 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/transfer/AbstractMavenTransferListener.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/transfer/AbstractMavenTransferListener.java @@ -19,7 +19,10 @@ package org.apache.maven.cling.transfer; import java.io.PrintWriter; +import java.time.Duration; +import java.time.Instant; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.api.services.MessageBuilder; import org.apache.maven.api.services.MessageBuilderFactory; import org.eclipse.aether.transfer.AbstractTransferListener; @@ -80,11 +83,12 @@ public abstract class AbstractMavenTransferListener extends AbstractTransferList message.resetStyle().append(resource.getResourceName()); message.style(STYLE).append(" (").append(format.format(contentLength)); - long duration = System.currentTimeMillis() - resource.getTransferStartTime(); - if (duration > 0L) { - double bytesPerSecond = contentLength / (duration / 1000.0); + Duration duration = + Duration.between(Instant.ofEpochMilli(resource.getTransferStartTime()), MonotonicClock.now()); + if ((duration.getSeconds() | duration.getNano()) > 0) { // duration.isPositive() + long bytesPerSecond = Math.round(contentLength / (double) duration.toSeconds()); message.append(" at "); - format.format(message, (long) bytesPerSecond); + format.format(message, bytesPerSecond); message.append("/s"); } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/transfer/Slf4jMavenTransferListener.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/transfer/Slf4jMavenTransferListener.java index b5ab1b6574..7db7403e91 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/transfer/Slf4jMavenTransferListener.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/transfer/Slf4jMavenTransferListener.java @@ -18,6 +18,10 @@ */ package org.apache.maven.cling.transfer; +import java.time.Duration; +import java.time.Instant; + +import org.apache.maven.api.MonotonicClock; import org.eclipse.aether.transfer.AbstractTransferListener; import org.eclipse.aether.transfer.TransferCancelledException; import org.eclipse.aether.transfer.TransferEvent; @@ -83,11 +87,12 @@ public class Slf4jMavenTransferListener extends AbstractTransferListener { .append(" ("); format.format(message, contentLength); - long duration = System.currentTimeMillis() - resource.getTransferStartTime(); - if (duration > 0L) { - double bytesPerSecond = contentLength / (duration / 1000.0); + Duration duration = + Duration.between(Instant.ofEpochMilli(resource.getTransferStartTime()), MonotonicClock.now()); + if ((duration.getSeconds() | duration.getNano()) > 0) { // duration.isPositive() + long bytesPerSecond = Math.round(contentLength / (double) duration.toSeconds()); message.append(" at "); - format.format(message, (long) bytesPerSecond); + format.format(message, bytesPerSecond); message.append("/s"); } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/utils/CLIReportingUtils.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/utils/CLIReportingUtils.java index d18f0a7c18..3af1415497 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/utils/CLIReportingUtils.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/utils/CLIReportingUtils.java @@ -20,8 +20,9 @@ package org.apache.maven.cling.utils; import java.io.IOException; import java.io.InputStream; -import java.text.SimpleDateFormat; -import java.util.Date; +import java.time.Duration; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAccessor; import java.util.Locale; import java.util.Properties; @@ -105,23 +106,13 @@ public final class CLIReportingUtils { * @return Readable build info */ public static String createMavenVersionString(Properties buildProperties) { - String timestamp = reduce(buildProperties.getProperty("timestamp")); String version = reduce(buildProperties.getProperty(BUILD_VERSION_PROPERTY)); String rev = reduce(buildProperties.getProperty("buildNumber")); String distributionName = reduce(buildProperties.getProperty("distributionName")); - String msg = distributionName + " "; - msg += (version != null ? version : ""); - if (rev != null || timestamp != null) { - msg += " ("; - msg += (rev != null ? rev : ""); - if (timestamp != null && !timestamp.isEmpty()) { - String ts = formatTimestamp(Long.parseLong(timestamp)); - msg += (rev != null ? "; " : "") + ts; - } - msg += ")"; - } - return msg; + return distributionName + " " + + (version != null ? version : "") + + (rev != null ? " (" + rev + ")" : ""); } private static String reduce(String s) { @@ -169,35 +160,25 @@ public final class CLIReportingUtils { } } - public static String formatTimestamp(long timestamp) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); - return sdf.format(new Date(timestamp)); + public static String formatTimestamp(TemporalAccessor instant) { + return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(instant); } - public static String formatDuration(long duration) { - // CHECKSTYLE_OFF: MagicNumber - long ms = duration % 1000; - long s = (duration / ONE_SECOND) % 60; - long m = (duration / ONE_MINUTE) % 60; - long h = (duration / ONE_HOUR) % 24; - long d = duration / ONE_DAY; - // CHECKSTYLE_ON: MagicNumber + public static String formatDuration(Duration duration) { + long days = duration.toDays(); + long hours = duration.toHoursPart(); + long minutes = duration.toMinutesPart(); + long seconds = duration.toSecondsPart(); + long millis = duration.toMillisPart(); - String format; - if (d > 0) { - // Length 11+ chars - format = "%d d %02d:%02d h"; - } else if (h > 0) { - // Length 7 chars - format = "%2$02d:%3$02d h"; - } else if (m > 0) { - // Length 9 chars - format = "%3$02d:%4$02d min"; + if (days > 0) { + return String.format("%d d %02d:%02d h", days, hours, minutes); + } else if (hours > 0) { + return String.format("%02d:%02d h", hours, minutes); + } else if (minutes > 0) { + return String.format("%02d:%02d min", minutes, seconds); } else { - // Length 7-8 chars - format = "%4$d.%5$03d s"; + return String.format("%d.%03d s", seconds, millis); } - - return String.format(format, d, h, m, s, ms); } } diff --git a/impl/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/impl/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index 0c24c22c02..41d87dd85e 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/impl/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -28,7 +28,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -39,6 +38,7 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Stream; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.api.Session; import org.apache.maven.api.model.Model; import org.apache.maven.api.model.Prerequisites; @@ -194,7 +194,7 @@ public class DefaultMaven implements Maven { // @SuppressWarnings("checkstyle:methodlength") private MavenExecutionResult doExecute(MavenExecutionRequest request) { - request.setStartTime(new Date()); + request.setStartInstant(MonotonicClock.now()); MavenExecutionResult result = new DefaultMavenExecutionResult(); diff --git a/impl/maven-core/src/main/java/org/apache/maven/execution/BuildFailure.java b/impl/maven-core/src/main/java/org/apache/maven/execution/BuildFailure.java index 2c43f1e943..dcde525f58 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/execution/BuildFailure.java +++ b/impl/maven-core/src/main/java/org/apache/maven/execution/BuildFailure.java @@ -18,6 +18,8 @@ */ package org.apache.maven.execution; +import java.time.Duration; + import org.apache.maven.project.MavenProject; /** @@ -39,6 +41,17 @@ public class BuildFailure extends BuildSummary { * @param cause The cause of the build failure, may be {@code null}. */ public BuildFailure(MavenProject project, long time, Throwable cause) { + this(project, Duration.ofMillis(time), cause); + } + + /** + * Creates a new build summary for the specified project. + * + * @param project The project being summarized, must not be {@code null}. + * @param time The build time of the project in milliseconds. + * @param cause The cause of the build failure, may be {@code null}. + */ + public BuildFailure(MavenProject project, Duration time, Throwable cause) { this(project, time, time, cause); } @@ -50,7 +63,7 @@ public class BuildFailure extends BuildSummary { * @param wallTime The wall time of the project in milliseconds. * @param cause The cause of the build failure, may be {@code null}. */ - public BuildFailure(MavenProject project, long execTime, long wallTime, Throwable cause) { + public BuildFailure(MavenProject project, Duration execTime, Duration wallTime, Throwable cause) { super(project, execTime, wallTime); this.cause = cause; } diff --git a/impl/maven-core/src/main/java/org/apache/maven/execution/BuildSuccess.java b/impl/maven-core/src/main/java/org/apache/maven/execution/BuildSuccess.java index a2a4546b23..34dc8dbdd3 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/execution/BuildSuccess.java +++ b/impl/maven-core/src/main/java/org/apache/maven/execution/BuildSuccess.java @@ -18,6 +18,8 @@ */ package org.apache.maven.execution; +import java.time.Duration; + import org.apache.maven.project.MavenProject; /** @@ -33,7 +35,17 @@ public class BuildSuccess extends BuildSummary { * @param time The build time of the project in milliseconds. */ public BuildSuccess(MavenProject project, long time) { - super(project, time, time); + this(project, Duration.ofMillis(time)); + } + + /** + * Creates a new build summary for the specified project. + * + * @param project The project being summarized, must not be {@code null}. + * @param time The build time of the project in milliseconds. + */ + public BuildSuccess(MavenProject project, Duration time) { + this(project, time, time); } /** @@ -43,7 +55,7 @@ public class BuildSuccess extends BuildSummary { * @param wallTime The wall time of the project in milliseconds. * @param execTime The exec time of the project in milliseconds. */ - public BuildSuccess(MavenProject project, long wallTime, long execTime) { + public BuildSuccess(MavenProject project, Duration wallTime, Duration execTime) { super(project, wallTime, execTime); } } diff --git a/impl/maven-core/src/main/java/org/apache/maven/execution/BuildSummary.java b/impl/maven-core/src/main/java/org/apache/maven/execution/BuildSummary.java index efc0da1d8b..0f6c37bedc 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/execution/BuildSummary.java +++ b/impl/maven-core/src/main/java/org/apache/maven/execution/BuildSummary.java @@ -18,6 +18,7 @@ */ package org.apache.maven.execution; +import java.time.Duration; import java.util.Objects; import org.apache.maven.project.MavenProject; @@ -36,12 +37,12 @@ public abstract class BuildSummary { /** * The build time of the project in milliseconds. */ - private final long wallTime; + private final Duration wallTime; /** * The total amount of time spent for to run mojos in milliseconds. */ - private final long execTime; + private final Duration execTime; /** * Creates a new build summary for the specified project. @@ -50,7 +51,7 @@ public abstract class BuildSummary { * @param time The build time of the project in milliseconds. */ protected BuildSummary(MavenProject project, long time) { - this(project, time, time); + this(project, Duration.ofMillis(time), Duration.ofMillis(time)); } /** @@ -60,7 +61,7 @@ public abstract class BuildSummary { * @param execTime The exec time of the project in milliseconds. * @param wallTime The wall time of the project in milliseconds. */ - protected BuildSummary(MavenProject project, long execTime, long wallTime) { + protected BuildSummary(MavenProject project, Duration execTime, Duration wallTime) { this.project = Objects.requireNonNull(project, "project cannot be null"); // TODO Validate for < 0? this.execTime = execTime; @@ -82,15 +83,24 @@ public abstract class BuildSummary { * @return The wall time of the project in milliseconds. */ public long getTime() { - return execTime; + return execTime.toMillis(); } /** - * Gets the exec time of the project in milliseconds. + * Gets the wall time of the project. * - * @return The exec time of the project in milliseconds. + * @return The wall time of the project. */ - public long getWallTime() { + public Duration getWallTime() { return wallTime; } + + /** + * Gets the exec time of the project. + * + * @return The exec time of the project. + */ + public Duration getExecTime() { + return execTime; + } } diff --git a/impl/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java b/impl/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java index aa9748ca51..eedfe23016 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java +++ b/impl/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java @@ -20,6 +20,7 @@ package org.apache.maven.execution; import java.io.File; import java.nio.file.Path; +import java.time.Instant; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -28,6 +29,7 @@ import java.util.Map; import java.util.Objects; import java.util.Properties; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.eventspy.internal.EventSpyDispatcher; import org.apache.maven.model.Profile; @@ -135,7 +137,7 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest { private Properties userProperties; - private Date startTime = new Date(); + private Instant startTime = MonotonicClock.now(); private boolean showErrors = false; @@ -214,7 +216,7 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest { copy.setExecutionListener(original.getExecutionListener()); copy.setUseLegacyLocalRepository(original.isUseLegacyLocalRepository()); copy.setBuilderId(original.getBuilderId()); - copy.setStartTime(original.getStartTime()); + copy.setStartInstant(original.getStartInstant()); return copy; } @@ -299,10 +301,22 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest { } @Override + @Deprecated public Date getStartTime() { + return new Date(startTime.toEpochMilli()); + } + + @Override + public Instant getStartInstant() { return startTime; } + @Override + public MavenExecutionRequest setStartInstant(Instant startTime) { + this.startTime = startTime; + return this; + } + @Override public boolean isShowErrors() { return showErrors; @@ -423,9 +437,10 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest { return this; } + @Deprecated @Override public MavenExecutionRequest setStartTime(Date startTime) { - this.startTime = startTime; + this.startTime = Instant.ofEpochMilli(startTime.getTime()); return this; } @@ -981,7 +996,7 @@ public class DefaultMavenExecutionRequest implements MavenExecutionRequest { projectBuildingRequest.setInactiveProfileIds(getInactiveProfiles()); projectBuildingRequest.setProfiles(getProfiles()); projectBuildingRequest.setProcessPlugins(true); - projectBuildingRequest.setBuildStartTime(getStartTime()); + projectBuildingRequest.setBuildStartInstant(getStartInstant()); } return projectBuildingRequest; diff --git a/impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java b/impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java index f95f48b26c..baf0080177 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java +++ b/impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java @@ -20,6 +20,7 @@ package org.apache.maven.execution; import java.io.File; import java.nio.file.Path; +import java.time.Instant; import java.util.Date; import java.util.List; import java.util.Map; @@ -105,10 +106,16 @@ public interface MavenExecutionRequest { String getBaseDirectory(); // Timing (remove this) + @Deprecated MavenExecutionRequest setStartTime(Date start); + @Deprecated Date getStartTime(); + MavenExecutionRequest setStartInstant(Instant start); + + Instant getStartInstant(); + // Goals MavenExecutionRequest setGoals(List goals); diff --git a/impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java b/impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java index 5d118ff7dd..8fa6e4098a 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java +++ b/impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java @@ -20,6 +20,7 @@ package org.apache.maven.execution; import java.io.File; import java.nio.file.Path; +import java.time.Instant; import java.util.Arrays; import java.util.Date; import java.util.List; @@ -245,10 +246,15 @@ public class MavenSession implements Cloneable { } } + @Deprecated public Date getStartTime() { return request.getStartTime(); } + public Instant getStartInstant() { + return request.getStartInstant(); + } + public boolean isParallel() { return parallel; } diff --git a/impl/maven-core/src/main/java/org/apache/maven/execution/ReactorManager.java b/impl/maven-core/src/main/java/org/apache/maven/execution/ReactorManager.java index 2ac0643135..bc02255c4f 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/execution/ReactorManager.java +++ b/impl/maven-core/src/main/java/org/apache/maven/execution/ReactorManager.java @@ -18,6 +18,7 @@ */ package org.apache.maven.execution; +import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -123,6 +124,10 @@ public class ReactorManager { buildFailuresByProject.put(getProjectKey(project), new BuildFailure(project, time, error)); } + public void registerBuildFailure(MavenProject project, Exception error, String task, Duration time) { + buildFailuresByProject.put(getProjectKey(project), new BuildFailure(project, time, error)); + } + public boolean hasBuildFailures() { return !buildFailuresByProject.isEmpty(); } @@ -147,6 +152,10 @@ public class ReactorManager { buildSuccessesByProject.put(getProjectKey(project), new BuildSuccess(project, time)); } + public void registerBuildSuccess(MavenProject project, Duration time) { + buildSuccessesByProject.put(getProjectKey(project), new BuildSuccess(project, time)); + } + public BuildFailure getBuildFailure(MavenProject project) { return buildFailuresByProject.get(getProjectKey(project)); } diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/impl/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 235b68d222..371c345f3d 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -168,6 +168,7 @@ public class DefaultRepositorySystemSessionFactory implements RepositorySystemSe configProps.put(ConfigurationProperties.USER_AGENT, getUserAgent()); configProps.put(ConfigurationProperties.INTERACTIVE, request.isInteractiveMode()); configProps.put("maven.startTime", request.getStartTime()); + configProps.put(Constants.MAVEN_START_INSTANT, request.getStartInstant()); sessionBuilder.setOffline(request.isOffline()); sessionBuilder.setChecksumPolicy(request.getGlobalChecksumPolicy()); diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java index a931b9874b..27c30927f0 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java @@ -146,7 +146,7 @@ public class DefaultSession extends AbstractSession implements InternalMavenSess @Nonnull @Override public Instant getStartTime() { - return getMavenSession().getRequest().getStartTime().toInstant(); + return getMavenSession().getRequest().getStartInstant(); } @Override diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java index 5450e16ea5..0994baf006 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java +++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java @@ -22,9 +22,12 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import java.time.Duration; +import java.time.Instant; import java.util.HashSet; import java.util.List; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.execution.BuildSuccess; import org.apache.maven.execution.ExecutionEvent; import org.apache.maven.execution.MavenSession; @@ -81,7 +84,7 @@ public class LifecycleModuleBuilder { TaskSegment taskSegment) { session.setCurrentProject(currentProject); - long buildStartTime = System.currentTimeMillis(); + Instant buildStartTime = MonotonicClock.now(); try { @@ -106,12 +109,14 @@ public class LifecycleModuleBuilder { new ProjectExecutionEvent(session, currentProject, mojoExecutions)); mojoExecutor.execute(session, mojoExecutions); - long buildEndTime = System.currentTimeMillis(); + Instant buildEndTime = MonotonicClock.now(); projectExecutionListener.afterProjectExecutionSuccess( new ProjectExecutionEvent(session, currentProject, mojoExecutions)); - reactorContext.getResult().addBuildSummary(new BuildSuccess(currentProject, buildEndTime - buildStartTime)); + reactorContext + .getResult() + .addBuildSummary(new BuildSuccess(currentProject, Duration.between(buildStartTime, buildEndTime))); eventCatapult.fire(ExecutionEvent.Type.ProjectSucceeded, session, null); } catch (Throwable t) { diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java index e1c2b5b195..b683a06cdb 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java +++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java @@ -22,9 +22,12 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import java.time.Duration; +import java.time.Instant; import java.util.List; import java.util.Set; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.artifact.Artifact; import org.apache.maven.execution.BuildFailure; import org.apache.maven.execution.ExecutionEvent; @@ -164,11 +167,13 @@ public class BuilderCommon { final MavenSession currentSession, final MavenProject mavenProject, Throwable t, - final long buildStartTime) { + final Instant buildStartTime) { // record the error and mark the project as failed - long buildEndTime = System.currentTimeMillis(); + Instant buildEndTime = MonotonicClock.now(); buildContext.getResult().addException(t); - buildContext.getResult().addBuildSummary(new BuildFailure(mavenProject, buildEndTime - buildStartTime, t)); + buildContext + .getResult() + .addBuildSummary(new BuildFailure(mavenProject, Duration.between(buildStartTime, buildEndTime), t)); // notify listeners about "soft" project build failures only if (t instanceof Exception && !(t instanceof RuntimeException)) { diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java index 3134ac94e7..ccc16724a1 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java +++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java @@ -23,6 +23,8 @@ import javax.inject.Named; import javax.xml.stream.XMLStreamException; import java.io.IOException; +import java.time.Duration; +import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -34,13 +36,13 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.maven.api.Lifecycle; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.api.services.LifecycleRegistry; import org.apache.maven.api.services.MavenException; import org.apache.maven.api.xml.XmlNode; @@ -905,31 +907,31 @@ public class BuildPlanExecutor { } protected static class Clock { - long start; - long end; - long resumed; - long exec; + Instant start; + Instant end; + Instant resumed; + Duration exec = Duration.ZERO; protected void start() { - if (start == 0) { - start = System.nanoTime(); + if (start == null) { + start = MonotonicClock.now(); resumed = start; } else { - resumed = System.nanoTime(); + resumed = MonotonicClock.now(); } } protected void stop() { - end = System.nanoTime(); - exec += end - resumed; + end = MonotonicClock.now(); + exec = exec.plus(Duration.between(resumed, end)); } - protected long wallTime() { - return TimeUnit.NANOSECONDS.toMillis(end - start); + protected Duration wallTime() { + return Duration.between(start, end); } - protected long execTime() { - return TimeUnit.NANOSECONDS.toMillis(exec); + protected Duration execTime() { + return exec; } } } diff --git a/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java b/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java index 8f18435478..dbf6611b0f 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java +++ b/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java @@ -18,6 +18,7 @@ */ package org.apache.maven.project; +import java.time.Instant; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -59,7 +60,7 @@ public class DefaultProjectBuildingRequest implements ProjectBuildingRequest { private Properties userProperties; - private Date buildStartTime; + private Instant buildStartTime; private boolean resolveDependencies; @@ -261,11 +262,21 @@ public class DefaultProjectBuildingRequest implements ProjectBuildingRequest { return profiles; } + @Deprecated public Date getBuildStartTime() { - return buildStartTime; + return buildStartTime != null ? new Date(buildStartTime.toEpochMilli()) : null; } + @Deprecated public void setBuildStartTime(Date buildStartTime) { + setBuildStartInstant(buildStartTime != null ? Instant.ofEpochMilli(buildStartTime.getTime()) : null); + } + + public Instant getBuildStartInstant() { + return this.buildStartTime; + } + + public void setBuildStartInstant(Instant buildStartTime) { this.buildStartTime = buildStartTime; } diff --git a/impl/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java b/impl/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java index 7d3cae86af..c2f8fb3bf3 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java +++ b/impl/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java @@ -18,6 +18,7 @@ */ package org.apache.maven.project; +import java.time.Instant; import java.util.Date; import java.util.List; import java.util.Properties; @@ -138,6 +139,7 @@ public interface ProjectBuildingRequest { * * @return The start time of the build or {@code null} if unknown. */ + @Deprecated Date getBuildStartTime(); /** @@ -145,8 +147,23 @@ public interface ProjectBuildingRequest { * * @param buildStartTime The start time of the build, may be {@code null}. */ + @Deprecated void setBuildStartTime(Date buildStartTime); + /** + * Gets the start time of the build. + * + * @return The start time of the build or {@code null} if unknown. + */ + Instant getBuildStartInstant(); + + /** + * Sets the start time of the build. + * + * @param buildStartInstant The start time of the build, may be {@code null}. + */ + void setBuildStartInstant(Instant buildStartInstant); + RepositorySystemSession getRepositorySession(); ProjectBuildingRequest setRepositorySession(RepositorySystemSession repositorySession); diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/MavenBuildTimestamp.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/MavenBuildTimestamp.java index 3ee89cedd8..412a8b53a9 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/MavenBuildTimestamp.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/model/MavenBuildTimestamp.java @@ -18,15 +18,14 @@ */ package org.apache.maven.internal.impl.model; -import java.text.SimpleDateFormat; import java.time.Instant; -import java.util.Date; -import java.util.GregorianCalendar; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Map; import java.util.Properties; -import java.util.TimeZone; import org.apache.maven.api.Constants; +import org.apache.maven.api.MonotonicClock; /** * MavenBuildTimestamp @@ -35,12 +34,10 @@ public class MavenBuildTimestamp { // ISO 8601-compliant timestamp for machine readability public static final String DEFAULT_BUILD_TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX"; - public static final TimeZone DEFAULT_BUILD_TIME_ZONE = TimeZone.getTimeZone("Etc/UTC"); - private final String formattedTimestamp; public MavenBuildTimestamp() { - this(Instant.now()); + this(MonotonicClock.now()); } public MavenBuildTimestamp(Instant time) { @@ -66,12 +63,11 @@ public class MavenBuildTimestamp { timestampFormat = DEFAULT_BUILD_TIMESTAMP_FORMAT; } if (time == null) { - time = Instant.now(); + time = MonotonicClock.now(); } - SimpleDateFormat dateFormat = new SimpleDateFormat(timestampFormat); - dateFormat.setCalendar(new GregorianCalendar()); - dateFormat.setTimeZone(DEFAULT_BUILD_TIME_ZONE); - formattedTimestamp = dateFormat.format(new Date(time.toEpochMilli())); + DateTimeFormatter formatter = + DateTimeFormatter.ofPattern(timestampFormat).withZone(ZoneId.of("UTC")); + formattedTimestamp = formatter.format(time); } public String formattedTimestamp() { diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/LocalSnapshotMetadata.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/LocalSnapshotMetadata.java index 511a2246b4..51e71f9f65 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/LocalSnapshotMetadata.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/LocalSnapshotMetadata.java @@ -20,9 +20,9 @@ package org.apache.maven.internal.impl.resolver; import java.io.File; import java.nio.file.Path; +import java.time.Instant; import java.util.ArrayList; import java.util.Collection; -import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; @@ -39,11 +39,11 @@ final class LocalSnapshotMetadata extends MavenMetadata { private final Collection artifacts = new ArrayList<>(); - LocalSnapshotMetadata(Artifact artifact, Date timestamp) { + LocalSnapshotMetadata(Artifact artifact, Instant timestamp) { super(createMetadata(artifact), (Path) null, timestamp); } - LocalSnapshotMetadata(Metadata metadata, Path path, Date timestamp) { + LocalSnapshotMetadata(Metadata metadata, Path path, Instant timestamp) { super(metadata, path, timestamp); } diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/LocalSnapshotMetadataGenerator.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/LocalSnapshotMetadataGenerator.java index e122812e2e..9d8eca5133 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/LocalSnapshotMetadataGenerator.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/LocalSnapshotMetadataGenerator.java @@ -18,12 +18,14 @@ */ package org.apache.maven.internal.impl.resolver; +import java.time.Instant; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; +import org.apache.maven.api.Constants; +import org.apache.maven.api.MonotonicClock; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.impl.MetadataGenerator; @@ -40,10 +42,10 @@ class LocalSnapshotMetadataGenerator implements MetadataGenerator { private final Map snapshots; - private final Date timestamp; + private final Instant timestamp; LocalSnapshotMetadataGenerator(RepositorySystemSession session, InstallRequest request) { - timestamp = (Date) ConfigUtils.getObject(session, new Date(), "maven.startTime"); + timestamp = (Instant) ConfigUtils.getObject(session, MonotonicClock.now(), Constants.MAVEN_START_INSTANT); snapshots = new LinkedHashMap<>(); } diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/MavenMetadata.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/MavenMetadata.java index 0d8e653119..16e653e418 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/MavenMetadata.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/MavenMetadata.java @@ -26,12 +26,11 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.text.DateFormat; -import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; import java.util.Collections; -import java.util.Date; import java.util.Map; -import java.util.TimeZone; import org.apache.maven.api.metadata.Metadata; import org.apache.maven.metadata.v4.MetadataStaxReader; @@ -46,28 +45,26 @@ abstract class MavenMetadata extends AbstractMetadata implements MergeableMetada static final String MAVEN_METADATA_XML = "maven-metadata.xml"; - static DateFormat fmt; + static DateTimeFormatter fmt; static { - TimeZone timezone = TimeZone.getTimeZone("UTC"); - fmt = new SimpleDateFormat("yyyyMMddHHmmss"); - fmt.setTimeZone(timezone); + fmt = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneOffset.UTC); } protected Metadata metadata; private final Path path; - protected final Date timestamp; + protected final Instant timestamp; private boolean merged; @Deprecated - protected MavenMetadata(Metadata metadata, File file, Date timestamp) { + protected MavenMetadata(Metadata metadata, File file, Instant timestamp) { this(metadata, file != null ? file.toPath() : null, timestamp); } - protected MavenMetadata(Metadata metadata, Path path, Date timestamp) { + protected MavenMetadata(Metadata metadata, Path path, Instant timestamp) { this.metadata = metadata; this.path = path; this.timestamp = timestamp; diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/MavenSnapshotMetadata.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/MavenSnapshotMetadata.java index 4aa0ba526c..13c3b163da 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/MavenSnapshotMetadata.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/MavenSnapshotMetadata.java @@ -19,9 +19,9 @@ package org.apache.maven.internal.impl.resolver; import java.nio.file.Path; +import java.time.Instant; import java.util.ArrayList; import java.util.Collection; -import java.util.Date; import org.apache.maven.api.metadata.Metadata; import org.eclipse.aether.artifact.Artifact; @@ -33,7 +33,7 @@ abstract class MavenSnapshotMetadata extends MavenMetadata { protected final Collection artifacts = new ArrayList<>(); - protected MavenSnapshotMetadata(Metadata metadata, Path path, Date timestamp) { + protected MavenSnapshotMetadata(Metadata metadata, Path path, Instant timestamp) { super(metadata, path, timestamp); } diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/PluginsMetadata.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/PluginsMetadata.java index 260c0c4db2..a019d26390 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/PluginsMetadata.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/PluginsMetadata.java @@ -20,7 +20,7 @@ package org.apache.maven.internal.impl.resolver; import java.io.File; import java.nio.file.Path; -import java.util.Date; +import java.time.Instant; import java.util.LinkedHashMap; import java.util.List; @@ -56,12 +56,12 @@ final class PluginsMetadata extends MavenMetadata { private final PluginInfo pluginInfo; - PluginsMetadata(PluginInfo pluginInfo, Date timestamp) { + PluginsMetadata(PluginInfo pluginInfo, Instant timestamp) { super(createRepositoryMetadata(pluginInfo), (Path) null, timestamp); this.pluginInfo = pluginInfo; } - PluginsMetadata(PluginInfo pluginInfo, Path path, Date timestamp) { + PluginsMetadata(PluginInfo pluginInfo, Path path, Instant timestamp) { super(createRepositoryMetadata(pluginInfo), path, timestamp); this.pluginInfo = pluginInfo; } diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/PluginsMetadataGenerator.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/PluginsMetadataGenerator.java index bdc4bf62b2..c309ab6943 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/PluginsMetadataGenerator.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/PluginsMetadataGenerator.java @@ -21,9 +21,9 @@ package org.apache.maven.internal.impl.resolver; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.time.Instant; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; @@ -31,6 +31,8 @@ import java.util.Objects; import java.util.jar.JarFile; import java.util.zip.ZipEntry; +import org.apache.maven.api.Constants; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.api.xml.XmlNode; import org.apache.maven.internal.impl.resolver.PluginsMetadata.PluginInfo; import org.apache.maven.internal.xml.XmlNodeStaxBuilder; @@ -56,7 +58,7 @@ class PluginsMetadataGenerator implements MetadataGenerator { private final Map processedPlugins; - private final Date timestamp; + private final Instant timestamp; PluginsMetadataGenerator(RepositorySystemSession session, InstallRequest request) { this(session, request.getMetadata()); @@ -68,7 +70,7 @@ class PluginsMetadataGenerator implements MetadataGenerator { private PluginsMetadataGenerator(RepositorySystemSession session, Collection metadatas) { this.processedPlugins = new LinkedHashMap<>(); - this.timestamp = (Date) ConfigUtils.getObject(session, new Date(), "maven.startTime"); + this.timestamp = (Instant) ConfigUtils.getObject(session, MonotonicClock.now(), Constants.MAVEN_START_INSTANT); /* * NOTE: This should be considered a quirk to support interop with Maven's legacy ArtifactDeployer which diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RemoteSnapshotMetadata.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RemoteSnapshotMetadata.java index 2365cb2482..7eb841a06a 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RemoteSnapshotMetadata.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RemoteSnapshotMetadata.java @@ -20,14 +20,12 @@ package org.apache.maven.internal.impl.resolver; import java.io.File; import java.nio.file.Path; -import java.text.DateFormat; -import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Date; -import java.util.GregorianCalendar; import java.util.LinkedHashMap; import java.util.Map; -import java.util.TimeZone; import org.apache.maven.api.metadata.Metadata; import org.apache.maven.api.metadata.Snapshot; @@ -41,18 +39,16 @@ import org.eclipse.aether.artifact.Artifact; final class RemoteSnapshotMetadata extends MavenSnapshotMetadata { public static final String DEFAULT_SNAPSHOT_TIMESTAMP_FORMAT = "yyyyMMdd.HHmmss"; - public static final TimeZone DEFAULT_SNAPSHOT_TIME_ZONE = TimeZone.getTimeZone("Etc/UTC"); - private final Map versions = new LinkedHashMap<>(); private final Integer buildNumber; - RemoteSnapshotMetadata(Artifact artifact, Date timestamp, Integer buildNumber) { + RemoteSnapshotMetadata(Artifact artifact, Instant timestamp, Integer buildNumber) { super(createRepositoryMetadata(artifact), null, timestamp); this.buildNumber = buildNumber; } - private RemoteSnapshotMetadata(Metadata metadata, Path path, Date timestamp, Integer buildNumber) { + private RemoteSnapshotMetadata(Metadata metadata, Path path, Instant timestamp, Integer buildNumber) { super(metadata, path, timestamp); this.buildNumber = buildNumber; } @@ -79,13 +75,11 @@ final class RemoteSnapshotMetadata extends MavenSnapshotMetadata { String lastUpdated; if (metadata.getVersioning() == null) { - DateFormat utcDateFormatter = new SimpleDateFormat(DEFAULT_SNAPSHOT_TIMESTAMP_FORMAT); - utcDateFormatter.setCalendar(new GregorianCalendar()); - utcDateFormatter.setTimeZone(DEFAULT_SNAPSHOT_TIME_ZONE); + DateTimeFormatter utcDateFormatter = DateTimeFormatter.ofPattern(DEFAULT_SNAPSHOT_TIMESTAMP_FORMAT); snapshot = Snapshot.newBuilder() .buildNumber(buildNumber != null ? buildNumber : getBuildNumber(recessive) + 1) - .timestamp(utcDateFormatter.format(this.timestamp)) + .timestamp(utcDateFormatter.format(this.timestamp.atZone(ZoneOffset.UTC))) .build(); lastUpdated = fmt.format(timestamp); diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RemoteSnapshotMetadataGenerator.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RemoteSnapshotMetadataGenerator.java index 102e67eaf3..c2e81b941b 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RemoteSnapshotMetadataGenerator.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/RemoteSnapshotMetadataGenerator.java @@ -18,13 +18,14 @@ */ package org.apache.maven.internal.impl.resolver; +import java.time.Instant; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; import org.apache.maven.api.Constants; +import org.apache.maven.api.MonotonicClock; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.deployment.DeployRequest; @@ -41,12 +42,12 @@ class RemoteSnapshotMetadataGenerator implements MetadataGenerator { private final Map snapshots; - private final Date timestamp; + private final Instant timestamp; private final Integer buildNumber; RemoteSnapshotMetadataGenerator(RepositorySystemSession session, DeployRequest request) { - timestamp = (Date) ConfigUtils.getObject(session, new Date(), "maven.startTime"); + timestamp = (Instant) ConfigUtils.getObject(session, MonotonicClock.now(), Constants.MAVEN_START_INSTANT); Object bn = ConfigUtils.getObject(session, null, Constants.MAVEN_DEPLOY_SNAPSHOT_BUILD_NUMBER); if (bn instanceof Integer) { this.buildNumber = (Integer) bn; diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/VersionsMetadata.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/VersionsMetadata.java index 219550e0ba..b55342dca6 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/VersionsMetadata.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/VersionsMetadata.java @@ -20,9 +20,9 @@ package org.apache.maven.internal.impl.resolver; import java.io.File; import java.nio.file.Path; +import java.time.Instant; import java.util.ArrayList; import java.util.Collection; -import java.util.Date; import java.util.LinkedHashSet; import java.util.List; @@ -38,12 +38,12 @@ final class VersionsMetadata extends MavenMetadata { private final Artifact artifact; - VersionsMetadata(Artifact artifact, Date timestamp) { + VersionsMetadata(Artifact artifact, Instant timestamp) { super(createRepositoryMetadata(artifact), (Path) null, timestamp); this.artifact = artifact; } - VersionsMetadata(Artifact artifact, Path path, Date timestamp) { + VersionsMetadata(Artifact artifact, Path path, Instant timestamp) { super(createRepositoryMetadata(artifact), path, timestamp); this.artifact = artifact; } diff --git a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/VersionsMetadataGenerator.java b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/VersionsMetadataGenerator.java index f23a482499..c684311fce 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/VersionsMetadataGenerator.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/internal/impl/resolver/VersionsMetadataGenerator.java @@ -18,13 +18,15 @@ */ package org.apache.maven.internal.impl.resolver; +import java.time.Instant; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; +import org.apache.maven.api.Constants; +import org.apache.maven.api.MonotonicClock; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.deployment.DeployRequest; @@ -44,7 +46,7 @@ class VersionsMetadataGenerator implements MetadataGenerator { private final Map processedVersions; - private final Date timestamp; + private final Instant timestamp; VersionsMetadataGenerator(RepositorySystemSession session, InstallRequest request) { this(session, request.getMetadata()); @@ -57,7 +59,7 @@ class VersionsMetadataGenerator implements MetadataGenerator { private VersionsMetadataGenerator(RepositorySystemSession session, Collection metadatas) { versions = new LinkedHashMap<>(); processedVersions = new LinkedHashMap<>(); - timestamp = (Date) ConfigUtils.getObject(session, new Date(), "maven.startTime"); + timestamp = (Instant) ConfigUtils.getObject(session, MonotonicClock.now(), Constants.MAVEN_START_INSTANT); /* * NOTE: This should be considered a quirk to support interop with Maven's legacy ArtifactDeployer which diff --git a/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/model/DefaultModelInterpolatorTest.java b/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/model/DefaultModelInterpolatorTest.java index beae5c686a..177dbb1870 100644 --- a/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/model/DefaultModelInterpolatorTest.java +++ b/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/model/DefaultModelInterpolatorTest.java @@ -21,10 +21,11 @@ package org.apache.maven.internal.impl.model; import java.nio.file.FileSystem; import java.nio.file.Path; import java.nio.file.Paths; -import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -108,7 +109,7 @@ class DefaultModelInterpolatorTest { @Test public void testDefaultBuildTimestampFormatShouldFormatTimeIn24HourFormat() { Calendar cal = Calendar.getInstance(); - cal.setTimeZone(MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE); + cal.setTimeZone(TimeZone.getTimeZone("Etc/UTC")); cal.set(Calendar.HOUR, 12); cal.set(Calendar.AM_PM, Calendar.AM); @@ -120,7 +121,7 @@ class DefaultModelInterpolatorTest { cal.set(Calendar.MONTH, Calendar.NOVEMBER); cal.set(Calendar.DATE, 11); - Date firstTestDate = cal.getTime(); + Instant firstTestDate = Instant.ofEpochMilli(cal.getTime().getTime()); cal.set(Calendar.HOUR, 11); cal.set(Calendar.AM_PM, Calendar.PM); @@ -128,10 +129,11 @@ class DefaultModelInterpolatorTest { // just to make sure all the bases are covered... cal.set(Calendar.HOUR_OF_DAY, 23); - Date secondTestDate = cal.getTime(); + Instant secondTestDate = Instant.ofEpochMilli(cal.getTime().getTime()); + + DateTimeFormatter format = DateTimeFormatter.ofPattern(MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT) + .withZone(ZoneId.of("UTC")); - SimpleDateFormat format = new SimpleDateFormat(MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT); - format.setTimeZone(MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE); assertEquals("1976-11-11T00:16:00Z", format.format(firstTestDate)); assertEquals("1976-11-11T23:16:00Z", format.format(secondTestDate)); } @@ -148,14 +150,14 @@ class DefaultModelInterpolatorTest { cal.set(Calendar.MONTH, Calendar.JUNE); cal.set(Calendar.DATE, 16); - Date firstTestDate = cal.getTime(); + Instant firstTestDate = Instant.ofEpochMilli(cal.getTime().getTime()); cal.set(Calendar.MONTH, Calendar.NOVEMBER); - Date secondTestDate = cal.getTime(); + Instant secondTestDate = Instant.ofEpochMilli(cal.getTime().getTime()); - SimpleDateFormat format = new SimpleDateFormat(MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT); - format.setTimeZone(MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE); + DateTimeFormatter format = DateTimeFormatter.ofPattern(MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT) + .withZone(ZoneId.of("UTC")); assertEquals("2014-06-15T23:16:00Z", format.format(firstTestDate)); assertEquals("2014-11-16T00:16:00Z", format.format(secondTestDate)); } diff --git a/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/model/MavenBuildTimestampTest.java b/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/model/MavenBuildTimestampTest.java index d19d32f45a..d08cac07ad 100644 --- a/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/model/MavenBuildTimestampTest.java +++ b/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/model/MavenBuildTimestampTest.java @@ -18,10 +18,10 @@ */ package org.apache.maven.internal.impl.model; -import java.time.Instant; import java.util.HashMap; import java.util.Map; +import org.apache.maven.api.MonotonicClock; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -31,7 +31,7 @@ class MavenBuildTimestampTest { void testMavenBuildTimestampUsesUTC() { Map interpolationProperties = new HashMap<>(); interpolationProperties.put("maven.build.timestamp.format", "yyyyMMdd'T'HHmm'Z'"); - MavenBuildTimestamp timestamp = new MavenBuildTimestamp(Instant.now(), interpolationProperties); + MavenBuildTimestamp timestamp = new MavenBuildTimestamp(MonotonicClock.now(), interpolationProperties); String formattedTimestamp = timestamp.formattedTimestamp(); assertTrue(formattedTimestamp.endsWith("Z"), "We expect the UTC marker at the end of the timestamp."); } diff --git a/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java b/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java index 7eba766de2..ecf5d5fb18 100644 --- a/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java +++ b/impl/maven-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java @@ -34,6 +34,7 @@ import java.util.stream.Collectors; import org.apache.maven.api.Artifact; import org.apache.maven.api.Lifecycle; +import org.apache.maven.api.MonotonicClock; import org.apache.maven.api.Packaging; import org.apache.maven.api.ProducedArtifact; import org.apache.maven.api.Project; @@ -101,7 +102,7 @@ public class ApiRunner { static class DefaultSession extends AbstractSession { private final Map systemProperties; - private final Instant startTime = Instant.now(); + private final Instant startTime = MonotonicClock.now(); DefaultSession(RepositorySystemSession session, RepositorySystem repositorySystem, Lookup lookup) { this(session, repositorySystem, Collections.emptyList(), null, lookup); diff --git a/impl/maven-logging/src/main/java/org/apache/maven/slf4j/MavenBaseLogger.java b/impl/maven-logging/src/main/java/org/apache/maven/slf4j/MavenBaseLogger.java index 273f13ebc7..19fc45a665 100644 --- a/impl/maven-logging/src/main/java/org/apache/maven/slf4j/MavenBaseLogger.java +++ b/impl/maven-logging/src/main/java/org/apache/maven/slf4j/MavenBaseLogger.java @@ -19,10 +19,13 @@ package org.apache.maven.slf4j; import java.io.PrintStream; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; import java.util.ArrayList; -import java.util.Date; import java.util.List; +import org.apache.maven.api.MonotonicClock; import org.slf4j.Logger; import org.slf4j.Marker; import org.slf4j.event.Level; @@ -145,7 +148,8 @@ public class MavenBaseLogger extends LegacyAbstractLogger { private static final long serialVersionUID = -632788891211436180L; - private static final long START_TIME = System.currentTimeMillis(); + private static final Clock MONOTONIC_CLOCK = Clock.tick(Clock.systemUTC(), Duration.ofMillis(1)); + private static final Instant START_TIME = MonotonicClock.now(); protected static final int LOG_LEVEL_TRACE = LocationAwareLogger.TRACE_INT; protected static final int LOG_LEVEL_DEBUG = LocationAwareLogger.DEBUG_INT; @@ -265,7 +269,7 @@ public class MavenBaseLogger extends LegacyAbstractLogger { } protected String getFormattedDate() { - Date now = new Date(); + Instant now = MonotonicClock.now(); String dateText; synchronized (CONFIG_PARAMS.dateFormatter) { dateText = CONFIG_PARAMS.dateFormatter.format(now); @@ -382,7 +386,7 @@ public class MavenBaseLogger extends LegacyAbstractLogger { buf.append(getFormattedDate()); buf.append(SP); } else { - buf.append(System.currentTimeMillis() - START_TIME); + buf.append(Duration.between(START_TIME, MonotonicClock.now()).toMillis()); buf.append(SP); } } diff --git a/impl/maven-logging/src/main/java/org/apache/maven/slf4j/SimpleLoggerConfiguration.java b/impl/maven-logging/src/main/java/org/apache/maven/slf4j/SimpleLoggerConfiguration.java index 02ca0f464e..63b3667402 100644 --- a/impl/maven-logging/src/main/java/org/apache/maven/slf4j/SimpleLoggerConfiguration.java +++ b/impl/maven-logging/src/main/java/org/apache/maven/slf4j/SimpleLoggerConfiguration.java @@ -22,8 +22,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.PrintStream; -import java.text.DateFormat; -import java.text.SimpleDateFormat; +import java.time.format.DateTimeFormatter; import java.util.Properties; import org.apache.maven.slf4j.OutputChoice.OutputChoiceType; @@ -56,7 +55,7 @@ public class SimpleLoggerConfiguration { private static final String DATE_TIME_FORMAT_STR_DEFAULT = null; private static String dateTimeFormatStr = DATE_TIME_FORMAT_STR_DEFAULT; - DateFormat dateFormatter = null; + DateTimeFormatter dateFormatter = null; private static final boolean SHOW_THREAD_NAME_DEFAULT = true; boolean showThreadName = SHOW_THREAD_NAME_DEFAULT; @@ -116,7 +115,7 @@ public class SimpleLoggerConfiguration { if (dateTimeFormatStr != null) { try { - dateFormatter = new SimpleDateFormat(dateTimeFormatStr); + dateFormatter = DateTimeFormatter.ofPattern(dateTimeFormatStr); } catch (IllegalArgumentException e) { Reporter.error("Bad date format in " + CONFIGURATION_FILE + "; will output relative time", e); } diff --git a/src/site/markdown/configuration.properties b/src/site/markdown/configuration.properties index b6366ad964..44b45571ff 100644 --- a/src/site/markdown/configuration.properties +++ b/src/site/markdown/configuration.properties @@ -16,7 +16,7 @@ # specific language governing permissions and limitations # under the License. # -props.count = 43 +props.count = 44 props.1.key = maven.build.timestamp.format props.1.configurationType = String props.1.description = Build timestamp format. @@ -171,105 +171,111 @@ props.26.configurationType = String props.26.description = props.26.defaultValue = ${maven.user.conf}/settings-security4.xml props.26.configurationSource = User properties -props.27.key = maven.style.color +props.27.key = maven.startInstant props.27.configurationType = String -props.27.description = Maven output color mode. Allowed values are auto, always, never. -props.27.defaultValue = auto -props.27.since = 4.0.0 +props.27.description = User property used to store the build timestamp. +props.27.defaultValue = +props.27.since = 4.1.0 props.27.configurationSource = User properties -props.28.key = maven.style.debug +props.28.key = maven.style.color props.28.configurationType = String -props.28.description = Color style for debug messages. -props.28.defaultValue = bold,f:cyan +props.28.description = Maven output color mode. Allowed values are auto, always, never. +props.28.defaultValue = auto props.28.since = 4.0.0 props.28.configurationSource = User properties -props.29.key = maven.style.error +props.29.key = maven.style.debug props.29.configurationType = String -props.29.description = Color style for error messages. -props.29.defaultValue = bold,f:red +props.29.description = Color style for debug messages. +props.29.defaultValue = bold,f:cyan props.29.since = 4.0.0 props.29.configurationSource = User properties -props.30.key = maven.style.failure +props.30.key = maven.style.error props.30.configurationType = String -props.30.description = Color style for failure messages. +props.30.description = Color style for error messages. props.30.defaultValue = bold,f:red props.30.since = 4.0.0 props.30.configurationSource = User properties -props.31.key = maven.style.info +props.31.key = maven.style.failure props.31.configurationType = String -props.31.description = Color style for info messages. -props.31.defaultValue = bold,f:blue +props.31.description = Color style for failure messages. +props.31.defaultValue = bold,f:red props.31.since = 4.0.0 props.31.configurationSource = User properties -props.32.key = maven.style.mojo +props.32.key = maven.style.info props.32.configurationType = String -props.32.description = Color style for mojo messages. -props.32.defaultValue = f:green +props.32.description = Color style for info messages. +props.32.defaultValue = bold,f:blue props.32.since = 4.0.0 props.32.configurationSource = User properties -props.33.key = maven.style.project +props.33.key = maven.style.mojo props.33.configurationType = String -props.33.description = Color style for project messages. -props.33.defaultValue = f:cyan +props.33.description = Color style for mojo messages. +props.33.defaultValue = f:green props.33.since = 4.0.0 props.33.configurationSource = User properties -props.34.key = maven.style.strong +props.34.key = maven.style.project props.34.configurationType = String -props.34.description = Color style for strong messages. -props.34.defaultValue = bold +props.34.description = Color style for project messages. +props.34.defaultValue = f:cyan props.34.since = 4.0.0 props.34.configurationSource = User properties -props.35.key = maven.style.success +props.35.key = maven.style.strong props.35.configurationType = String -props.35.description = Color style for success messages. -props.35.defaultValue = bold,f:green +props.35.description = Color style for strong messages. +props.35.defaultValue = bold props.35.since = 4.0.0 props.35.configurationSource = User properties -props.36.key = maven.style.trace +props.36.key = maven.style.success props.36.configurationType = String -props.36.description = Color style for trace messages. -props.36.defaultValue = bold,f:magenta +props.36.description = Color style for success messages. +props.36.defaultValue = bold,f:green props.36.since = 4.0.0 props.36.configurationSource = User properties -props.37.key = maven.style.transfer +props.37.key = maven.style.trace props.37.configurationType = String -props.37.description = Color style for transfer messages. -props.37.defaultValue = f:bright-black +props.37.description = Color style for trace messages. +props.37.defaultValue = bold,f:magenta props.37.since = 4.0.0 props.37.configurationSource = User properties -props.38.key = maven.style.warning +props.38.key = maven.style.transfer props.38.configurationType = String -props.38.description = Color style for warning messages. -props.38.defaultValue = bold,f:yellow +props.38.description = Color style for transfer messages. +props.38.defaultValue = f:bright-black props.38.since = 4.0.0 props.38.configurationSource = User properties -props.39.key = maven.user.conf +props.39.key = maven.style.warning props.39.configurationType = String -props.39.description = Maven user configuration directory. -props.39.defaultValue = ${user.home}/.m2 +props.39.description = Color style for warning messages. +props.39.defaultValue = bold,f:yellow props.39.since = 4.0.0 props.39.configurationSource = User properties -props.40.key = maven.user.extensions +props.40.key = maven.user.conf props.40.configurationType = String -props.40.description = Maven user extensions. -props.40.defaultValue = ${maven.user.conf}/extensions.xml +props.40.description = Maven user configuration directory. +props.40.defaultValue = ${user.home}/.m2 props.40.since = 4.0.0 props.40.configurationSource = User properties -props.41.key = maven.user.settings +props.41.key = maven.user.extensions props.41.configurationType = String -props.41.description = Maven user settings. -props.41.defaultValue = ${maven.user.conf}/settings.xml +props.41.description = Maven user extensions. +props.41.defaultValue = ${maven.user.conf}/extensions.xml props.41.since = 4.0.0 props.41.configurationSource = User properties -props.42.key = maven.user.toolchains +props.42.key = maven.user.settings props.42.configurationType = String -props.42.description = Maven user toolchains. -props.42.defaultValue = ${maven.user.conf}/toolchains.xml +props.42.description = Maven user settings. +props.42.defaultValue = ${maven.user.conf}/settings.xml props.42.since = 4.0.0 props.42.configurationSource = User properties -props.43.key = maven.versionResolver.noCache -props.43.configurationType = Boolean -props.43.description = User property for disabling version resolver cache. -props.43.defaultValue = false -props.43.since = 3.0.0 +props.43.key = maven.user.toolchains +props.43.configurationType = String +props.43.description = Maven user toolchains. +props.43.defaultValue = ${maven.user.conf}/toolchains.xml +props.43.since = 4.0.0 props.43.configurationSource = User properties +props.44.key = maven.versionResolver.noCache +props.44.configurationType = Boolean +props.44.description = User property for disabling version resolver cache. +props.44.defaultValue = false +props.44.since = 3.0.0 +props.44.configurationSource = User properties diff --git a/src/site/markdown/configuration.yaml b/src/site/markdown/configuration.yaml index aea2d4470f..f225960935 100644 --- a/src/site/markdown/configuration.yaml +++ b/src/site/markdown/configuration.yaml @@ -171,6 +171,12 @@ props: description: "" defaultValue: ${maven.user.conf}/settings-security4.xml configurationSource: User properties + - key: maven.startInstant + configurationType: String + description: "User property used to store the build timestamp." + defaultValue: + since: 4.1.0 + configurationSource: User properties - key: maven.style.color configurationType: String description: "Maven output color mode. Allowed values are auto, always, never." diff --git a/src/site/markdown/maven-configuration.md b/src/site/markdown/maven-configuration.md index fbc6cda3cf..aa4eada9ed 100644 --- a/src/site/markdown/maven-configuration.md +++ b/src/site/markdown/maven-configuration.md @@ -51,21 +51,22 @@ under the License. | 24. | `maven.resolver.transport` | `String` | Resolver transport to use. Can be default, wagon, apache, jdk or auto. | `default` | 4.0.0 | User properties | | 25. | `maven.session.versionFilter` | `String` | User property for version filter expression used in session, applied to resolving ranges: a semicolon separated list of filters to apply. By default, no version filter is applied (like in Maven 3).
Supported filters:

Example filter expression: "h(5);s;e(org.foo:bar:1) will cause: ranges are filtered for "top 5" (instead full range), snapshots are banned if root project is not a snapshot, and if range for org.foo:bar is being processed, version 1 is omitted. Value in this property builds org.eclipse.aether.collection.VersionFilter instance. | - | 4.0.0 | User properties | | 26. | `maven.settings.security` | `String` | | `${maven.user.conf}/settings-security4.xml` | | User properties | -| 27. | `maven.style.color` | `String` | Maven output color mode. Allowed values are auto, always, never. | `auto` | 4.0.0 | User properties | -| 28. | `maven.style.debug` | `String` | Color style for debug messages. | `bold,f:cyan` | 4.0.0 | User properties | -| 29. | `maven.style.error` | `String` | Color style for error messages. | `bold,f:red` | 4.0.0 | User properties | -| 30. | `maven.style.failure` | `String` | Color style for failure messages. | `bold,f:red` | 4.0.0 | User properties | -| 31. | `maven.style.info` | `String` | Color style for info messages. | `bold,f:blue` | 4.0.0 | User properties | -| 32. | `maven.style.mojo` | `String` | Color style for mojo messages. | `f:green` | 4.0.0 | User properties | -| 33. | `maven.style.project` | `String` | Color style for project messages. | `f:cyan` | 4.0.0 | User properties | -| 34. | `maven.style.strong` | `String` | Color style for strong messages. | `bold` | 4.0.0 | User properties | -| 35. | `maven.style.success` | `String` | Color style for success messages. | `bold,f:green` | 4.0.0 | User properties | -| 36. | `maven.style.trace` | `String` | Color style for trace messages. | `bold,f:magenta` | 4.0.0 | User properties | -| 37. | `maven.style.transfer` | `String` | Color style for transfer messages. | `f:bright-black` | 4.0.0 | User properties | -| 38. | `maven.style.warning` | `String` | Color style for warning messages. | `bold,f:yellow` | 4.0.0 | User properties | -| 39. | `maven.user.conf` | `String` | Maven user configuration directory. | `${user.home}/.m2` | 4.0.0 | User properties | -| 40. | `maven.user.extensions` | `String` | Maven user extensions. | `${maven.user.conf}/extensions.xml` | 4.0.0 | User properties | -| 41. | `maven.user.settings` | `String` | Maven user settings. | `${maven.user.conf}/settings.xml` | 4.0.0 | User properties | -| 42. | `maven.user.toolchains` | `String` | Maven user toolchains. | `${maven.user.conf}/toolchains.xml` | 4.0.0 | User properties | -| 43. | `maven.versionResolver.noCache` | `Boolean` | User property for disabling version resolver cache. | `false` | 3.0.0 | User properties | +| 27. | `maven.startInstant` | `String` | User property used to store the build timestamp. | - | 4.1.0 | User properties | +| 28. | `maven.style.color` | `String` | Maven output color mode. Allowed values are auto, always, never. | `auto` | 4.0.0 | User properties | +| 29. | `maven.style.debug` | `String` | Color style for debug messages. | `bold,f:cyan` | 4.0.0 | User properties | +| 30. | `maven.style.error` | `String` | Color style for error messages. | `bold,f:red` | 4.0.0 | User properties | +| 31. | `maven.style.failure` | `String` | Color style for failure messages. | `bold,f:red` | 4.0.0 | User properties | +| 32. | `maven.style.info` | `String` | Color style for info messages. | `bold,f:blue` | 4.0.0 | User properties | +| 33. | `maven.style.mojo` | `String` | Color style for mojo messages. | `f:green` | 4.0.0 | User properties | +| 34. | `maven.style.project` | `String` | Color style for project messages. | `f:cyan` | 4.0.0 | User properties | +| 35. | `maven.style.strong` | `String` | Color style for strong messages. | `bold` | 4.0.0 | User properties | +| 36. | `maven.style.success` | `String` | Color style for success messages. | `bold,f:green` | 4.0.0 | User properties | +| 37. | `maven.style.trace` | `String` | Color style for trace messages. | `bold,f:magenta` | 4.0.0 | User properties | +| 38. | `maven.style.transfer` | `String` | Color style for transfer messages. | `f:bright-black` | 4.0.0 | User properties | +| 39. | `maven.style.warning` | `String` | Color style for warning messages. | `bold,f:yellow` | 4.0.0 | User properties | +| 40. | `maven.user.conf` | `String` | Maven user configuration directory. | `${user.home}/.m2` | 4.0.0 | User properties | +| 41. | `maven.user.extensions` | `String` | Maven user extensions. | `${maven.user.conf}/extensions.xml` | 4.0.0 | User properties | +| 42. | `maven.user.settings` | `String` | Maven user settings. | `${maven.user.conf}/settings.xml` | 4.0.0 | User properties | +| 43. | `maven.user.toolchains` | `String` | Maven user toolchains. | `${maven.user.conf}/toolchains.xml` | 4.0.0 | User properties | +| 44. | `maven.versionResolver.noCache` | `Boolean` | User property for disabling version resolver cache. | `false` | 3.0.0 | User properties |