[ 
https://issues.apache.org/jira/browse/XMLBEANS-620?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17573100#comment-17573100
 ] 

Peter Keller edited comment on XMLBEANS-620 at 7/29/22 6:21 PM:
----------------------------------------------------------------

I have explored this test case with the following JDKs:

OpenJDK from [https://adoptium.net|https://adoptium.net/] :
 * jdk8u332-b09 works
 * jdk-11.0.16+8, jdk-17.0.4+8 both fail

OpenJ9 from 
[https://developer.ibm.com/languages/java/semeru-runtimes/downloads/] :
 * jdk8u332-b09, jdk-17.0.3+7 both fail

h1. Analysis

When [ChildSolverCollectionStrategy.collectAll() 
|https://github.com/apache/xmlbeans/blob/052e9f00d5af77c3338021b499678b933b3c476a/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java#L69]is
 called, the {{roots}} variable contains the following list of paths:

0. /path/to/xmlbeans-ie-root/proj1/src/main/java
1. /path/to/xmlbeans-ie-root/proj2/src/main/java
2. /path/to/xmlbeans-ie-root/java-src

The first time around the loop, {{root}} is simply assigned {{{}roots[0]{}}}. 
The second time around, 
[commonRoot(Path, 
Path)|https://github.com/apache/xmlbeans/blob/052e9f00d5af77c3338021b499678b933b3c476a/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java#L91]
 is called with {{root}} and {{roots[1]}} as arguments. After 
{{{}l1.retainAll(l2);{}}}, {{l1}} contains {{{}[path, to, xmlbeans-ie-root, 
src, main, java]{}}}(which does not correspond to an existing path on the 
filesystem). The relative path {{java}} is returned.

The third time around the loop, {{commonRoot( java, roots[2] )}} is called, and 
this is where the real problems start.

The relative Path corresponding to {{java}} is first [converted to an absolute 
Path|https://github.com/apache/xmlbeans/blob/052e9f00d5af77c3338021b499678b933b3c476a/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java#L93].
 I have found that in my scenario (invoking the XMLBeans Ant Task from Gradle) 
the absolute path that is used to resolve {{java}} depends on the JDK in use: 
it can be either (1) the current working directory, or (2) the Gradle home 
directory. In particular with case (2) there is no guarantee that any of the 
elements of the resulting absolute path are present in {{{}roots[2]{}}}. When 
this happens, {{commonRoot}} returns {{null}} and the schema compilation fails.

I have no experience with JavaParser, but my first thought is: is it really 
necessary to work out an absolute root for the ProjectRoot instance in this way 
at all? When the schema compilation does work, {{pr.toString()}} produces this:

{{ProjectRoot at xmlbeans-ie-root with [}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj3/java-src,}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj1/src/main/java,}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj2/src/main/java]}}

i.e. the root directory is relative, but the source roots are absolute. If the 
directory structure under {{proj3}} and the contents of {{build.gradle}} are 
changed to match {{proj1}} and {{{}proj2{}}}, the schema compilation always 
works, even with something like {{{}GRADLE_USER_HOME=/tmp/tmp.MQ3j1kdQ73{}}}, 
and {{pr.toString()}} looks like this:

{{ProjectRoot at java with [}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj1/src/main/java,}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj2/src/main/java,}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj3/src/main/java]}}

So JavaParser doesn't seem to care whether the project root makes any sense at 
all, as long as the source roots are absolute (at least under a Unix-like 
filesystem hierarchy, which always has {{/}} at the top: I don't know if the 
same applies to Windows).

Maybe the {{ProjectRoot}} instance should just be created with {{user.dir}} at 
the root? Also, the method of finding a common root using {{l1.retainAll(l2)}} 
is very fragile. It seems to me that it is only the tolerance of 
{{ProjectRoot}} that prevents this from becoming a major source of breakage.


was (Author: pakeller):
I have explored this test case with the following JDKs:

