RFR(S): 8188122: Path length limits on Windows leads to obscure class loading failures

Calvin Cheung calvin.cheung at oracle.com
Thu Nov 9 17:23:47 UTC 2017


Hi Thomas,

On 11/8/17, 10:40 PM, Thomas Stüfe wrote:
> Hi Calvin,
>
> On Wed, Nov 8, 2017 at 6:27 PM, Calvin Cheung 
> <calvin.cheung at oracle.com <mailto:calvin.cheung at oracle.com>> wrote:
>
>
>
>     On 11/7/17, 6:12 AM, Thomas Stüfe wrote:
>>     Hi Calvin,
>>
>>     On Wed, Nov 1, 2017 at 8:07 PM, Calvin Cheung
>>     <calvin.cheung at oracle.com <mailto:calvin.cheung at oracle.com>> wrote:
>>
>>
>>
>>         On 10/27/17, 12:55 AM, Thomas Stüfe wrote:
>>>         Hi Calvin,
>>>
>>>         On Fri, Oct 27, 2017 at 2:03 AM, Calvin Cheung
>>>         <calvin.cheung at oracle.com <mailto:calvin.cheung at oracle.com>>
>>>         wrote:
>>>
>>>             Hi Thomas,
>>>
>>>             On 10/25/17, 11:54 PM, Thomas Stüfe wrote:
>>>
>>>                 Hi Calvin,
>>>
>>>                 this is a worthwhile addition, thank you for your work!
>>>
>>>             Thanks for your review.
>>>
>>>
>>>         Thanks for your work :)
>>>
>>>         First off, there is another issue in
>>>         file_attribute_data_to_stat(). We actually had this issue
>>>         before, but your work uncovered it:
>>>
>>>         According to POSIX
>>>         (http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/stat.h.html
>>>         <http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/stat.h.html>)
>>>         and every unix manpage I looked at (solaris, linux, aix..),
>>>         st_ctime is not the file creation time but the last time
>>>         file status was changed. Only Microsoft gets this wrong in
>>>         their posix layer, its stat() function returns
>>>          (https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx
>>>         <https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx>)
>>>         creation time in st_ctime.
>>>
>>>         But as os::stat() is a platform independent layer, I'd say
>>>         we should behave the same on all platforms, and that would
>>>         be the Posix way.
>>>
>>>         I did not find any code calling os::stat() and using
>>>         st_ctime, so this is still save to change for windows. (Note
>>>         that I found that perfMemory_xxx.cpp uses plain OS ::stat
>>>         and misuses ctime as "creation time" - I opened a bug for
>>>         that (https://bugs.openjdk.java.net/browse/JDK-8190260
>>>         <https://bugs.openjdk.java.net/browse/JDK-8190260> - but
>>>         that does not affect us, as they do not call os::stat()).
>>>
>>>         There is one more complication: in os::stat() we use plain
>>>         ::stat() in the single byte case.:
>>>
>>>         *+ if (strlen(path) < MAX_PATH) {*
>>>         *+     ret = ::stat(pathbuf, sbuf);*
>>>         *+   } else {*
>>>         *
>>>         *
>>>         But ::stat() on Windows is broken, as I wrote above. We
>>>         should not use it, especially not if we change the meaing of
>>>         st_ctime in the double byte path.
>>>
>>>         My suggestion would be to just always call
>>>         GetFileAttributes(), also for the single byte path. A very
>>>         simple solution would be to just always go the double byte
>>>         path with UNC translation, regardless of the path
>>>         length. Or, if you are worried about performance, for paths
>>>         shorter than MAX_PATH we use GetFileAttributesA(), for
>>>         longer paths GetFileAttributesW with UNC translation. In
>>>         both cases you get a WIN32_FILE_ATTRIBUTE_DATA which you can
>>>         feed tp your  file_attribute_data_to_stat() routine and have
>>>         the struct stat you return be always consistent.
>>         I ran into an issue with the dwFileAttributes value for a jar
>>         file. On Windows Server O/S, the value is set to 0x2020 which
>>         is (FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
>>         FILE_ATTRIBUTE_ARCHIVE) but on a desktop O/S like Windows 7,
>>         it is set to 0x0020 which is just FILE_ATTRIBUTE_ARCHIVE.
>>         I've fixed it in file_attribute_data_to_stat().
>>
>>
>>     Oh.. :( good catch! But that opens a new can of worms I did not
>>     see before:
>>
>>     FILE_ATTRIBUTE_NORMAL is documented as "A file that does not have
>>     other attributes set. This attribute is valid only when used
>>     alone." In addition to this flag, we have a multitude of things
>>     like FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ENCRYPTED,
>>     FILE_ATTRIBUTE_READONLY ... etc, all cases where we assume this
>>     is a normal file in Unix terminology and where we would expect
>>     os::stat to return S_IFREG, but where according to the msdn doc
>>     FILE_ATTRIBUTE_NORMAL is not set.
>>
>>     Looking at what others do in this scenario (Looked at mingw
>>     sources and at ReactOS - I am not posting any source code here
>>     for legal reasons but feel free to look for yourself), the usual
>>     way to translate WIN32_FILE_ATTRIBUTES to struct stat seems to be:
>>     "if FILE_ATTRIBUTE_DIRECTORY then set S_IFDIR else S_IFREG" (so,
>>     no dependency on FILE_ATTRIBUTE_NORMAL).
>     This makes sense but I ran into similar problem as before - the
>     dwFileAttributes has a different value on a windows server O/S vs
>     desktop O/S. So I need to do the check as follows:
>
>     +   // A directory has the dwFileAttributes value of 0x2010 which is
>     +   // (FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_ARCHIVE)
>     +   // on Windows Server O/S but the value is 0x0010 on Windows desktop O/S
>     +   // such as Windows 7.
>     +   if ((file_data.dwFileAttributes&  FILE_ATTRIBUTE_DIRECTORY) != 0) {
>     +     sbuf->st_mode |= S_IFDIR;
>     +   } else {
>     +     sbuf->st_mode |= S_IFREG;
>     +   }
>
> I scratched my head a bit about the comment till I understood that you 
> mean "if FILE_ATTRIBUTE_DIRECTORY bit is set it is a directory 
> regardless of which other flags are set" instead of "if 
> flags==FILE_ATTRIBUTE_DIRECTORY it is a directory". Sure, I guess my 
> comment above was sloppy, but this was what I meant. I am not even 
> sure the comment is needed, this is quite self-explaining.
I've noticed a typo in the above comment:
+   // (FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_ARCHIVE)

FILE_ATTRIBUTE_ARCHIVE should be FILE_ATTRIBUTE_DIRECTORY

I'll correct it before push.

>
>     updated webrev:
>     http://cr.openjdk.java.net/~ccheung/8188122/webrev.04/
>     <http://cr.openjdk.java.net/%7Eccheung/8188122/webrev.04/>
>
>
> I am fine with all the changes now. Thank you for your work and patience.
Thanks for your discussions and review.

thanks,
Calvin
>
> Kind Regards, Thomas
>
>
>
>
>     Diff from webrev.03:
>
>     < --- old/src/hotspot/os/windows/os_windows.cpp 2017-11-08
>     08:50:40.170786397 -0800
>     < +++ new/src/hotspot/os/windows/os_windows.cpp 2017-11-08
>     08:50:39.803751877 -0800
>     < @@ -4060,41 +4060,119 @@
>     ---
>     > --- old/src/hotspot/os/windows/os_windows.cpp 2017-11-01
>     09:40:13.657460425 -0700
>     > +++ new/src/hotspot/os/windows/os_windows.cpp 2017-11-01
>     09:40:13.261423192 -0700
>     > @@ -4060,41 +4060,121 @@
>     25,29c25
>     < +  // A directory has the dwFileAttributes value of 0x2010 which is
>     < +  // (FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_ARCHIVE)
>     < +  // on Windows Server O/S but the value is 0x0010 on Windows
>     desktop O/S
>     < +  // such as Windows 7.
>     < +  if ((file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
>     != 0) {
>     ---
>     > +  if (file_data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {
>     31c27,33
>     < +  } else {
>     ---
>     > +  }
>     > +  if ((file_data.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
>     > +      // an archive file such as a jar file has the
>     dwFileAttributes value of
>     > +      // 0x2020 (FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
>     FILE_ATTRIBUTE_ARCHIVE)
>     > +      // on Windows Server O/S but the value is 0x0020 on
>     > +      // Windows desktop O/S such as Windows 7.
>     > +      ((file_data.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) !=
>     0)) {
>
>>
>>     I wonder about other special cases which should work too:
>>     - read-only files should be S_IFREG and !S_IWRITE,
>     For a read-only system file under the user's home dir.
>
>     st_mode & 0xFF00 = 0x8100 = S_IFREG | S_IREAD
>     dwFileAttributes = 39 = (FILE_ATTRIBUTE_ARCHIVE |
>     FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM |
>     FILE_ATTRIBUTE_READONLY)
>>     read-only directories should be S_IFDIR and !S_IWRITE.
>     I've tried the C:\progra~1 dir.
>
>     st_mode & 0xFF00 = 0x4100 = S_IFDIR | S_IREAD
>     dwFileAttributes = 17 = (FILE_ATTRIBUTE_DIRECTORY |
>     FILE_ATTRIBUTE_READONLY)
>>     - We should tread the device root ("C:\") as a directory (so,
>>     os::stat("c:\") should return S_IFDIR). Does this work?
>     This one works too.
>
>     st_mode & 0xFF00 = 0x4100 = S_IFDIR | S_IREAD
>     dwFileAttributes = 22 = (FILE_ATTRIBUTE_DIRECTORY |
>     FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)
>>
>>         I've also used GetTickCounts() to measure the performance of
>>         ::stat() vs GetFileAttributesA() plus
>>         file_attribute_data_to_stat(). There's no difference at the
>>         ms resolution. Using the high-resolution timestamp
>>         (https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx)
>>         <https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408%28v=vs.85%29.aspx%29>,
>>         it doesn't show much difference.
>>
>>
>>     stat() seems to be implemented using FindFirstFile() (see crt
>>     sources if you can), and we call GetFileAttributesA(), so I do
>>     not think this differs much.
>     Yes, I saw the same in my Visual Studio installation.
>
>     thanks,
>     Calvin
>
>>>
>>>         But onward:
>>>
>>>
>>>
>>>                 =========================
>>>
>>>                 src/hotspot/os/windows/os_windows.cpp
>>>
>>>                 Could you please use wchar_t instead of WCHAR?
>>>
>>>             Fixed.
>>>
>>>
>>>                 ---------------
>>>                 in os::stat():
>>>
>>>                 This cumbersome malloc/strcpy sequence:
>>>
>>>                 !   size_t path_len = strlen(path) + 1;
>>>                 +   char* pathbuf = (char*)os::malloc(path_len *
>>>                 sizeof(char), mtInternal);
>>>                 +   if (pathbuf == NULL) {
>>>                 +     errno = ENOMEM;
>>>                       return -1;
>>>                     }
>>>                     os::native_path(strcpy(pathbuf, path));
>>>
>>>                  can be reduced to a simple strdup:
>>>
>>>                 char* pathbuf = os::strdup(path, mtInternal);
>>>                 if (pathbuf == NULL) {
>>>                   errno = ENOMEM;
>>>                   return -1;
>>>                 }
>>>                 os::native_path(pathbuf);
>>>
>>>                 This also would separate strcpy() from
>>>                 os::native_path() which is a bit unreadable.
>>>
>>>             I've made the change.
>>>
>>>
>>>                 --------------------
>>>
>>>                 The single-byte path (strdup, ::stat()), together
>>>                 with its free(), can be moved inside the
>>>                 (strlen(path) < MAX_PATH) condition. os::native_path
>>>                 will not change the path length (it better not, as
>>>                 it operates on the input buffer). That avoids 
>>>                 having two allocations on the doublebyte path.
>>>
>>>
>>>             os::native_path() converts a path like C:\\\\somedir to
>>>             C:\\somedir
>>>             So I'll need the converted path in the wchar_t case too.
>>>             The freeing of the pathbuf is being done at the end of
>>>             the function or in the middle of the wchar_t case if
>>>             there's an error.
>>>
>>>
>>>         Oh, you are right,of course. I missed that it this is needed
>>>         for both paths.
>>>
>>>
>>>
>>>                 -----------------------
>>>
>>>                 But seeing that translation to UNC paths is
>>>                 something we might want more often, I would combine
>>>                 allocation and UNC prefix adding to one function
>>>                 like this, to avoid the memove and increase reusability:
>>>
>>>                 // Creates an unc path from a single byte path.
>>>                 Return buffer is allocated in C heap and needs to be
>>>                 freed by caller. Returns NULL on error.
>>>                 static whchar_t* create_unc_path(const char* s) {
>>>                   - does s start with \\?\ ?
>>>                 - yes:
>>>                             - os::malloc(strlen(s) + 1) and mbstowcs_s
>>>                         - no:
>>>                             - os::malloc(strlen(s) + 1 + 4),
>>>                 mbstowcs_s to fourth position in string, prefix with
>>>                 L"\\?\"
>>>                 }
>>>
>>>
>>>             I also include the case for adding  L"\\\\?\\UNC\0" at
>>>             the beginning to be consistent with
>>>             libjava/canonicalize_md.c. 
>>>
>>>
>>>                 We also need error checking to mbstowcs_s.
>>>
>>>             I've added assert like the following after the call:
>>>
>>>             assert(converted_chars == path_len, "sanity");
>>>
>>>
>>>
>>>         create_unc_path() :
>>>
>>>         - could you convert the /**/ to // comments, please?
>>         Fixed.
>>
>>
>>     thanks.
>>
>>
>>>
>>>         - not sure about the assert after mbstowcs_s: if we happen
>>>         to encounter an invalid multibyte character, function will
>>>         fail and return an error:
>>>
>>>         https://msdn.microsoft.com/en-us/library/eyktyxsx.aspx
>>>         <https://msdn.microsoft.com/en-us/library/eyktyxsx.aspx>
>>>         "If mbstowcs_s encounters an invalid multibyte character, it
>>>         puts 0 in *``pReturnValue, sets the destination buffer to an
>>>         empty string, sets errno to EILSEQ, and returns EILSEQ."
>>         I've changed create_unc_path() so that the caller will get
>>         the errno and removed the assert.
>>
>>         static wchar_t* create_unc_path(const char* path, errno_t &err)
>>
>>
>>     Okay, works for me.
>>
>>
>>>
>>>          As this is dependent on user data, we should not assert,
>>>         but handle the return code of mbstowcs_s gracefully. Same
>>>         goes for libjava/canonicalize_md.c.
>>>
>>>         - Here: ::mbstowcs_s(&converted_chars, &wpath[7], path_len +
>>>         7, path, path_len);
>>>         third parameter is wrong, as we hand in an offset into the
>>>         buffer, we must decrement the buffer size by this offset, so
>>>         correct would be path_len +7 - 7 or just path_len.
>>>
>>>         - Same error below: + ::mbstowcs_s(&converted_chars,
>>>         &wpath[4], path_len + 4, path, path_len);
>>         Fixed in both places.
>>
>>
>>     Okay.
>>
>>
>>>
>>>
>>>                 Just for cleanliness, I would then wrap deallocation
>>>                 into an own function.
>>>
>>>                 static viud destroy_unc_path(whchar_t* s) {
>>>                 os::free(s); }
>>>
>>>             I've added the destroy function.
>>>
>>>
>>>                 These two functions could be candidates of putting
>>>                 into os::win32 namespace, as this form of ANSI->UNC
>>>                 path translation is quite common - whoever wants to
>>>                 use the xxxxW() functions must do this.
>>>
>>>             I'm leaving them in os_windows.cpp since they're being
>>>             used only within that file.
>>>
>>>
>>>         Fine by me.
>>>
>>>
>>>
>>>                 -----------------------
>>>
>>>                 FindFirstFileW:
>>>
>>>                 I am pretty sure that you can achieve the same
>>>                 result with GetFileAttributesExW(). It also returns
>>>                 WIN32_FIND_DATAW.
>>>
>>>             It actually returns WIN32_FILE_ATTRIBUTE_DATA and is
>>>             very similar to WIN32_FIND_DATAW.
>>>
>>>
>>>                 It is way more straightforward to use than
>>>                 FindFirstFileW, as it does not require you to write
>>>                 a callback hook.
>>>
>>>             I've switched to using GetFileAttributesExW().
>>>
>>>
>>>         Thank you, this is way more readable.
>>>         Another issue: do we still need the fix for 6539723 if we
>>>         switch from stat() to GetFileAttributesExW()? This fix looks
>>>         important, but the comment
>>>         indicates that it could break things if the original bug is
>>>         not present.
>>>
>>>         Btw, this is another strong argument for scrapping ::stat()
>>>         altogether on all code paths, not only for long input paths,
>>>         because stat() and GetFileAttributesExW() may behave
>>>         differently. So it would be good to use the same API on all
>>>         code paths, in order to get the best test coverage.
>>         For this round of change, I'm using
>>         GetFileAttributesEx[A|W]() for both code paths.
>>
>>         webrev:
>>         http://cr.openjdk.java.net/~ccheung/8188122/webrev.03/
>>         <http://cr.openjdk.java.net/%7Eccheung/8188122/webrev.03/>
>>
>>         thanks,
>>         Calvin
>>
>>
>>     Okay, all good apart from the issues mentioned above. Thanks for
>>     your work!
>>
>>     Best Regards, Thomas
>>
>>
>>
>>>
>>>
>>>
>>>                 -------
>>>
>>>                 eval_find_data(): This is more of a generic helper
>>>                 function, could you rename this to something
>>>                 clearer, e.g. make_double_word() ?
>>>
>>>             Ok. I've renamed it.
>>>
>>>
>>>                 Also, setup_stat(), could this be renamed more
>>>                 clearly to something like WIN32_FIND_DATA_to_stat?
>>>                 or lowercase if this bothers you :)
>>>
>>>             I'm naming the function as file_attribute_data_to_stat()
>>>             to match with the data structure name.
>>>
>>>
>>>         Thanks for taking my suggestions.
>>>
>>>
>>>
>>>                 ==================================
>>>                 src/hotspot/share/classfile/classLoader.cpp
>>>
>>>                 In ClassPathDirEntry::open_stream(), I would feel
>>>                 better if we were asserting _dir and name to be !=
>>>                 NULL before feeding it to strlen.
>>>
>>>             I've added an assert statement.
>>>
>>>
>>>                 ===================
>>>
>>>             Here's an updated webrev:
>>>             http://cr.openjdk.java.net/~ccheung/8188122/webrev.02/
>>>             <http://cr.openjdk.java.net/%7Eccheung/8188122/webrev.02/>
>>>
>>>
>>>         Thanks!
>>>
>>>         Thomas
>>>
>>>             thanks,
>>>             Calvin
>>>
>>>
>>>                 Thanks!
>>>
>>>                 Thomas
>>>
>>>
>>>
>>>
>>>
>>>
>>>                 On Wed, Oct 25, 2017 at 9:48 PM, Calvin Cheung
>>>                 <calvin.cheung at oracle.com
>>>                 <mailto:calvin.cheung at oracle.com>
>>>                 <mailto:calvin.cheung at oracle.com
>>>                 <mailto:calvin.cheung at oracle.com>>> wrote:
>>>
>>>                     I've reworked this fix by using the Unicode
>>>                 version of open
>>>                     (wopen) to handle path name longer than max path
>>>                 with the path
>>>                     prefixed to indicate an extended length path as
>>>                 described in [1].
>>>
>>>                     The Unicode version of stat (wstat) doesn't work
>>>                 well with long
>>>                     path [2]. So FindFirstFileW will be used.The data in
>>>                     WIN32_FIND_DATA returned from FindFirstFileW
>>>                 needs to be
>>>                     transferred to the stat structure since the
>>>                 caller expects a
>>>                     return stat structure and other platforms return
>>>                 a stat structure.
>>>
>>>                     In classLoader.cpp, calculate the size of buffer
>>>                 required instead
>>>                     of limiting it to JVM_MAXPATHLEN.
>>>                     In os_windows.cpp, dynamically allocate buffers
>>>                 in os::open and
>>>                     os::stat.
>>>
>>>                     updated webrev:
>>>                 http://cr.openjdk.java.net/~ccheung/8188122/webrev.01/
>>>                 <http://cr.openjdk.java.net/%7Eccheung/8188122/webrev.01/>
>>>                 <http://cr.openjdk.java.net/%7Eccheung/8188122/webrev.01/
>>>                 <http://cr.openjdk.java.net/%7Eccheung/8188122/webrev.01/>>
>>>
>>>                     It passed hs-tier2 testing using mach5.
>>>
>>>                     thanks,
>>>                     Calvin
>>>
>>>                     [1]
>>>                 https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#MAX_PATH
>>>                 <https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx#MAX_PATH>
>>>                 <https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx#MAX_PATH
>>>                 <https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx#MAX_PATH>>
>>>
>>>                     [2]
>>>                 https://social.msdn.microsoft.com/Forums/vstudio/en-US/3c093ea9-f0aa-446d-b648-2dabe8480430/stat-and-long-names?forum=vcgeneral
>>>                 <https://social.msdn.microsoft.com/Forums/vstudio/en-US/3c093ea9-f0aa-446d-b648-2dabe8480430/stat-and-long-names?forum=vcgeneral>
>>>                 <https://social.msdn.microsoft.com/Forums/vstudio/en-US/3c093ea9-f0aa-446d-b648-2dabe8480430/stat-and-long-names?forum=vcgeneral
>>>                 <https://social.msdn.microsoft.com/Forums/vstudio/en-US/3c093ea9-f0aa-446d-b648-2dabe8480430/stat-and-long-names?forum=vcgeneral>>
>>>
>>>
>>>
>>>                     On 10/16/17, 3:15 PM, Calvin Cheung wrote:
>>>
>>>                         JBS:
>>>                 https://bugs.openjdk.java.net/browse/JDK-8188122
>>>                 <https://bugs.openjdk.java.net/browse/JDK-8188122>
>>>                 <https://bugs.openjdk.java.net/browse/JDK-8188122
>>>                 <https://bugs.openjdk.java.net/browse/JDK-8188122>>
>>>
>>>                         Adding a warning message if the full path or
>>>                 the directory
>>>                         length exceeds MAX_PATH on windows.
>>>
>>>                         Example warning messages.
>>>
>>>                         1) The full path exceeds MAX_PATH:
>>>
>>>                         Java HotSpot(TM) 64-Bit Server VM warning:
>>>                 construct full path
>>>                         name failed: total length 270 exceeds max
>>>                 length of 260
>>>                             dir
>>>                        
>>>                 T:\\testoutput\\jtreg\\JTwork\\classes\\2\\runtime\\LoadClass\\LongPath.d\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>                         length 259
>>>                             name Hello.class length 11
>>>
>>>                         2) The directory path exceeds MAX_PATH:
>>>
>>>                         Java HotSpot(TM) 64-Bit Server VM warning:
>>>                 os::stat failed:
>>>                         path length 265 exceeds max length 260
>>>                             path
>>>                        
>>>                 T:\\testoutput\\jtreg\\JTwork\\classes\\2\\runtime\\LoadClass\\LongPath.d\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\xxxxx
>>>
>>>                         webrev:
>>>                 http://cr.openjdk.java.net/~ccheung/8188122/webrev.00/
>>>                 <http://cr.openjdk.java.net/%7Eccheung/8188122/webrev.00/>
>>>                 <http://cr.openjdk.java.net/%7Eccheung/8188122/webrev.00/
>>>                 <http://cr.openjdk.java.net/%7Eccheung/8188122/webrev.00/>>
>>>
>>>                         Testing:
>>>                             JPRT (including the new test)
>>>
>>>                         thanks,
>>>                         Calvin
>>>
>>>
>>>
>>
>


More information about the hotspot-runtime-dev mailing list