[crac] RFR: Merge jdk:jdk-25+10
Dmitry Cherepanov
dcherepanov at openjdk.org
Mon May 26 22:51:55 UTC 2025
This PR includes merges for tags between `jdk-25+5` and `jdk-25+10`, attaching output of `--diff-merges=remerge` for each merge
<details>
<summary>jdk-25+5</summary>
commit 5ae68607f0b679587a60a1aab8b2aadb4105bbb7
Merge: ed3997056b6 2e00816ac30
Author: Dmitry Cherepanov <dcherepanov at azul.com>
Date: Mon May 19 22:35:02 2025 +0400
Merge with jdk-25+5
</details>
<details>
<summary>jdk-25+6</summary>
commit cc975a31216702e48256ad35e96957c978190027
Merge: 5ae68607f0b 9c430c92257
Author: Dmitry Cherepanov <dcherepanov at azul.com>
Date: Mon May 26 20:44:57 2025 +0400
Merge with jdk-25+6
diff --git a/src/hotspot/share/compiler/compileLog.cpp b/src/hotspot/share/compiler/compileLog.cpp
index 4c8165fc7bd..f183d628d45 100644
--- a/src/hotspot/share/compiler/compileLog.cpp
+++ b/src/hotspot/share/compiler/compileLog.cpp
@@ -340,7 +340,7 @@ void CompileLog::finish_log_on_checkpoint(outputStream* file) {
// print/print_cr may need to allocate large stack buffer to format
// strings, here we use snprintf() and print_raw() instead.
file->print_raw("<compilation_log thread='");
- jio_snprintf(buf, buflen, UINTX_FORMAT, log->thread_id());
+ jio_snprintf(buf, buflen, "%zu", log->thread_id());
file->print_raw(buf);
file->print_raw_cr("'>");
diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp
remerge CONFLICT (content): Merge conflict in src/hotspot/share/gc/parallel/psParallelCompact.cpp
index 00bb365dffd..438b6b90740 100644
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp
@@ -1,10 +1,6 @@
/*
-<<<<<<< 5ae68607f0b (Merge with jdk-25+5)
- * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2019, 2021, Azul Systems, Inc. All rights reserved.
-=======
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
->>>>>>> 9c430c92257 (8336920: ArithmeticException in javax.sound.sampled.AudioInputStream)
+ * Copyright (c) 2019, 2021, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp
remerge CONFLICT (content): Merge conflict in src/hotspot/share/gc/serial/defNewGeneration.cpp
index 1151a9847b5..bbb0a64ad5c 100644
--- a/src/hotspot/share/gc/serial/defNewGeneration.cpp
+++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp
@@ -1,10 +1,6 @@
/*
-<<<<<<< 5ae68607f0b (Merge with jdk-25+5)
- * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2019, 2021, Azul Systems, Inc. All rights reserved.
-=======
* Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved.
->>>>>>> 9c430c92257 (8336920: ArithmeticException in javax.sound.sampled.AudioInputStream)
+ * Copyright (c) 2019, 2021, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
remerge CONFLICT (content): Merge conflict in src/hotspot/share/runtime/arguments.cpp
index 36913cea320..a185c895ec4 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -1,10 +1,6 @@
/*
-<<<<<<< 5ae68607f0b (Merge with jdk-25+5)
- * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2017, 2024, Azul Systems, Inc. All rights reserved.
-=======
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
->>>>>>> 9c430c92257 (8336920: ArithmeticException in javax.sound.sampled.AudioInputStream)
+ * Copyright (c) 2017, 2024, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java
remerge CONFLICT (content): Merge conflict in src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java
index 58772e8328e..e3a1b749388 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java
@@ -34,14 +34,8 @@
import java.io.File;
import java.io.IOException;
-<<<<<<< 5ae68607f0b (Merge with jdk-25+5)
import java.nio.file.Files;
import java.nio.file.Path;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-=======
-import java.nio.file.Path;
->>>>>>> 9c430c92257 (8336920: ArithmeticException in javax.sound.sampled.AudioInputStream)
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
@@ -53,11 +47,7 @@
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
-<<<<<<< 5ae68607f0b (Merge with jdk-25+5)
-import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
-=======
->>>>>>> 9c430c92257 (8336920: ArithmeticException in javax.sound.sampled.AudioInputStream)
import jdk.internal.crac.Core;
import jdk.internal.crac.JDKResource;
@@ -133,15 +123,12 @@ public void afterRestore(Context<? extends Resource> context) throws Exception {
synchronized (PlatformRecorder.this) {
futureRecordings.forEach(r -> {
recordings.add(r);
- WriteableUserPath destination = r.getDestination();
- // The backup recording has to be moved before creating WriteableUserPath
+ WriteablePath destination = r.getDestination();
+ // The backup recording has to be moved before creating WriteablePath
// (and touching the recording output file)
try {
- destination.doPrivilegedIO(() -> {
- File destFile = destination.getReal().toFile();
- if (!destFile.exists()) {
- return null;
- }
+ File destFile = destination.getReal().toFile();
+ if (destFile.exists()) {
Path backup = null;
for (int i = 0; backup == null && i < MAX_BACKUPS; ++i) {
String name = destFile.getName();
@@ -161,15 +148,14 @@ public void afterRestore(Context<? extends Resource> context) throws Exception {
Files.move(destFile.toPath(), backup);
Logger.log(JFR, INFO, "Backed up " + destFile + " to " + backup);
}
- return null;
- });
+ }
} catch (IOException e) {
Logger.log(JFR, ERROR, "Cannot backup previous recording: " + e);
}
try {
- // We need to invoke WritableUserPath after restore to create the dump file.
- // Since we're creating another WritableUserPath we can use the original specification
- r.setDestination(new WriteableUserPath(destination.getPotentiallyMaliciousOriginal()));
+ // We need to invoke WriteablePath after restore to create the dump file.
+ // Since we're creating another WriteablePath we can use the original specification
+ r.setDestination(new WriteablePath(destination.getPath()));
} catch (IOException e) {
Logger.log(JFR, ERROR, "Cannot reset recording destination: " + e);
}
@@ -188,33 +174,11 @@ public PlatformRecorder() throws Exception {
JDKEvents.initialize();
Logger.log(JFR_SYSTEM, INFO, "Registered JDK events");
startDiskMonitor();
-<<<<<<< 5ae68607f0b (Merge with jdk-25+5)
- shutdownHook = SecuritySupport.createThreadWitNoPermissions("JFR Shutdown Hook", new ShutdownHook(this));
- SecuritySupport.setUncaughtExceptionHandler(shutdownHook, new ShutdownHook.ExceptionHandler());
- SecuritySupport.registerShutdownHook(shutdownHook);
-
- Core.Priority.JFR.getContext().register(resource);
- }
-
-
- private static Timer createTimer() {
- try {
- List<Timer> result = new CopyOnWriteArrayList<>();
- Thread t = SecuritySupport.createThreadWitNoPermissions("Permissionless thread", ()-> {
- result.add(new Timer("JFR Recording Scheduler", true));
- });
- JVM.exclude(t);
- t.start();
- t.join();
- return result.getFirst();
- } catch (InterruptedException e) {
- throw new IllegalStateException("Not able to create timer task. " + e.getMessage(), e);
- }
-=======
shutdownHook = new ShutdownHook(this);
shutdownHook.setUncaughtExceptionHandler(new ShutdownHook.ExceptionHandler());
Runtime.getRuntime().addShutdownHook(shutdownHook);
->>>>>>> 9c430c92257 (8336920: ArithmeticException in javax.sound.sampled.AudioInputStream)
+
+ Core.Priority.JFR.getContext().register(resource);
}
public synchronized PlatformRecording newRecording(Map<String, String> settings) {
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java
index def8f757615..91430369ed2 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java
@@ -827,7 +827,7 @@ private static List<RepositoryChunk> reduceFromEnd(Long maxSize, List<Repository
return result;
}
- SafePath getDumpDirectory() {
+ Path getDumpDirectory() {
return dumpDirectory;
}
</details>
Merge with jdk-25+6 requires additional changes
- use `%zu` after [JDK-8346990](https://bugs.openjdk.org/browse/JDK-8346990)
- adjust JFR code after [JDK-8347287](https://bugs.openjdk.org/browse/JDK-8347287) refactored helper classes
<details>
<summary>jdk-25+7</summary>
commit b150e5dae99fdb451b00344ea53dde0f3139a3cf
Merge: cc975a31216 8cf07358397
Author: Dmitry Cherepanov <dcherepanov at azul.com>
Date: Mon May 26 22:28:44 2025 +0400
Merge with jdk-25+7
diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
remerge CONFLICT (content): Merge conflict in src/hotspot/os/linux/os_linux.cpp
index 5ddb60173e4..08386bf941a 100644
--- a/src/hotspot/os/linux/os_linux.cpp
+++ b/src/hotspot/os/linux/os_linux.cpp
@@ -24,11 +24,7 @@
*
*/
-<<<<<<< cc975a31216 (Merge with jdk-25+6)
-// no precompiled headers
#include "classfile/classLoader.hpp"
-=======
->>>>>>> 8cf07358397 (8348102: java/net/httpclient/HttpClientSNITest.java fails intermittently)
#include "classfile/vmSymbols.hpp"
#include "code/vtableStubs.hpp"
#include "compiler/compileBroker.hpp"
diff --git a/src/hotspot/os/windows/crac_windows.cpp b/src/hotspot/os/windows/crac_windows.cpp
index e5c69ec440b..8fff5135bf4 100644
--- a/src/hotspot/os/windows/crac_windows.cpp
+++ b/src/hotspot/os/windows/crac_windows.cpp
@@ -21,8 +21,6 @@
* questions.
*/
-#include "precompiled.hpp"
-
#include "jvm.h"
#include "runtime/crac_structs.hpp"
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
remerge CONFLICT (content): Merge conflict in src/hotspot/share/gc/g1/g1CollectedHeap.cpp
index b9d443c32c9..c0e2f158284 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
@@ -1,10 +1,6 @@
/*
-<<<<<<< cc975a31216 (Merge with jdk-25+6)
- * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2019, 2021, Azul Systems, Inc. All rights reserved.
-=======
* Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved.
->>>>>>> 8cf07358397 (8348102: java/net/httpclient/HttpClientSNITest.java fails intermittently)
+ * Copyright (c) 2019, 2021, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/src/hotspot/share/gc/z/zPageAllocator.cpp b/src/hotspot/share/gc/z/zPageAllocator.cpp
index 974ae74fdc7..02a70bfd2a3 100644
--- a/src/hotspot/share/gc/z/zPageAllocator.cpp
+++ b/src/hotspot/share/gc/z/zPageAllocator.cpp
@@ -1059,7 +1059,7 @@ void ZPageAllocator::uncommit_unused_memory() {
} while (flushed > 0);
if (uncommitted > 0) {
EventZUncommit event;
- log_info(gc, heap)("Uncommitted (cleanup): " SIZE_FORMAT "M(%.0f%%)",
+ log_info(gc, heap)("Uncommitted (cleanup): %zuM(%.0f%%)",
uncommitted / M, percent_of(uncommitted, ZHeap::heap()->max_capacity()));
event.commit(uncommitted);
}
diff --git a/src/hotspot/share/runtime/crac.cpp b/src/hotspot/share/runtime/crac.cpp
index 85610dde1e6..5580538bbcc 100644
--- a/src/hotspot/share/runtime/crac.cpp
+++ b/src/hotspot/share/runtime/crac.cpp
@@ -21,8 +21,6 @@
* questions.
*/
-#include "precompiled.hpp"
-
#include "classfile/classLoader.hpp"
#include "jfr/jfr.hpp"
#include "jvm.h"
diff --git a/src/hotspot/share/runtime/crac_engine.cpp b/src/hotspot/share/runtime/crac_engine.cpp
index b5ae02bbf7a..40f981c3f03 100644
--- a/src/hotspot/share/runtime/crac_engine.cpp
+++ b/src/hotspot/share/runtime/crac_engine.cpp
@@ -21,8 +21,6 @@
* questions.
*/
-#include "precompiled.hpp"
-
#include "crlib/crlib.h"
#include "crlib/crlib_restore_data.h"
#include "logging/log.hpp"
diff --git a/test/lib/jdk/test/lib/crac/CracTest.java b/test/lib/jdk/test/lib/crac/CracTest.java
index 8ccea9cea67..383d50a2566 100644
--- a/test/lib/jdk/test/lib/crac/CracTest.java
+++ b/test/lib/jdk/test/lib/crac/CracTest.java
@@ -56,6 +56,7 @@ class ArgsHolder {
/**
* Main method for orchestrating the test. This should be called directly by JTReg.
*/
+ @SuppressWarnings("unchecked")
static void main(String[] args) throws Exception {
String testClassName;
if (args.length == 0 || !ArgsHolder.RUN_TEST.equals(args[0])) {
@@ -99,6 +100,7 @@ static void main(String[] args) throws Exception {
* @param args Arguments received in the main method.
* @throws Exception
*/
+ @SuppressWarnings("unchecked")
static void run(Class<? extends CracTest> testClass, String[] args) throws Exception {
assertNotNull(args);
ArgsHolder.testClass = testClass;
</details>
Merge with jdk-25+7 requires additional changes
- avoid explicit `#include "precompiled.hpp"` after [JDK-8347909](https://bugs.openjdk.org/browse/JDK-8347909)
- use `%zu` after [JDK-8347731](https://bugs.openjdk.org/browse/JDK-8347731)
- suppress unchecked warning in `CracTest.java` after [JDK-8347840](https://bugs.openjdk.org/browse/JDK-8347840) enabled warnings in build scripts
<details>
<summary>jdk-25+8</summary>
commit c1da8a1879af8360e5ced3a5011a4de17604bae2
Merge: b150e5dae99 d985b31cbb5
Author: Dmitry Cherepanov <dcherepanov at azul.com>
Date: Tue May 27 01:33:18 2025 +0400
Merge with jdk-25+8
diff --git a/src/java.base/share/classes/java/security/SecureRandom.java b/src/java.base/share/classes/java/security/SecureRandom.java
remerge CONFLICT (content): Merge conflict in src/java.base/share/classes/java/security/SecureRandom.java
index 170b21b603f..c5104d883f8 100644
--- a/src/java.base/share/classes/java/security/SecureRandom.java
+++ b/src/java.base/share/classes/java/security/SecureRandom.java
@@ -214,14 +214,11 @@ public class SecureRandom extends java.util.Random {
* "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard RNG algorithm names.
-<<<<<<< b150e5dae99 (Merge with jdk-25+7)
*
* @crac Instances created by this constructor are automatically reseeded
* after restore from a checkpoint.
* See {@link sun.security.provider.SecureRandom} for details.
-=======
* @spec security/standard-names.html Java Security Standard Algorithm Names
->>>>>>> d985b31cbb5 (8342096: Popup menus that request focus are not shown on Linux with Wayland)
*/
public SecureRandom() {
/*
</details>
<details>
<summary>jdk-25+9</summary>
commit 203c311bb3aaa8bcd44b3b6b6849ced3a4846c11
Merge: c1da8a1879a 30f71622a1c
Author: Dmitry Cherepanov <dcherepanov at azul.com>
Date: Tue May 27 01:33:25 2025 +0400
Merge with jdk-25+9
</details>
<details>
<summary>jdk-25+10</summary>
commit 2aac32e50e809f6cdd4dfeb1b1ef438e6afc4668 (HEAD -> merge-jdk, dmitry-crac/merge-jdk)
Merge: 203c311bb3a a637ccf2fea
Author: Dmitry Cherepanov <dcherepanov at azul.com>
Date: Tue May 27 01:34:26 2025 +0400
Merge with jdk-25+10
diff --git a/.jcheck/conf b/.jcheck/conf
remerge CONFLICT (content): Merge conflict in .jcheck/conf
index aaca839a59d..25bd8dd0b94 100644
--- a/.jcheck/conf
+++ b/.jcheck/conf
@@ -13,31 +13,3 @@ ignore=duke
[census]
version=0
domain=openjdk.org
-<<<<<<< 203c311bb3a (Merge with jdk-25+9)
-=======
-
-[checks "whitespace"]
-files=.*.cpp|.*.hpp|.*.c|.*.h|.*.java|.*.cc|.*.hh|.*.m|.*.mm|.*.S|.*.md|.*.properties|.*.gmk|.*.m4|.*.ac|Makefile
-ignore-tabs=.*.gmk|Makefile
-
-[checks "merge"]
-message=Merge
-
-[checks "reviewers"]
-reviewers=1
-ignore=duke
-
-[checks "committer"]
-role=committer
-
-[checks "issues"]
-pattern=^([124-8][0-9]{6}): (\S.*)$
-
-[checks "problemlists"]
-dirs=test/jdk|test/langtools|test/lib-test|test/hotspot/jtreg|test/jaxp
-
-[checks "copyright"]
-files=^(?!LICENSE|license.txt|.*.bin|.*.gif|.*.jpg|.*.png|.*.icon|.*.tiff|.*.dat|.*.patch|.*.wav|.*.class|.*-header|.*.jar).*
-oracle_locator=.*Copyright (c)(.*)Oracle and/or its affiliates. All rights reserved.
-oracle_validator=.*Copyright (c) (\d{4})(?:, (\d{4}))?, Oracle and/or its affiliates. All rights reserved.
->>>>>>> a637ccf2fea (8349851: RISC-V: Call VM leaf can use movptr2)
diff --git a/make/modules/java.base/Launcher.gmk b/make/modules/java.base/Launcher.gmk
remerge CONFLICT (content): Merge conflict in make/modules/java.base/Launcher.gmk
index 5d4f2da27b1..d3baea141ab 100644
--- a/make/modules/java.base/Launcher.gmk
+++ b/make/modules/java.base/Launcher.gmk
@@ -104,7 +104,6 @@ ifeq ($(call isTargetOsType, unix), true)
endif
################################################################################
-<<<<<<< 203c311bb3a (Merge with jdk-25+9)
ifeq ($(OPENJDK_TARGET_OS), linux)
$(eval $(call SetupJdkExecutable, BUILD_CRIUENGINE, \
@@ -162,5 +161,3 @@ $(CRIU_CRAC_BIN) : $(USE_CRIU_CRAC)
endif
################################################################################
-=======
->>>>>>> a637ccf2fea (8349851: RISC-V: Call VM leaf can use movptr2)
diff --git a/make/modules/java.base/Lib.gmk b/make/modules/java.base/Lib.gmk
remerge CONFLICT (content): Merge conflict in make/modules/java.base/Lib.gmk
index 32638089365..d964c56871f 100644
--- a/make/modules/java.base/Lib.gmk
+++ b/make/modules/java.base/Lib.gmk
@@ -201,7 +201,6 @@ ifeq ($(call isTargetOs, linux)+$(call isTargetCpu, x86_64)+$(INCLUDE_COMPILER2)
endif
################################################################################
-<<<<<<< 203c311bb3a (Merge with jdk-25+9)
# Build checkpoint/restore exec library
################################################################################
@@ -215,5 +214,3 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBCREXEC, \
LDFLAGS := $(LDFLAGS_JDKLIB), \
))
TARGETS += $(BUILD_LIBCREXEC)
-=======
->>>>>>> a637ccf2fea (8349851: RISC-V: Call VM leaf can use movptr2)
</details>
-------------
Commit messages:
- Merge with jdk-25+10
- 8349851: RISC-V: Call VM leaf can use movptr2
- 8349787: java/lang/Thread/virtual/ThreadPollOnYield.java#default passes unexpectedly without libVThreadPinner.so
- 8344802: Crash in StubRoutines::verify_mxcsr with -XX:+EnableX86ECoreOpts and -Xcheck:jni
- 6562489: Font-Renderer should ignore invisible characters \u2062 and \u2063
- 8349934: Wrong file regex for copyright header format check in .jcheck/conf
- 8349571: Remove JavaThreadFactory interface from SA
- 8349684: Remove SA core file tests from problem list for macosx-x64
- 8348427: DeferredLintHandler API should use JCTree instead of DiagnosticPosition
- 8249831: Test sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java is marked with @ignore
- ... and 537 more: https://git.openjdk.org/crac/compare/ed399705...2aac32e5
The webrevs contain the adjustments done while merging with regards to each parent branch:
- crac: https://webrevs.openjdk.org/?repo=crac&pr=231&range=00.0
- jdk:jdk-25+10: https://webrevs.openjdk.org/?repo=crac&pr=231&range=00.1
Changes: https://git.openjdk.org/crac/pull/231/files
Stats: 205176 lines in 4867 files changed: 97022 ins; 87259 del; 20895 mod
Patch: https://git.openjdk.org/crac/pull/231.diff
Fetch: git fetch https://git.openjdk.org/crac.git pull/231/head:pull/231
PR: https://git.openjdk.org/crac/pull/231
More information about the crac-dev
mailing list