OpenJDK from [https://adoptium.net|https://adoptium.net/] :
 * jdk8u332-b09 works
 * jdk-11.0.16+8, jdk-17.0.4+8 both fail

OpenJ9 from 
[https://developer.ibm.com/languages/java/semeru-runtimes/downloads/] :
 * jdk8u332-b09, jdk-17.0.3+7 both fail

h1. Analysis

When [ChildSolverCollectionStrategy.collectAll() 
|https://github.com/apache/xmlbeans/blob/052e9f00d5af77c3338021b499678b933b3c476a/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java#L69]is
 called, the {{roots}} variable contains the following list of paths:

0. /path/to/xmlbeans-ie-root/proj1/src/main/java
1. /path/to/xmlbeans-ie-root/proj2/src/main/java
2. /path/to/xmlbeans-ie-root/java-src

The first time around the loop, {{root}} is simply assigned {{{}roots[0]{}}}. 
The second time around, 
[commonRoot(Path, 
Path)|https://github.com/apache/xmlbeans/blob/052e9f00d5af77c3338021b499678b933b3c476a/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java#L91]
 is called with {{root}} and {{roots[1]}} as arguments. After 
{{{}l1.retainAll(l2);{}}}, {{l1}} contains {{{}[path, to, xmlbeans-ie-root, 
src, main, java]{}}}(which does not correspond to an existing path on the 
filesystem). The relative path {{java}} is returned.

The third time around the loop, {{commonRoot( java, roots[2] )}} is called, and 
this is where the real problems start.

The relative Path corresponding to {{java}} is first [converted to an absolute 
Path|https://github.com/apache/xmlbeans/blob/052e9f00d5af77c3338021b499678b933b3c476a/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java#L93].
 I have found that in my scenario (invoking the XMLBeans Ant Task from Gradle) 
the absolute path that is used to resolve {{java}} depends on the JDK in use: 
it can be either (1) the current working directory, or (2) the Gradle home 
directory. In particular with case (2) there is no guarantee that any of the 
elements of the resulting absolute path are present in {{{}roots[2]{}}}. When 
this happens, {{commonRoot}} returns {{null}} and the schema compilation fails.

I have no experience with JavaParser, but my first thought is: is it really 
necessary to work out an absolute root for the ProjectRoot instance in this way 
at all? When the schema compilation does work, {{pr.toString()}} produces this:

{{ProjectRoot at xmlbeans-ie-root with [}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj3/java-src,}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj1/src/main/java,}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj2/src/main/java]}}

i.e. the root directory is relative, but the source roots are absolute. If the 
directory structure under {{proj3}} and the contents of {{build.gradle}} are 
changed to match {{proj1}} and {{{}proj2{}}}, the schema compilation always 
works, even with something like {{{}GRADLE_USER_HOME=/tmp/tmp.MQ3j1kdQ73{}}}, 
and {{pr.toString()}} looks like this:

{{ProjectRoot at java with [}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj1/src/main/java,}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj2/src/main/java],}}
{{SourceRoot at /path/to/xmlbeans-ie-root/proj3/src/main/java]}}

So JavaParser doesn't seem to care whether the project root makes any sense at 
all, as long as the source roots are absolute (at least under a Unix-like 
filesystem hierarchy, which always has {{/}} at the top: I don't know if the 
same applies to Windows).

Maybe the {{ProjectRoot}} instance should just be created with {{user.dir}} at 
the root? Also, the method of finding a common root using {{l1.retainAll(l2)}} 
is very fragile. It seems to me that it is only the tolerance of 
{{ProjectRoot}} that prevents this from becoming a major source of breakage.

> More robustness needed when setting up JavaParser's ProjectRoot
> ---------------------------------------------------------------
>
>                 Key: XMLBEANS-620
>                 URL: https://issues.apache.org/jira/browse/XMLBEANS-620
>             Project: XMLBeans
>          Issue Type: Bug
>          Components: Binding
>    Affects Versions: Version 5.1.0
>         Environment: Linux, OpenJDK, OpenJ9
>            Reporter: Peter Keller
>            Priority: Major
>         Attachments: xmlbeans-ie-root.tar
>
>
> I have encountered some fragility with the interface extension mechanism 
> around
> working out the root directory for JavaParser's
> [ProjectRoot|https://www.javadoc.io/doc/com.github.javaparser/javaparser-core/latest/com/github/javaparser/utils/ProjectRoot.html].
>  I
> will soon upload a test case that shows a scenario where the choice of JDK for
> the schema compilation makes the difference between succeeding, and failing
> with ["Unable to construct a common project root - giving 
> up."|https://github.com/apache/xmlbeans/blob/052e9f00d5af77c3338021b499678b933b3c476a/src/main/java/org/apache/xmlbeans/impl/config/ChildSolverCollectionStrategy.java#L83].
>  IMHO
> sorting this issue out needs more than simply getting a test case to work,
> rather some thought is needed about what is really required.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to