Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
Version 5.0.3
-
None
-
None
Description
The following code in /xmlbeans/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java can leak memory:
private class FileVisitor extends SimpleFileVisitor<Path> {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (javaMatcher.matches(file)) {
if (roots.stream().noneMatch(file::startsWith)) {
getRoot(file).ifPresent(r -> {
getSolver().add(new JavaParserTypeSolver(r, getParserConfiguration()));
roots.add(r);
});
because the paths in roots are absolute paths at this point, but file may be a relative path. This means that the file::startsWith test always fails, and IIUC this means that a new JavaParserTypeSolver instance is created for every Java source file, for every interface extension. These instances can never be garbage-collected.
For the project that I am currently trying to migrate from XMLBeans 3.1.0, I can run the schema compiler with -Xmx50g on a large memory server, and the heap still fills up in a few minutes.
In my hands, the following patch fixes the problem and gives a huge performance boost as well:
index 25003989..a19d495a 100644
--- a/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java
+++ b/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java
@@ -105,7 +105,7 @@ class ChildSolverCollectionStrategy implements CollectionStrategy {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (javaMatcher.matches(file)) {
- if (roots.stream().noneMatch(file::startsWith)) {
+ if (roots.stream().map(Path::toAbsolutePath).noneMatch(file.toAbsolutePath()::startsWith)) {
getRoot(file).ifPresent(r -> {
getSolver().add(new JavaParserTypeSolver(r, getParserConfiguration()));
roots.add(r);
The difference can also be seen by giving absolute paths, not relative paths, for the directories containing Java source files to the schema compiler.