Quantcast

question about symlink handling

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

question about symlink handling

Liam Miller-Cushon
This is somewhat related to: http://mail.openjdk.java.net/pipermail/compiler-dev/2016-November/010544.html

Starting in 9, javac uses canonical paths in isNameCompatible. So if a source file is a symlink, it reports errors if the symlink target (rather than the user-supplied path) doesn't match the public class name:

$ echo 'public class Hello {}' > SOURCE
$ ln -s SOURCE Hello.java
$ javac Hello.java
Hello.java:1: error: class Hello is public, should be declared in a file named Hello.java

The diagnostic is confusing because it still uses the user-supplied path, but I'm more interested in whether isNameCompatible should be using canonical paths.

For what it's worth I prefer the previous behaviour, because our build system uses symlinks extensively and the symlink target is a hash of the content instead of a valid Java file name.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: question about symlink handling

Liam Miller-Cushon
I filed https://bugs.openjdk.java.net/browse/JDK-8178017 for this.

Would you consider taking a patch to restore the JDK 8 behaviour? The idea would be to use the userPath in SimpleFileObject#getShortName, and then use that definition of getShortName in getKind and isNameCompatibleWith.

On Wed, Dec 7, 2016 at 12:36 PM, Liam Miller-Cushon <[hidden email]> wrote:
This is somewhat related to: http://mail.openjdk.java.net/pipermail/compiler-dev/2016-November/010544.html

Starting in 9, javac uses canonical paths in isNameCompatible. So if a source file is a symlink, it reports errors if the symlink target (rather than the user-supplied path) doesn't match the public class name:

$ echo 'public class Hello {}' > SOURCE
$ ln -s SOURCE Hello.java
$ javac Hello.java
Hello.java:1: error: class Hello is public, should be declared in a file named Hello.java

The diagnostic is confusing because it still uses the user-supplied path, but I'm more interested in whether isNameCompatible should be using canonical paths.

For what it's worth I prefer the previous behaviour, because our build system uses symlinks extensively and the symlink target is a hash of the content instead of a valid Java file name.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: question about symlink handling

Jonathan Gibbons
I agree the error message is less than optimal. 

It is certainly the intent of the JavaFileManager API to use user-friendly names in diagnostics:  it would look really bad if all diagnostics used full/canonical path names, so we can't go that way.

It would seem somewhat strange to rely on canonical path names for part of the functionality of the file manager and not for others, but maybe it would be OK for isNameCompatible and getKind.  That being said, note the very long-standing behavior to use the canonical name on Windows, allowing a Windows user to use a command line "JAVAC HELLO.JAVA" and have it work. (Not that I advocate such usage!)

It seems a somewhat specialized use case to be storing source code in files with non-standard file names.  That's not to say you shouldn't but it seems like that is a different sort of "host system" than the one currently supported by javac. How easy would it be for you to provide and use a different file manager that has the semantics suitable for your environment?

Given the existing "fault tolerant" code in PathFileObject.isNameCompatible, how practical would it be to override isNameCompatible in SimpleFileObject such that it first checks the userPath, and then rolls over to the default definition.   Ideally that first check should be as fault-tolerant as the existing checks, so there would be a small refactoring to be able to apply the same checks to both the userPath and the real path.  And, similar treatment for getKind().

-- Jon



On 04/03/2017 05:07 PM, Liam Miller-Cushon wrote:
I filed https://bugs.openjdk.java.net/browse/JDK-8178017 for this.

Would you consider taking a patch to restore the JDK 8 behaviour? The idea would be to use the userPath in SimpleFileObject#getShortName, and then use that definition of getShortName in getKind and isNameCompatibleWith.

On Wed, Dec 7, 2016 at 12:36 PM, Liam Miller-Cushon <[hidden email]> wrote:
This is somewhat related to: http://mail.openjdk.java.net/pipermail/compiler-dev/2016-November/010544.html

Starting in 9, javac uses canonical paths in isNameCompatible. So if a source file is a symlink, it reports errors if the symlink target (rather than the user-supplied path) doesn't match the public class name:

$ echo 'public class Hello {}' > SOURCE
$ ln -s SOURCE Hello.java
$ javac Hello.java
Hello.java:1: error: class Hello is public, should be declared in a file named Hello.java

The diagnostic is confusing because it still uses the user-supplied path, but I'm more interested in whether isNameCompatible should be using canonical paths.

For what it's worth I prefer the previous behaviour, because our build system uses symlinks extensively and the symlink target is a hash of the content instead of a valid Java file name.


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: question about symlink handling

Liam Miller-Cushon
On Mon, Apr 3, 2017 at 5:54 PM, Jonathan Gibbons <[hidden email]> wrote:
It seems a somewhat specialized use case to be storing source code in files with non-standard file names.  That's not to say you shouldn't but it seems like that is a different sort of "host system" than the one currently supported by javac. How easy would it be for you to provide and use a different file manager that has the semantics suitable for your environment?

Agreed, the environment where I noticed this is unusual, and if it wasn't for the issue with the diagnostic I might not have reported it. I'll think about whether there's a cleaner way to hide those details from javac. For the most part it's a normal filesystem with a lot of symlinks, so it'd be nice to continue to use as much of the JavacFileManager implementation as possible.
 
Given the existing "fault tolerant" code in PathFileObject.isNameCompatible, how practical would it be to override isNameCompatible in SimpleFileObject such that it first checks the userPath, and then rolls over to the default definition.   Ideally that first check should be as fault-tolerant as the existing checks, so there would be a small refactoring to be able to apply the same checks to both the userPath and the real path.

That sounds practical to me.
 
And, similar treatment for getKind().

Changing the handling of kind in isNameCompatible is straightforward, but making all uses of getKind() fault-tolerant seems harder. For example, JavacTool uses getKind() to validate that the source file objects are actually sources.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: question about symlink handling

Jonathan Gibbons



On 4/3/17 6:41 PM, Liam Miller-Cushon wrote:
On Mon, Apr 3, 2017 at 5:54 PM, Jonathan Gibbons <[hidden email]> wrote:
It seems a somewhat specialized use case to be storing source code in files with non-standard file names.  That's not to say you shouldn't but it seems like that is a different sort of "host system" than the one currently supported by javac. How easy would it be for you to provide and use a different file manager that has the semantics suitable for your environment?

Agreed, the environment where I noticed this is unusual, and if it wasn't for the issue with the diagnostic I might not have reported it. I'll think about whether there's a cleaner way to hide those details from javac. For the most part it's a normal filesystem with a lot of symlinks, so it'd be nice to continue to use as much of the JavacFileManager implementation as possible.
 
Given the existing "fault tolerant" code in PathFileObject.isNameCompatible, how practical would it be to override isNameCompatible in SimpleFileObject such that it first checks the userPath, and then rolls over to the default definition.   Ideally that first check should be as fault-tolerant as the existing checks, so there would be a small refactoring to be able to apply the same checks to both the userPath and the real path.

That sounds practical to me.
 
And, similar treatment for getKind().

Changing the handling of kind in isNameCompatible is straightforward, but making all uses of getKind() fault-tolerant seems harder. For example, JavacTool uses getKind() to validate that the source file objects are actually sources.

Maybe you're right that we can't do too much with getKind. I'll take another look at the code tomorrow. Mostly, I was wanting to come up with a definition that was "the best of both worlds" -- user path, and canonical path, supporting those folk on Windows who may be used to case-equivalence for user paths, and those folk who apparently use unadorned cryptographic hashes for their canonical file names!

-- Jon
Loading...