JDK-5085227 : getCanonicalPath on link returns invalid result
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 1.4.2,7u25
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2004-08-10
  • Updated: 2014-12-04
  • Resolved: 2014-12-04
Related Reports
Duplicate :  
Description

Name: rmT116609			Date: 08/10/2004


FULL PRODUCT VERSION :
java version "1.4.2_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05)
Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux totoro 2.4.19-4GB #1 Fri Apr 2 19:59:17 UTC 2004 i686 unknown

A DESCRIPTION OF THE PROBLEM :
getCanonicalPath on a link returns the path to the link instead of the link's target if getCanonicalPath was called before the link is actually created.

If you comment out line 23 of the test code the correct path is returned.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Compile the attached unit test
2) Execute the unit test (e.g. java -classpath .:junit.jar  junit.textui.TestRunner LinkTest)


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The unit test should succeed.
ACTUAL -
The unit test fails.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
.F
Time: 0.164
There was 1 failure:
1) testGetCanonicalPath(LinkTest)junit.framework.ComparisonFailure: expected:<..
.target> but was:<...link>
        at LinkTest.testGetCanonicalPath(LinkTest.java:48)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

FAILURES!!!
Tests run: 1,  Failures: 1,  Errors: 0

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.*;
import junit.framework.*;

public class LinkTest
    extends TestCase
{
    private File linkFile, targetFile;

    public LinkTest()
    {
        super("LinkTest");
    }

    public void setUp()
        throws Exception
    {
        String dir = System.getProperty("user.home");
            
        linkFile = new File(dir, "link");
        targetFile = new File(dir, "target");

        // This line seems to be the cause of the problem.
        linkFile.getCanonicalPath();

        assertTrue(targetFile.createNewFile());
            
        String[] cmd = {
            "ln",
            "-s",
            targetFile.getAbsolutePath(),
            linkFile.getAbsolutePath(),
        };
        
        Process p = Runtime.getRuntime().exec(cmd);

        p.waitFor();
    }
    
    public void tearDown()
    {
        linkFile.delete();
        targetFile.delete();
    }

    public void testGetCanonicalPath()
        throws IOException
    {
        assertEquals(targetFile.getAbsolutePath(), linkFile.getCanonicalPath());
    }
}

---------- END SOURCE ----------
(Incident Review ID: 284849) 
======================================================================

Comments
JDK-7066948
04-12-2014

Thanks for correction Alan, I will add the links to 7066948/17001789.
03-07-2013

This bug seems to be re-open in error. Please see JDK-7066948 for the bug that requests that the canonicalization cache be disabled by default (which we would all like to do, it's just that it requires re-checking the performance and probably something for a major release, not a minor release).
03-07-2013

we have an internal request to reopen the bug.
03-07-2013

EVALUATION Perhaps getCanonicalPath cannot do as much caching as is done currently, in the face of a dynamically changing filesystem. ###@###.### I have reproduced the problem on Linux and Solaris. It appears to be due to this change: 2004-08-11D 1.11 02/10/01 17:11:13 kbr 12 11 00048/00001/00180 MRs: COMMENTS: 4747353 Cache filename canonicalization results Added time-expiring caches for canonicalization results; both full filenames as well as directory prefixes inside java.home ###@###.### 2004-08-16 This behavior is documented in the release notes and was introduced to increase the performance of getCanonicalPath(). The end result is similar to the behavior of NFS, where certain file system changes will become visible to the application in a short period of time, but not instantaneously. The caches can be disabled on a per-application basis by specifying the system property -Dsun.io.useCanonCaches=false. Disabling them globally will significantly impact startup performance, and since this behavior does not appear to be a problem for most users this bug is being closed as "will not fix". ###@###.### 2005-1-13 23:59:30 GMT
13-01-2005