diff --git a/.hgtags b/.hgtags index abf4dd939ca..28f9ad5279c 100644 --- a/.hgtags +++ b/.hgtags @@ -375,3 +375,4 @@ e8373543a3f0f60589b7d72b1f9b172721124caf jdk-9+129 e613affb88d178dc7c589f1679db113d589bddb4 jdk-9+130 4d2a15091124488080d65848b704e25599b2aaeb jdk-9+131 2e83d21d78cd9c1d52e6cd2599e9c8aa36ea1f52 jdk-9+132 +e17429a7e843c4a4ed3651458d0f950970edcbcc jdk-9+133 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 2ab754ea198..9b00c6661fd 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -375,3 +375,4 @@ f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129 d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130 8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131 a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132 +be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133 diff --git a/corba/.hgtags b/corba/.hgtags index 2ba88ee0421..a959d0d2240 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -375,3 +375,4 @@ c3e83ccab3bb1733ae903d681879a33f85ed465c jdk-9+129 77f9692d5976ae155773dd3e07533616bb95bae1 jdk-9+130 f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131 1ab4b9399c4cba584f66c1c088188f2f565fbf9c jdk-9+132 +2021bfedf1c478a4808a7711a6090682a12f4c0e jdk-9+133 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index dd85a0e3b2b..8d8a2e6cf99 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -535,3 +535,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129 7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130 943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131 713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132 +a25e0fb6033245ab075136e744d362ce765464cd jdk-9+133 diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp index bab62cd4f86..22097092a7a 100644 --- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp +++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,6 +28,7 @@ #include "runtime/globals_extension.hpp" #include "runtime/vm_version.hpp" +#include "utilities/sizes.hpp" class VM_Version : public Abstract_VM_Version { friend class JVMCIVMStructs; diff --git a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp index 9e91f22f266..1fcf7d9984b 100644 --- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp +++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp @@ -37,7 +37,7 @@ #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" #include "runtime/interfaceSupport.hpp" diff --git a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java index f9f0a07838d..a9e91802bba 100644 --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java @@ -24,6 +24,7 @@ package sun.jvm.hotspot.gc.g1; +import java.io.PrintStream; import java.util.Iterator; import java.util.Observable; import java.util.Observer; @@ -125,6 +126,15 @@ public class G1CollectedHeap extends CollectedHeap { return CollectedHeapName.G1_COLLECTED_HEAP; } + @Override + public void printOn(PrintStream tty) { + MemRegion mr = reservedRegion(); + + tty.print("garbage-first heap"); + tty.print(" [" + mr.start() + ", " + mr.end() + "]"); + tty.println(" region size " + (HeapRegion.grainBytes() / 1024) + "K"); + } + public G1CollectedHeap(Address addr) { super(addr); } diff --git a/hotspot/src/os/aix/vm/os_aix.cpp b/hotspot/src/os/aix/vm/os_aix.cpp index dffad2b7f3f..6c668c16870 100644 --- a/hotspot/src/os/aix/vm/os_aix.cpp +++ b/hotspot/src/os/aix/vm/os_aix.cpp @@ -52,7 +52,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" @@ -3800,10 +3800,6 @@ int os::stat(const char *path, struct stat *sbuf) { return ::stat(pathbuf, sbuf); } -bool os::check_heap(bool force) { - return true; -} - // Is a (classpath) directory empty? bool os::dir_is_empty(const char* path) { DIR *dir = NULL; diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp index a40175df89c..39cfd207cc6 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.cpp +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp @@ -42,7 +42,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" @@ -3780,11 +3780,6 @@ int os::compare_file_modified_times(const char* file1, const char* file2) { return diff; } - -bool os::check_heap(bool force) { - return true; -} - // Is a (classpath) directory empty? bool os::dir_is_empty(const char* path) { DIR *dir = NULL; diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 5f4f1174c9d..9248eb72e35 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -42,7 +42,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" @@ -5174,10 +5174,6 @@ int os::stat(const char *path, struct stat *sbuf) { return ::stat(pathbuf, sbuf); } -bool os::check_heap(bool force) { - return true; -} - // Is a (classpath) directory empty? bool os::dir_is_empty(const char* path) { DIR *dir = NULL; diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 3b9a3793a61..825a679dc19 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -42,7 +42,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" @@ -4589,10 +4589,6 @@ void os::make_polling_page_readable(void) { } } -// OS interface. - -bool os::check_heap(bool force) { return true; } - // Is a (classpath) directory empty? bool os::dir_is_empty(const char* path) { DIR *dir = NULL; diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 5dfdab012d6..24b39189e76 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -45,7 +45,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" @@ -5258,75 +5258,6 @@ int os::fork_and_exec(char* cmd) { } } -//-------------------------------------------------------------------------------------------------- -// Non-product code - -static int mallocDebugIntervalCounter = 0; -static int mallocDebugCounter = 0; - -// For debugging possible bugs inside HeapWalk (a ring buffer) -#define SAVE_COUNT 8 -static PROCESS_HEAP_ENTRY saved_heap_entries[SAVE_COUNT]; -static int saved_heap_entry_index; - -bool os::check_heap(bool force) { - if (++mallocDebugCounter < MallocVerifyStart && !force) return true; - if (++mallocDebugIntervalCounter >= MallocVerifyInterval || force) { - // Note: HeapValidate executes two hardware breakpoints when it finds something - // wrong; at these points, eax contains the address of the offending block (I think). - // To get to the exlicit error message(s) below, just continue twice. - // - // Note: we want to check the CRT heap, which is not necessarily located in the - // process default heap. - HANDLE heap = (HANDLE) _get_heap_handle(); - if (!heap) { - return true; - } - - // If we fail to lock the heap, then gflags.exe has been used - // or some other special heap flag has been set that prevents - // locking. We don't try to walk a heap we can't lock. - if (HeapLock(heap) != 0) { - PROCESS_HEAP_ENTRY phe; - phe.lpData = NULL; - memset(saved_heap_entries, 0, sizeof(saved_heap_entries)); - saved_heap_entry_index = 0; - int count = 0; - - while (HeapWalk(heap, &phe) != 0) { - count ++; - if ((phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) && - !HeapValidate(heap, 0, phe.lpData)) { - tty->print_cr("C heap has been corrupted (time: %d allocations)", mallocDebugCounter); - tty->print_cr("corrupted block near address %#x, length %d, count %d", phe.lpData, phe.cbData, count); - HeapUnlock(heap); - fatal("corrupted C heap"); - } else { - // Save previous seen entries in a ring buffer. We have seen strange - // heap corruption fatal errors that produced mdmp files, but when we load - // these mdmp files in WinDBG, "!heap -triage" shows no error. - // We can examine the saved_heap_entries[] array in the mdmp file to - // diagnose such seemingly spurious errors reported by HeapWalk. - saved_heap_entries[saved_heap_entry_index++] = phe; - if (saved_heap_entry_index >= SAVE_COUNT) { - saved_heap_entry_index = 0; - } - } - } - DWORD err = GetLastError(); - if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED && - (err == ERROR_INVALID_FUNCTION && phe.lpData != NULL)) { - HeapUnlock(heap); - fatal("heap walk aborted with error %d", err); - } - HeapUnlock(heap); - } - mallocDebugIntervalCounter = 0; - } - return true; -} - - bool os::find(address addr, outputStream* st) { int offset = -1; bool result = false; diff --git a/hotspot/src/os/windows/vm/threadCritical_windows.cpp b/hotspot/src/os/windows/vm/threadCritical_windows.cpp index 3ea83c1acb6..b432f7bb078 100644 --- a/hotspot/src/os/windows/vm/threadCritical_windows.cpp +++ b/hotspot/src/os/windows/vm/threadCritical_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadCritical.hpp" diff --git a/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp b/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.hpp similarity index 98% rename from hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp rename to hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.hpp index a7462ad395e..efa550bffea 100644 --- a/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp +++ b/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,11 +23,8 @@ * */ -#ifndef OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP -#define OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" +#ifndef OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_HPP +#define OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_HPP #ifndef _LP64 #error "Atomic currently only impleneted for PPC64" @@ -479,4 +476,4 @@ inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void #undef strasm_nobarrier #undef strasm_nobarrier_clobber_memory -#endif // OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP +#endif // OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_HPP diff --git a/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp b/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp similarity index 97% rename from hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp rename to hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp index 8310003a8f1..92b5b9311ae 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp +++ b/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,9 @@ * */ -#ifndef OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP -#define OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP +#ifndef OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_HPP +#define OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_HPP -#include "runtime/atomic.hpp" #include "runtime/os.hpp" // Implementation of class atomic @@ -225,4 +224,4 @@ inline void Atomic::store(jlong store_value, volatile jlong* dest) { #endif // AMD64 -#endif // OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP +#endif // OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_HPP diff --git a/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp b/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp index bc28eb2b2d4..038d6f985d5 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp +++ b/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP #define OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" diff --git a/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp b/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.hpp similarity index 97% rename from hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp rename to hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.hpp index 4490e49020c..e8083400ec1 100644 --- a/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp +++ b/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,10 +23,9 @@ * */ -#ifndef OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP -#define OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP +#ifndef OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_HPP +#define OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_HPP -#include "runtime/atomic.hpp" #include "runtime/os.hpp" // Implementation of class atomic @@ -331,4 +330,4 @@ inline void Atomic::store(jlong store_value, volatile jlong* dest) { os::atomic_copy64((volatile jlong*)&store_value, dest); } -#endif // OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP +#endif // OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_HPP diff --git a/hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.inline.hpp b/hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.hpp similarity index 94% rename from hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.inline.hpp rename to hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.hpp index 95d007fc21b..77dd34a663e 100644 --- a/hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.inline.hpp +++ b/hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,11 +23,9 @@ * */ -#ifndef OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP -#define OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP +#ifndef OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_HPP +#define OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_HPP -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" #include "vm_version_aarch64.hpp" // Implementation of class atomic @@ -161,4 +159,4 @@ inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void inline jlong Atomic::load(volatile jlong* src) { return *src; } -#endif // OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP +#endif // OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_HPP diff --git a/hotspot/src/os_cpu/linux_aarch64/vm/orderAccess_linux_aarch64.inline.hpp b/hotspot/src/os_cpu/linux_aarch64/vm/orderAccess_linux_aarch64.inline.hpp index adeaa0ad1fd..03c6b314d56 100644 --- a/hotspot/src/os_cpu/linux_aarch64/vm/orderAccess_linux_aarch64.inline.hpp +++ b/hotspot/src/os_cpu/linux_aarch64/vm/orderAccess_linux_aarch64.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,7 @@ #ifndef OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP #define OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" #include "vm_version_aarch64.hpp" diff --git a/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp b/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.hpp similarity index 98% rename from hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp rename to hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.hpp index 6c8498c4508..0f4a5a8447d 100644 --- a/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp +++ b/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,11 +23,8 @@ * */ -#ifndef OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_INLINE_HPP -#define OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" +#ifndef OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_HPP +#define OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_HPP #ifndef PPC64 #error "Atomic currently only implemented for PPC64" @@ -479,4 +476,4 @@ inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void #undef strasm_nobarrier #undef strasm_nobarrier_clobber_memory -#endif // OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_INLINE_HPP +#endif // OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_HPP diff --git a/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp b/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp index b0df28daea3..5830beba77d 100644 --- a/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp +++ b/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,6 @@ #ifndef OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP #define OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - // Implementation of class atomic inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } diff --git a/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp b/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp similarity index 97% rename from hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp rename to hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp index faf0a8043f7..7b51da41ce0 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp +++ b/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,9 @@ * */ -#ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP -#define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP +#ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP +#define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP -#include "runtime/atomic.hpp" #include "runtime/os.hpp" // Implementation of class atomic @@ -225,4 +224,4 @@ inline void Atomic::store(jlong store_value, volatile jlong* dest) { #endif // AMD64 -#endif // OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP +#endif // OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP diff --git a/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp b/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp index b4aceaf5a91..0f564216e13 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp +++ b/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP #define OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" diff --git a/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.hpp similarity index 97% rename from hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp rename to hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.hpp index 4a9b2c05da9..7c3235ffd06 100644 --- a/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp +++ b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,10 +23,9 @@ * */ -#ifndef OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP -#define OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP +#ifndef OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_HPP +#define OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_HPP -#include "runtime/atomic.hpp" #include "runtime/os.hpp" // Implementation of class atomic @@ -325,4 +324,4 @@ inline void Atomic::store(jlong store_value, volatile jlong* dest) { os::atomic_copy64((volatile jlong*)&store_value, dest); } -#endif // OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP +#endif // OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_HPP diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.hpp similarity index 97% rename from hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp rename to hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.hpp index 03c4326073a..3c292a4dea0 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,9 @@ * */ -#ifndef OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP -#define OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP +#ifndef OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_HPP +#define OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_HPP -#include "runtime/atomic.hpp" #include "runtime/os.hpp" // Implementation of class atomic @@ -374,4 +373,4 @@ inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* #endif // _GNU_SOURCE -#endif // OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP +#endif // OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_HPP diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp index 4bf5833a458..7a74147d6a0 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_CPU_SOLARIS_SPARC_VM_ORDERACCESS_SOLARIS_SPARC_INLINE_HPP #define OS_CPU_SOLARIS_SPARC_VM_ORDERACCESS_SOLARIS_SPARC_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" // Compiler version last used for testing: solaris studio 12u3 diff --git a/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp b/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp similarity index 97% rename from hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp rename to hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp index e856b755cf2..44f269912f5 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,9 @@ * */ -#ifndef OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP -#define OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP +#ifndef OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP +#define OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP -#include "runtime/atomic.hpp" #include "runtime/os.hpp" inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } @@ -276,4 +275,4 @@ extern "C" { #endif // _GNU_SOURCE -#endif // OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP +#endif // OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP diff --git a/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp b/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp index af4e2e29337..b88e715e4d4 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_CPU_SOLARIS_X86_VM_ORDERACCESS_SOLARIS_X86_INLINE_HPP #define OS_CPU_SOLARIS_X86_VM_ORDERACCESS_SOLARIS_X86_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" diff --git a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp index 7713550f374..ef64ff751d0 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @@ -38,7 +38,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/frame.inline.hpp" #include "runtime/interfaceSupport.hpp" diff --git a/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp b/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp similarity index 97% rename from hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp rename to hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp index 3d7662e5cd7..953e13d8ddf 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp +++ b/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,9 @@ * */ -#ifndef OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP -#define OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP +#ifndef OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_HPP +#define OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_HPP -#include "runtime/atomic.hpp" #include "runtime/os.hpp" // The following alternative implementations are needed because @@ -301,4 +300,4 @@ inline void Atomic::store(jlong store_value, jlong* dest) { #pragma warning(default: 4035) // Enables warnings reporting missing return statement -#endif // OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP +#endif // OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_HPP diff --git a/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp b/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp index 8481bd93f30..36c1c4a42c0 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp +++ b/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define OS_CPU_WINDOWS_X86_VM_ORDERACCESS_WINDOWS_X86_INLINE_HPP #include -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" diff --git a/hotspot/src/share/vm/asm/assembler.cpp b/hotspot/src/share/vm/asm/assembler.cpp index fe8dbb1b401..120b68e39a7 100644 --- a/hotspot/src/share/vm/asm/assembler.cpp +++ b/hotspot/src/share/vm/asm/assembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "asm/codeBuffer.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" #include "runtime/thread.hpp" diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index bd2cd0fb0f8..e25e81fdd04 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -4266,7 +4266,7 @@ void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool succes #if INCLUDE_TRACE EventCompilerInlining event; if (event.should_commit()) { - event.set_compileID(compilation()->env()->task()->compile_id()); + event.set_compileId(compilation()->env()->task()->compile_id()); event.set_message(msg); event.set_succeeded(success); event.set_bci(bci()); diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 3ee774ec00f..bbb5ef87c67 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -49,7 +49,7 @@ #include "memory/resourceArea.hpp" #include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/interfaceSupport.hpp" diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index 323b75a5016..024909b1cbc 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -1149,10 +1149,10 @@ void ciEnv::record_failure(const char* reason) { void ciEnv::report_failure(const char* reason) { // Create and fire JFR event - EventCompilerFailure event; + EventCompilationFailure event; if (event.should_commit()) { - event.set_compileID(compile_id()); - event.set_failure(reason); + event.set_compileId(compile_id()); + event.set_failureMessage(reason); event.commit(); } } diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index a54c0a724de..4860427786f 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -1410,11 +1410,11 @@ void ciMethod::print_impl(outputStream* st) { } #if INCLUDE_TRACE -TraceStructCiMethod ciMethod::to_trace_struct() const { - TraceStructCiMethod result; - result.set_class(holder()->name()->as_utf8()); +TraceStructCalleeMethod ciMethod::to_trace_struct() const { + TraceStructCalleeMethod result; + result.set_type(holder()->name()->as_utf8()); result.set_name(name()->as_utf8()); - result.set_signature(signature()->as_symbol()->as_utf8()); + result.set_descriptor(signature()->as_symbol()->as_utf8()); return result; } #endif diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp index 7a56f1cf2a5..94e6ac523c7 100644 --- a/hotspot/src/share/vm/ci/ciMethod.hpp +++ b/hotspot/src/share/vm/ci/ciMethod.hpp @@ -342,7 +342,7 @@ class ciMethod : public ciMetadata { void print_short_name(outputStream* st = tty); #if INCLUDE_TRACE - TraceStructCiMethod to_trace_struct() const; + TraceStructCalleeMethod to_trace_struct() const; #endif }; diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 30262696a8c..13c8ce71e9e 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -5402,6 +5402,17 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa debug_only(ik->verify();) } +static bool relax_format_check_for(ClassLoaderData* loader_data) { + bool trusted = (loader_data->is_the_null_class_loader_data() || + SystemDictionary::is_platform_class_loader(loader_data->class_loader())); + bool need_verify = + // verifyAll + (BytecodeVerificationLocal && BytecodeVerificationRemote) || + // verifyRemote + (!BytecodeVerificationLocal && BytecodeVerificationRemote && !trusted); + return !need_verify; +} + ClassFileParser::ClassFileParser(ClassFileStream* stream, Symbol* name, ClassLoaderData* loader_data, @@ -5490,7 +5501,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream, // Check if verification needs to be relaxed for this class file // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376) - _relax_verify = Verifier::relax_verify_for(_loader_data->class_loader()); + _relax_verify = relax_format_check_for(_loader_data); parse_stream(stream, CHECK); diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp index 09ddbf40b92..ba1191614b1 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp @@ -63,7 +63,7 @@ #include "memory/resourceArea.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/javaCalls.hpp" #include "runtime/jniHandles.hpp" #include "runtime/mutex.hpp" diff --git a/hotspot/src/share/vm/classfile/klassFactory.cpp b/hotspot/src/share/vm/classfile/klassFactory.cpp index 6eb6ccc9405..4d08ea3329c 100644 --- a/hotspot/src/share/vm/classfile/klassFactory.cpp +++ b/hotspot/src/share/vm/classfile/klassFactory.cpp @@ -31,12 +31,12 @@ #include "prims/jvmtiEnvBase.hpp" #include "trace/traceMacros.hpp" -static ClassFileStream* prologue(ClassFileStream* stream, - Symbol* name, - ClassLoaderData* loader_data, - Handle protection_domain, - JvmtiCachedClassFileData** cached_class_file, - TRAPS) { +static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream, + Symbol* name, + ClassLoaderData* loader_data, + Handle protection_domain, + JvmtiCachedClassFileData** cached_class_file, + TRAPS) { assert(stream != NULL, "invariant"); @@ -102,8 +102,6 @@ instanceKlassHandle KlassFactory::create_from_stream(ClassFileStream* stream, assert(loader_data != NULL, "invariant"); assert(THREAD->is_Java_thread(), "must be a JavaThread"); - bool changed_by_loadhook = false; - ResourceMark rm; HandleMark hm; @@ -111,12 +109,15 @@ instanceKlassHandle KlassFactory::create_from_stream(ClassFileStream* stream, ClassFileStream* old_stream = stream; - stream = prologue(stream, - name, - loader_data, - protection_domain, - &cached_class_file, - CHECK_NULL); + // Skip this processing for VM anonymous classes + if (host_klass == NULL) { + stream = check_class_file_load_hook(stream, + name, + loader_data, + protection_domain, + &cached_class_file, + CHECK_NULL); + } ClassFileParser parser(stream, name, diff --git a/hotspot/src/share/vm/classfile/stringTable.cpp b/hotspot/src/share/vm/classfile/stringTable.cpp index abf662cb403..7d3fe1636f2 100644 --- a/hotspot/src/share/vm/classfile/stringTable.cpp +++ b/hotspot/src/share/vm/classfile/stringTable.cpp @@ -34,7 +34,7 @@ #include "memory/filemap.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/hashtable.inline.hpp" #include "utilities/macros.hpp" diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index f4997a7ca70..8f51f527508 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -34,7 +34,7 @@ #include "memory/filemap.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/hashtable.inline.hpp" diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 033980e3d78..70f9e6a169f 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -1641,7 +1641,6 @@ void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) { JvmtiExport::post_class_load((JavaThread *) THREAD, k()); } - TRACE_KLASS_DEFINITION(k, THREAD); class_define_event(k); } diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index c0976d55d4b..2194859c30c 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -88,7 +88,7 @@ bool Verifier::should_verify_for(oop class_loader, bool should_verify_class) { BytecodeVerificationLocal : BytecodeVerificationRemote; } -bool Verifier::relax_verify_for(oop loader) { +bool Verifier::relax_access_for(oop loader) { bool trusted = java_lang_ClassLoader::is_trusted_loader(loader); bool need_verify = // verifyAll diff --git a/hotspot/src/share/vm/classfile/verifier.hpp b/hotspot/src/share/vm/classfile/verifier.hpp index a613c62a3d5..f4c00eb9b1d 100644 --- a/hotspot/src/share/vm/classfile/verifier.hpp +++ b/hotspot/src/share/vm/classfile/verifier.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,8 +58,8 @@ class Verifier : AllStatic { // -Xverify:all/none override this value static bool should_verify_for(oop class_loader, bool should_verify_class); - // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2. - static bool relax_verify_for(oop class_loader); + // Relax certain access checks to enable some broken 1.1 apps to run on 1.2. + static bool relax_access_for(oop class_loader); // Print output for class+resolve static void trace_class_resolution(Klass* resolve_class, InstanceKlass* verify_class); diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp index d09518c011f..db757f7faa0 100644 --- a/hotspot/src/share/vm/code/nmethod.cpp +++ b/hotspot/src/share/vm/code/nmethod.cpp @@ -41,7 +41,7 @@ #include "oops/methodData.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiImpl.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index f9768b50d99..b3bc80c6a51 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -42,7 +42,7 @@ #include "prims/nativeLookup.hpp" #include "prims/whitebox.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" @@ -1755,7 +1755,7 @@ void CompileBroker::post_compile(CompilerThread* thread, CompileTask* task, Even assert(task->compile_id() != CICrashAt, "just as planned"); if (event.should_commit()) { event.set_method(task->method()); - event.set_compileID(task->compile_id()); + event.set_compileId(task->compile_id()); event.set_compileLevel(task->comp_level()); event.set_succeded(task->is_success()); event.set_isOsr(task->osr_bci() != CompileBroker::standard_entry_bci); @@ -2399,4 +2399,3 @@ void CompileBroker::print_last_compile() { } } } - diff --git a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp index cbbbfbded27..6d78865ac43 100644 --- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp @@ -61,7 +61,7 @@ #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiExport.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/globals_extension.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" diff --git a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp index da6b6d623a3..e8f606eecc8 100644 --- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp @@ -50,7 +50,7 @@ #include "memory/resourceArea.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" diff --git a/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp b/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp index cc9dbf46e67..1e757b8009d 100644 --- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp +++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp @@ -26,7 +26,7 @@ #include "gc/g1/collectionSetChooser.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/shared/space.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" // Even though we don't use the GC efficiency in our heuristics as // much as we used to, we still order according to GC efficiency. This diff --git a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp index b16ccc6fed0..dcd88be5057 100644 --- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp +++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp @@ -27,7 +27,7 @@ #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" #include "gc/shared/workgroup.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/safepoint.hpp" #include "runtime/thread.inline.hpp" diff --git a/hotspot/src/share/vm/gc/g1/g1Analytics.cpp b/hotspot/src/share/vm/gc/g1/g1Analytics.cpp index 8214a4bfa55..c43b4169e49 100644 --- a/hotspot/src/share/vm/gc/g1/g1Analytics.cpp +++ b/hotspot/src/share/vm/gc/g1/g1Analytics.cpp @@ -316,12 +316,8 @@ size_t G1Analytics::predict_pending_cards() const { return get_new_size_prediction(_pending_cards_seq); } -double G1Analytics::oldest_known_gc_end_time_sec() const { - return _recent_prev_end_times_for_all_gcs_sec->oldest(); -} - double G1Analytics::last_known_gc_end_time_sec() const { - return _recent_prev_end_times_for_all_gcs_sec->last(); + return _recent_prev_end_times_for_all_gcs_sec->oldest(); } void G1Analytics::update_recent_gc_times(double end_time_sec, diff --git a/hotspot/src/share/vm/gc/g1/g1Analytics.hpp b/hotspot/src/share/vm/gc/g1/g1Analytics.hpp index 3f9a37a98e7..a22d0dd72bd 100644 --- a/hotspot/src/share/vm/gc/g1/g1Analytics.hpp +++ b/hotspot/src/share/vm/gc/g1/g1Analytics.hpp @@ -155,7 +155,6 @@ public: void update_recent_gc_times(double end_time_sec, double elapsed_ms); void compute_pause_time_ratio(double interval_ms, double pause_time_ms); - double oldest_known_gc_end_time_sec() const; double last_known_gc_end_time_sec() const; }; diff --git a/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp b/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp index 100b894ecc1..fc6fe469625 100644 --- a/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp @@ -30,7 +30,7 @@ #include "gc/shared/workgroup.hpp" #include "logging/log.hpp" #include "memory/universe.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "runtime/os.hpp" #include "utilities/bitMap.inline.hpp" diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp index a267098ed86..e1462e9343c 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -28,7 +28,6 @@ #include "classfile/symbolTable.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" -#include "gc/g1/g1Analytics.hpp" #include "gc/g1/bufferingOopClosure.hpp" #include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/concurrentG1RefineThread.hpp" @@ -75,7 +74,7 @@ #include "memory/iterator.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/init.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/vmThread.hpp" @@ -2474,19 +2473,8 @@ size_t G1CollectedHeap::max_capacity() const { } jlong G1CollectedHeap::millis_since_last_gc() { - jlong now = os::elapsed_counter() / NANOSECS_PER_MILLISEC; - const G1Analytics* analytics = _g1_policy->analytics(); - double last = analytics->last_known_gc_end_time_sec(); - jlong ret_val = now - (last * 1000); - if (ret_val < 0) { - // See the notes in GenCollectedHeap::millis_since_last_gc() - // for more information about the implementation. - log_warning(gc)("Detected clock going backwards. " - "Milliseconds since last GC would be " JLONG_FORMAT - ". returning zero instead.", ret_val); - return 0; - } - return ret_val; + // assert(false, "NYI"); + return 0; } void G1CollectedHeap::prepare_for_verify() { diff --git a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp index 454c5989484..27f4071b7bf 100644 --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp @@ -52,7 +52,7 @@ #include "memory/allocation.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/prefetch.inline.hpp" diff --git a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp index dfef9538ba7..454f73bc0c6 100644 --- a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp +++ b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp @@ -604,7 +604,7 @@ void G1DefaultPolicy::record_collection_pause_end(double pause_time_ms, size_t c _analytics->report_alloc_rate_ms(alloc_rate_ms); double interval_ms = - (end_time_sec - _analytics->oldest_known_gc_end_time_sec()) * 1000.0; + (end_time_sec - _analytics->last_known_gc_end_time_sec()) * 1000.0; _analytics->update_recent_gc_times(end_time_sec, pause_time_ms); _analytics->compute_pause_time_ratio(interval_ms, pause_time_ms); } diff --git a/hotspot/src/share/vm/gc/g1/g1EvacStats.inline.hpp b/hotspot/src/share/vm/gc/g1/g1EvacStats.inline.hpp index 337d4625707..007f62d3af4 100644 --- a/hotspot/src/share/vm/gc/g1/g1EvacStats.inline.hpp +++ b/hotspot/src/share/vm/gc/g1/g1EvacStats.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_VM_GC_G1_G1EVACSTATS_INLINE_HPP #include "gc/g1/g1EvacStats.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" inline void G1EvacStats::add_direct_allocated(size_t value) { Atomic::add_ptr(value, &_direct_allocated); diff --git a/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp b/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp index aae9c94f0f6..c18fb36afaf 100644 --- a/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp +++ b/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "gc/g1/dirtyCardQueue.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1HotCardCache.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" G1HotCardCache::G1HotCardCache(G1CollectedHeap *g1h): _g1h(g1h), _hot_cache(NULL), _use_cache(false), _card_counts(g1h) {} diff --git a/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp b/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp index 3d8866de817..4eed0960dca 100644 --- a/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp +++ b/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ #include "oops/instanceRefKlass.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiExport.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/fprofiler.hpp" #include "runtime/synchronizer.hpp" diff --git a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp index c701b700c6a..006a658f5d8 100644 --- a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp @@ -30,7 +30,7 @@ #include "gc/shared/memset_with_concurrent_readers.hpp" #include "logging/log.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/thread.inline.hpp" diff --git a/hotspot/src/share/vm/gc/g1/g1StringDedup.cpp b/hotspot/src/share/vm/gc/g1/g1StringDedup.cpp index 8b8ce067eaf..e9f91bd2c1b 100644 --- a/hotspot/src/share/vm/gc/g1/g1StringDedup.cpp +++ b/hotspot/src/share/vm/gc/g1/g1StringDedup.cpp @@ -31,7 +31,7 @@ #include "gc/g1/g1StringDedupStat.hpp" #include "gc/g1/g1StringDedupTable.hpp" #include "gc/g1/g1StringDedupThread.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" bool G1StringDedup::_enabled = false; diff --git a/hotspot/src/share/vm/gc/g1/g1StringDedup.hpp b/hotspot/src/share/vm/gc/g1/g1StringDedup.hpp index 9191613787b..6ed8f22b74a 100644 --- a/hotspot/src/share/vm/gc/g1/g1StringDedup.hpp +++ b/hotspot/src/share/vm/gc/g1/g1StringDedup.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,7 +84,6 @@ #include "memory/allocation.hpp" #include "oops/oop.hpp" -#include "runtime/atomic.hpp" class OopClosure; class BoolObjectClosure; diff --git a/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp b/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp index 3bca86a80a5..b029c3f2b40 100644 --- a/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp +++ b/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp @@ -30,7 +30,7 @@ #include "gc/shared/gcLocker.hpp" #include "logging/log.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/stack.inline.hpp" diff --git a/hotspot/src/share/vm/gc/g1/g1StringDedupThread.cpp b/hotspot/src/share/vm/gc/g1/g1StringDedupThread.cpp index 0bdfc193064..f0b25d3c6a9 100644 --- a/hotspot/src/share/vm/gc/g1/g1StringDedupThread.cpp +++ b/hotspot/src/share/vm/gc/g1/g1StringDedupThread.cpp @@ -31,7 +31,7 @@ #include "gc/g1/suspendibleThreadSet.hpp" #include "logging/log.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" G1StringDedupThread* G1StringDedupThread::_thread = NULL; diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.cpp b/hotspot/src/share/vm/gc/g1/heapRegion.cpp index 13143a32afe..33d8268855d 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp @@ -39,7 +39,7 @@ #include "memory/iterator.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" int HeapRegion::LogOfHRGrainBytes = 0; diff --git a/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp b/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp index 248e0befa1d..01c53283579 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp +++ b/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp @@ -30,7 +30,7 @@ #include "gc/g1/heapRegion.hpp" #include "gc/shared/space.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" inline HeapWord* G1ContiguousSpace::allocate_impl(size_t min_word_size, size_t desired_word_size, diff --git a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp index ad4821ae4fd..9aa4da68968 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp @@ -33,7 +33,7 @@ #include "memory/allocation.hpp" #include "memory/padded.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/bitMap.inline.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/growableArray.hpp" diff --git a/hotspot/src/share/vm/gc/g1/heapRegionTracer.cpp b/hotspot/src/share/vm/gc/g1/heapRegionTracer.cpp index ec3febd2f64..35baa9d5d66 100644 --- a/hotspot/src/share/vm/gc/g1/heapRegionTracer.cpp +++ b/hotspot/src/share/vm/gc/g1/heapRegionTracer.cpp @@ -39,7 +39,7 @@ void HeapRegionTracer::send_region_type_change(uint index, e.set_to(to); e.set_start(start); e.set_used(used); - e.set_allocContext(allocationContext); + e.set_allocationContext(allocationContext); e.commit(); } } diff --git a/hotspot/src/share/vm/gc/g1/sparsePRT.cpp b/hotspot/src/share/vm/gc/g1/sparsePRT.cpp index cab39b36e91..44e43465ce6 100644 --- a/hotspot/src/share/vm/gc/g1/sparsePRT.cpp +++ b/hotspot/src/share/vm/gc/g1/sparsePRT.cpp @@ -30,7 +30,7 @@ #include "gc/shared/cardTableModRefBS.hpp" #include "gc/shared/space.inline.hpp" #include "memory/allocation.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" // Check that the size of the SparsePRTEntry is evenly divisible by the maximum diff --git a/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp b/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp index 42e67119e0a..48eb3c4163d 100644 --- a/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp +++ b/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp @@ -30,7 +30,7 @@ #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp" #include "runtime/os.hpp" diff --git a/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp b/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp index e53d195d639..c4cb76d5c86 100644 --- a/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp +++ b/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp @@ -1,6 +1,5 @@ - /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +27,7 @@ #include "gc/shared/collectedHeap.hpp" #include "gc/shared/spaceDecorator.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/thread.inline.hpp" MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment) { diff --git a/hotspot/src/share/vm/gc/parallel/mutableSpace.cpp b/hotspot/src/share/vm/gc/parallel/mutableSpace.cpp index 4db21472ec5..61dc795d484 100644 --- a/hotspot/src/share/vm/gc/parallel/mutableSpace.cpp +++ b/hotspot/src/share/vm/gc/parallel/mutableSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "gc/parallel/mutableSpace.hpp" #include "gc/shared/spaceDecorator.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/safepoint.hpp" #include "runtime/thread.hpp" #include "utilities/macros.hpp" diff --git a/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp b/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp index 39b63acb016..df29bbdcde4 100644 --- a/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp +++ b/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp @@ -27,7 +27,7 @@ #include "gc/parallel/psCompactionManager.inline.hpp" #include "gc/parallel/psParallelCompact.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "services/memTracker.hpp" #include "utilities/bitMap.inline.hpp" diff --git a/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp b/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp index 2884b4c7df6..fc3e9088ea9 100644 --- a/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp +++ b/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp @@ -38,7 +38,7 @@ #include "oops/instanceMirrorKlass.inline.hpp" #include "oops/objArrayKlass.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" PSOldGen* ParCompactionManager::_old_gen = NULL; ParCompactionManager** ParCompactionManager::_manager_array = NULL; diff --git a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp index d16e510a5f5..ccd464892e4 100644 --- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp @@ -57,7 +57,7 @@ #include "oops/methodData.hpp" #include "oops/objArrayKlass.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/fprofiler.hpp" #include "runtime/safepoint.hpp" #include "runtime/vmThread.hpp" diff --git a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp index a10a9f18c62..147bc06d305 100644 --- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp +++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp @@ -46,7 +46,7 @@ #include "memory/resourceArea.hpp" #include "oops/instanceRefKlass.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/java.hpp" #include "runtime/prefetch.inline.hpp" #include "runtime/thread.inline.hpp" diff --git a/hotspot/src/share/vm/gc/shared/allocTracer.cpp b/hotspot/src/share/vm/gc/shared/allocTracer.cpp index af427a8289f..5f79a3310b3 100644 --- a/hotspot/src/share/vm/gc/shared/allocTracer.cpp +++ b/hotspot/src/share/vm/gc/shared/allocTracer.cpp @@ -29,18 +29,18 @@ #include "utilities/globalDefinitions.hpp" void AllocTracer::send_allocation_outside_tlab_event(KlassHandle klass, size_t alloc_size) { - EventAllocObjectOutsideTLAB event; + EventObjectAllocationOutsideTLAB event; if (event.should_commit()) { - event.set_class(klass()); + event.set_objectClass(klass()); event.set_allocationSize(alloc_size); event.commit(); } } void AllocTracer::send_allocation_in_new_tlab_event(KlassHandle klass, size_t tlab_size, size_t alloc_size) { - EventAllocObjectInNewTLAB event; + EventObjectAllocationInNewTLAB event; if (event.should_commit()) { - event.set_class(klass()); + event.set_objectClass(klass()); event.set_allocationSize(alloc_size); event.set_tlabSize(tlab_size); event.commit(); diff --git a/hotspot/src/share/vm/gc/shared/cardTableRS.cpp b/hotspot/src/share/vm/gc/shared/cardTableRS.cpp index 5e28170a2aa..eabc5156902 100644 --- a/hotspot/src/share/vm/gc/shared/cardTableRS.cpp +++ b/hotspot/src/share/vm/gc/shared/cardTableRS.cpp @@ -29,7 +29,7 @@ #include "gc/shared/space.inline.hpp" #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "utilities/macros.hpp" diff --git a/hotspot/src/share/vm/gc/shared/gcLocker.cpp b/hotspot/src/share/vm/gc/shared/gcLocker.cpp index cc847261efd..4b72cd80bfd 100644 --- a/hotspot/src/share/vm/gc/shared/gcLocker.cpp +++ b/hotspot/src/share/vm/gc/shared/gcLocker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "gc/shared/gcLocker.inline.hpp" #include "memory/resourceArea.hpp" #include "logging/log.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/thread.inline.hpp" volatile jint GCLocker::_jni_lock_count = 0; diff --git a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp index e51e8fe8f54..046db77d4d5 100644 --- a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp +++ b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp @@ -43,7 +43,7 @@ typedef uintptr_t TraceAddress; void GCTracer::send_garbage_collection_event() const { - EventGCGarbageCollection event(UNTIMED); + EventGarbageCollection event(UNTIMED); if (event.should_commit()) { event.set_gcId(GCId::current()); event.set_name(_shared_gc_info.name()); @@ -91,7 +91,7 @@ void GCTracer::send_metaspace_chunk_free_list_summary(GCWhen::Type when, Metaspa } void ParallelOldTracer::send_parallel_old_event() const { - EventGCParallelOld e(UNTIMED); + EventParallelOldGarbageCollection e(UNTIMED); if (e.should_commit()) { e.set_gcId(GCId::current()); e.set_densePrefix((TraceAddress)_parallel_old_gc_info.dense_prefix()); @@ -102,7 +102,7 @@ void ParallelOldTracer::send_parallel_old_event() const { } void YoungGCTracer::send_young_gc_event() const { - EventGCYoungGarbageCollection e(UNTIMED); + EventYoungGarbageCollection e(UNTIMED); if (e.should_commit()) { e.set_gcId(GCId::current()); e.set_tenuringThreshold(_tenuring_threshold); @@ -127,7 +127,7 @@ void YoungGCTracer::send_promotion_in_new_plab_event(Klass* klass, size_t obj_si EventPromoteObjectInNewPLAB event; if (event.should_commit()) { event.set_gcId(GCId::current()); - event.set_class(klass); + event.set_objectClass(klass); event.set_objectSize(obj_size); event.set_tenured(tenured); event.set_tenuringAge(age); @@ -142,7 +142,7 @@ void YoungGCTracer::send_promotion_outside_plab_event(Klass* klass, size_t obj_s EventPromoteObjectOutsidePLAB event; if (event.should_commit()) { event.set_gcId(GCId::current()); - event.set_class(klass); + event.set_objectClass(klass); event.set_objectSize(obj_size); event.set_tenured(tenured); event.set_tenuringAge(age); @@ -151,7 +151,7 @@ void YoungGCTracer::send_promotion_outside_plab_event(Klass* klass, size_t obj_s } void OldGCTracer::send_old_gc_event() const { - EventGCOldGarbageCollection e(UNTIMED); + EventOldGarbageCollection e(UNTIMED); if (e.should_commit()) { e.set_gcId(GCId::current()); e.set_starttime(_shared_gc_info.start_timestamp()); @@ -173,7 +173,7 @@ void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_in EventPromotionFailed e; if (e.should_commit()) { e.set_gcId(GCId::current()); - e.set_data(to_trace_struct(pf_info)); + e.set_promotionFailed(to_trace_struct(pf_info)); e.set_thread(pf_info.thread_trace_id()); e.commit(); } @@ -190,7 +190,7 @@ void OldGCTracer::send_concurrent_mode_failure_event() { #if INCLUDE_ALL_GCS void G1NewTracer::send_g1_young_gc_event() { - EventGCG1GarbageCollection e(UNTIMED); + EventG1GarbageCollection e(UNTIMED); if (e.should_commit()) { e.set_gcId(GCId::current()); e.set_type(_g1_young_gc_info.type()); @@ -201,7 +201,7 @@ void G1NewTracer::send_g1_young_gc_event() { } void G1MMUTracer::send_g1_mmu_event(double timeSlice, double gcTime, double maxTime) { - EventGCG1MMU e; + EventG1MMU e; if (e.should_commit()) { e.set_gcId(GCId::current()); e.set_timeSlice(timeSlice); @@ -212,15 +212,15 @@ void G1MMUTracer::send_g1_mmu_event(double timeSlice, double gcTime, double maxT } void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) { - EventEvacuationInfo e; + EventEvacuationInformation e; if (e.should_commit()) { e.set_gcId(GCId::current()); e.set_cSetRegions(info->collectionset_regions()); e.set_cSetUsedBefore(info->collectionset_used_before()); e.set_cSetUsedAfter(info->collectionset_used_after()); e.set_allocationRegions(info->allocation_regions()); - e.set_allocRegionsUsedBefore(info->alloc_regions_used_before()); - e.set_allocRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied()); + e.set_allocationRegionsUsedBefore(info->alloc_regions_used_before()); + e.set_allocationRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied()); e.set_bytesCopied(info->bytes_copied()); e.set_regionsFreed(info->regions_freed()); e.commit(); @@ -231,13 +231,14 @@ void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_in EventEvacuationFailed e; if (e.should_commit()) { e.set_gcId(GCId::current()); - e.set_data(to_trace_struct(ef_info)); + e.set_evacuationFailed(to_trace_struct(ef_info)); e.commit(); } } -static TraceStructG1EvacStats create_g1_evacstats(unsigned gcid, const G1EvacSummary& summary) { - TraceStructG1EvacStats s; +static TraceStructG1EvacuationStatistics +create_g1_evacstats(unsigned gcid, const G1EvacSummary& summary) { + TraceStructG1EvacuationStatistics s; s.set_gcId(gcid); s.set_allocated(summary.allocated() * HeapWordSize); s.set_wasted(summary.wasted() * HeapWordSize); @@ -252,17 +253,17 @@ static TraceStructG1EvacStats create_g1_evacstats(unsigned gcid, const G1EvacSum } void G1NewTracer::send_young_evacuation_statistics(const G1EvacSummary& summary) const { - EventGCG1EvacuationYoungStatistics surv_evt; + EventG1EvacuationYoungStatistics surv_evt; if (surv_evt.should_commit()) { - surv_evt.set_stats(create_g1_evacstats(GCId::current(), summary)); + surv_evt.set_statistics(create_g1_evacstats(GCId::current(), summary)); surv_evt.commit(); } } void G1NewTracer::send_old_evacuation_statistics(const G1EvacSummary& summary) const { - EventGCG1EvacuationOldStatistics old_evt; + EventG1EvacuationOldStatistics old_evt; if (old_evt.should_commit()) { - old_evt.set_stats(create_g1_evacstats(GCId::current(), summary)); + old_evt.set_statistics(create_g1_evacstats(GCId::current(), summary)); old_evt.commit(); } } @@ -273,7 +274,7 @@ void G1NewTracer::send_basic_ihop_statistics(size_t threshold, size_t last_allocation_size, double last_allocation_duration, double last_marking_length) { - EventGCG1BasicIHOP evt; + EventG1BasicIHOP evt; if (evt.should_commit()) { evt.set_gcId(GCId::current()); evt.set_threshold(threshold); @@ -295,7 +296,7 @@ void G1NewTracer::send_adaptive_ihop_statistics(size_t threshold, double predicted_allocation_rate, double predicted_marking_length, bool prediction_active) { - EventGCG1AdaptiveIHOP evt; + EventG1AdaptiveIHOP evt; if (evt.should_commit()) { evt.set_gcId(GCId::current()); evt.set_threshold(threshold); diff --git a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp index c1a28350047..049b675bd51 100644 --- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp @@ -1256,21 +1256,21 @@ class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure { }; jlong GenCollectedHeap::millis_since_last_gc() { - // javaTimeNanos() is guaranteed to be monotonically non-decreasing - // provided the underlying platform provides such a time source - // (and it is bug free). So we still have to guard against getting - // back a time later than 'now'. + // We need a monotonically non-decreasing time in ms but + // os::javaTimeMillis() does not guarantee monotonicity. jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; GenTimeOfLastGCClosure tolgc_cl(now); // iterate over generations getting the oldest // time that a generation was collected generation_iterate(&tolgc_cl, false); + // javaTimeNanos() is guaranteed to be monotonically non-decreasing + // provided the underlying platform provides such a time source + // (and it is bug free). So we still have to guard against getting + // back a time later than 'now'. jlong retVal = now - tolgc_cl.time(); if (retVal < 0) { - log_warning(gc)("Detected clock going backwards. " - "Milliseconds since last GC would be " JLONG_FORMAT - ". returning zero instead.", retVal); + NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);) return 0; } return retVal; diff --git a/hotspot/src/share/vm/gc/shared/objectCountEventSender.cpp b/hotspot/src/share/vm/gc/shared/objectCountEventSender.cpp index 4146a809d3b..d9ca9294da6 100644 --- a/hotspot/src/share/vm/gc/shared/objectCountEventSender.cpp +++ b/hotspot/src/share/vm/gc/shared/objectCountEventSender.cpp @@ -40,7 +40,7 @@ void ObjectCountEventSender::send(const KlassInfoEntry* entry, const Ticks& time EventObjectCountAfterGC event(UNTIMED); event.set_gcId(GCId::current()); - event.set_class(entry->klass()); + event.set_objectClass(entry->klass()); event.set_count(entry->count()); event.set_totalSize(entry->words() * BytesPerWord); event.set_endtime(timestamp); diff --git a/hotspot/src/share/vm/gc/shared/plab.inline.hpp b/hotspot/src/share/vm/gc/shared/plab.inline.hpp index 33a9f58007c..6963a7fd913 100644 --- a/hotspot/src/share/vm/gc/shared/plab.inline.hpp +++ b/hotspot/src/share/vm/gc/shared/plab.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/plab.hpp" #include "memory/allocation.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" inline HeapWord* PLAB::allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes) { HeapWord* res = CollectedHeap::align_allocation_or_fail(_top, _end, alignment_in_bytes); diff --git a/hotspot/src/share/vm/gc/shared/space.cpp b/hotspot/src/share/vm/gc/shared/space.cpp index c207dcd74b5..db21862989c 100644 --- a/hotspot/src/share/vm/gc/shared/space.cpp +++ b/hotspot/src/share/vm/gc/shared/space.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ #include "gc/shared/spaceDecorator.hpp" #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/java.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/prefetch.inline.hpp" diff --git a/hotspot/src/share/vm/gc/shared/taskqueue.cpp b/hotspot/src/share/vm/gc/shared/taskqueue.cpp index 57b65fbcc73..2fc94c6304d 100644 --- a/hotspot/src/share/vm/gc/shared/taskqueue.cpp +++ b/hotspot/src/share/vm/gc/shared/taskqueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "gc/shared/taskqueue.hpp" #include "oops/oop.inline.hpp" #include "logging/log.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "runtime/thread.inline.hpp" #include "utilities/debug.hpp" diff --git a/hotspot/src/share/vm/gc/shared/taskqueue.inline.hpp b/hotspot/src/share/vm/gc/shared/taskqueue.inline.hpp index baa35059bed..8852557c5db 100644 --- a/hotspot/src/share/vm/gc/shared/taskqueue.inline.hpp +++ b/hotspot/src/share/vm/gc/shared/taskqueue.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ #include "gc/shared/taskqueue.hpp" #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "utilities/debug.hpp" #include "utilities/stack.inline.hpp" diff --git a/hotspot/src/share/vm/gc/shared/workgroup.cpp b/hotspot/src/share/vm/gc/shared/workgroup.cpp index 84016fe466d..6df874b2510 100644 --- a/hotspot/src/share/vm/gc/shared/workgroup.cpp +++ b/hotspot/src/share/vm/gc/shared/workgroup.cpp @@ -28,7 +28,7 @@ #include "gc/shared/workerManager.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "runtime/semaphore.hpp" #include "runtime/thread.inline.hpp" diff --git a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp index 179940d7e22..655b58af156 100644 --- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp @@ -39,7 +39,7 @@ #include "oops/oop.inline.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp index 0770b397d79..18ac2392abe 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp @@ -48,7 +48,7 @@ #include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "prims/nativeLookup.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/deoptimization.hpp" diff --git a/hotspot/src/share/vm/logging/logDecorations.hpp b/hotspot/src/share/vm/logging/logDecorations.hpp index 3988bac83b3..38dcb40e99c 100644 --- a/hotspot/src/share/vm/logging/logDecorations.hpp +++ b/hotspot/src/share/vm/logging/logDecorations.hpp @@ -53,10 +53,6 @@ class LogDecorations VALUE_OBJ_CLASS_SPEC { LogDecorations(LogLevelType level, const LogTagSet& tagset, const LogDecorators& decorators); - LogLevelType level() const { - return _level; - } - void set_level(LogLevelType level) { _level = level; } diff --git a/hotspot/src/share/vm/logging/logOutputList.cpp b/hotspot/src/share/vm/logging/logOutputList.cpp index e2f8a6f1559..bc0565ae766 100644 --- a/hotspot/src/share/vm/logging/logOutputList.cpp +++ b/hotspot/src/share/vm/logging/logOutputList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #include "logging/logLevel.hpp" #include "logging/logOutputList.hpp" #include "memory/allocation.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/hotspot/src/share/vm/logging/logOutputList.hpp b/hotspot/src/share/vm/logging/logOutputList.hpp index e983cb0d7c2..851f4192bb3 100644 --- a/hotspot/src/share/vm/logging/logOutputList.hpp +++ b/hotspot/src/share/vm/logging/logOutputList.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ #include "logging/logLevel.hpp" #include "memory/allocation.hpp" -#include "runtime/atomic.hpp" #include "utilities/globalDefinitions.hpp" class LogOutput; @@ -61,6 +60,11 @@ class LogOutputList VALUE_OBJ_CLASS_SPEC { void add_output(LogOutput* output, LogLevelType level); void update_output_level(LogOutputNode* node, LogLevelType level); + // Bookkeeping functions to keep track of number of active readers/iterators for the list. + jint increase_readers(); + jint decrease_readers(); + void wait_until_no_readers() const; + public: LogOutputList() : _active_readers(0) { for (size_t i = 0; i < LogLevel::Count; i++) { @@ -84,11 +88,6 @@ class LogOutputList VALUE_OBJ_CLASS_SPEC { // Set (add/update/remove) the output to the specified level. void set_output_level(LogOutput* output, LogLevelType level); - // Bookkeeping functions to keep track of number of active readers/iterators for the list. - jint increase_readers(); - jint decrease_readers(); - void wait_until_no_readers() const; - class Iterator VALUE_OBJ_CLASS_SPEC { friend class LogOutputList; private: diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp index f7dea3d6c91..2e32964bf7e 100644 --- a/hotspot/src/share/vm/memory/allocation.cpp +++ b/hotspot/src/share/vm/memory/allocation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ #include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "runtime/task.hpp" #include "runtime/threadCritical.hpp" diff --git a/hotspot/src/share/vm/memory/allocation.inline.hpp b/hotspot/src/share/vm/memory/allocation.inline.hpp index 5fe55f4a292..db09c0cfb0e 100644 --- a/hotspot/src/share/vm/memory/allocation.inline.hpp +++ b/hotspot/src/share/vm/memory/allocation.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP #define SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "services/memTracker.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index ac7d0f838a3..1801a7c21cf 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -37,7 +37,7 @@ #include "memory/metaspaceTracer.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "runtime/init.hpp" #include "runtime/java.hpp" diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index a3dff52548f..1e434d1b79a 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -56,7 +56,7 @@ #include "oops/oop.inline.hpp" #include "oops/typeArrayKlass.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/commandLineFlagConstraintList.hpp" #include "runtime/deoptimization.hpp" #include "runtime/fprofiler.hpp" @@ -1129,8 +1129,6 @@ void Universe::initialize_verify_flags() { verify_flags |= Verify_MetaspaceAux; } else if (strcmp(token, "jni_handles") == 0) { verify_flags |= Verify_JNIHandles; - } else if (strcmp(token, "c-heap") == 0) { - verify_flags |= Verify_CHeap; } else if (strcmp(token, "codecache_oops") == 0) { verify_flags |= Verify_CodeCacheOops; } else { @@ -1208,10 +1206,6 @@ void Universe::verify(VerifyOption option, const char* prefix) { log_debug(gc, verify)("JNIHandles"); JNIHandles::verify(); } - if (should_verify_subset(Verify_CHeap)) { - log_debug(gc, verify)("C-heap"); - os::check_heap(); - } if (should_verify_subset(Verify_CodeCacheOops)) { log_debug(gc, verify)("CodeCache Oops"); CodeCache::verify_oops(); diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp index 924809b5704..054b11aa873 100644 --- a/hotspot/src/share/vm/memory/universe.hpp +++ b/hotspot/src/share/vm/memory/universe.hpp @@ -480,8 +480,7 @@ class Universe: AllStatic { Verify_ClassLoaderDataGraph = 64, Verify_MetaspaceAux = 128, Verify_JNIHandles = 256, - Verify_CHeap = 512, - Verify_CodeCacheOops = 1024, + Verify_CodeCacheOops = 512, Verify_All = -1 }; static void initialize_verify_flags(); diff --git a/hotspot/src/share/vm/oops/compiledICHolder.cpp b/hotspot/src/share/vm/oops/compiledICHolder.cpp index 9e01e4ea705..55397d06c10 100644 --- a/hotspot/src/share/vm/oops/compiledICHolder.cpp +++ b/hotspot/src/share/vm/oops/compiledICHolder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "oops/compiledICHolder.hpp" #include "oops/klass.hpp" #include "oops/method.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" volatile int CompiledICHolder::_live_count; volatile int CompiledICHolder::_live_not_claimed_count; diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp index ee2425fc615..a30d19dd685 100644 --- a/hotspot/src/share/vm/oops/cpCache.cpp +++ b/hotspot/src/share/vm/oops/cpCache.cpp @@ -32,7 +32,7 @@ #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "prims/methodHandles.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/orderAccess.inline.hpp" #include "utilities/macros.hpp" diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 1e7b1b1bb3d..d6b2323af28 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -56,7 +56,7 @@ #include "prims/jvmtiRedefineClasses.hpp" #include "prims/jvmtiThreadState.hpp" #include "prims/methodComparator.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index d7fb8924e71..38a613d93b7 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -36,7 +36,7 @@ #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "trace/traceMacros.hpp" #include "utilities/macros.hpp" diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp index fe3cd508a9f..578bcc4e520 100644 --- a/hotspot/src/share/vm/oops/oop.inline.hpp +++ b/hotspot/src/share/vm/oops/oop.inline.hpp @@ -36,7 +36,7 @@ #include "oops/klass.inline.hpp" #include "oops/markOop.inline.hpp" #include "oops/oop.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/os.hpp" #include "utilities/macros.hpp" diff --git a/hotspot/src/share/vm/oops/symbol.cpp b/hotspot/src/share/vm/oops/symbol.cpp index 74d56db1e7d..5f4ad042e75 100644 --- a/hotspot/src/share/vm/oops/symbol.cpp +++ b/hotspot/src/share/vm/oops/symbol.cpp @@ -29,7 +29,7 @@ #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "oops/symbol.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" Symbol::Symbol(const u1* name, int length, int refcount) { @@ -229,24 +229,25 @@ unsigned int Symbol::new_hash(juint seed) { } void Symbol::increment_refcount() { - // Only increment the refcount if positive. If negative either + // Only increment the refcount if non-negative. If negative either // overflow has occurred or it is a permanent symbol in a read only // shared archive. - if (_refcount >= 0) { + if (_refcount >= 0) { // not a permanent symbol Atomic::inc(&_refcount); NOT_PRODUCT(Atomic::inc(&_total_count);) } } void Symbol::decrement_refcount() { - if (_refcount >= 0) { - Atomic::dec(&_refcount); + if (_refcount >= 0) { // not a permanent symbol + jshort new_value = Atomic::add(-1, &_refcount); #ifdef ASSERT - if (_refcount < 0) { + if (new_value == -1) { // we have transitioned from 0 -> -1 print(); assert(false, "reference count underflow for symbol"); } #endif + (void)new_value; } } diff --git a/hotspot/src/share/vm/oops/symbol.hpp b/hotspot/src/share/vm/oops/symbol.hpp index b6801f03f9c..468640caa24 100644 --- a/hotspot/src/share/vm/oops/symbol.hpp +++ b/hotspot/src/share/vm/oops/symbol.hpp @@ -26,8 +26,8 @@ #define SHARE_VM_OOPS_SYMBOL_HPP #include "memory/allocation.hpp" -#include "runtime/atomic.hpp" #include "utilities/exceptions.hpp" +#include "utilities/macros.hpp" #include "utilities/utf8.hpp" // A Symbol is a canonicalized string. diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp index 9882317cf0b..4c5ee040585 100644 --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp @@ -508,7 +508,7 @@ void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, #if INCLUDE_TRACE EventCompilerInlining event; if (event.should_commit()) { - event.set_compileID(C->compile_id()); + event.set_compileId(C->compile_id()); event.set_message(inline_msg); event.set_succeeded(success); event.set_bci(caller_bci); diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index f2f8c4630db..651166c50d8 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -729,7 +729,7 @@ class Compile : public Phase { if (event.should_commit()) { event.set_starttime(C->_latest_stage_start_counter); event.set_phase((u1) cpt); - event.set_compileID(C->_compile_id); + event.set_compileId(C->_compile_id); event.set_phaseLevel(level); event.commit(); } @@ -748,7 +748,7 @@ class Compile : public Phase { if (event.should_commit()) { event.set_starttime(C->_latest_stage_start_counter); event.set_phase((u1) PHASE_END); - event.set_compileID(C->_compile_id); + event.set_compileId(C->_compile_id); event.set_phaseLevel(level); event.commit(); } diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp index 3626009a15c..d0a3c4b8fd3 100644 --- a/hotspot/src/share/vm/opto/runtime.cpp +++ b/hotspot/src/share/vm/opto/runtime.cpp @@ -60,7 +60,7 @@ #include "opto/runtime.hpp" #include "opto/subnode.hpp" #include "prims/jvmtiThreadState.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/fprofiler.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index 878bd6623a5..f083a74c7aa 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -59,7 +59,7 @@ #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/fprofiler.hpp" diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index 79c450b002d..b66c22bf74e 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -54,7 +54,7 @@ #include "prims/privilegedStack.hpp" #include "prims/stackwalk.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" diff --git a/hotspot/src/share/vm/prims/jvmtiImpl.cpp b/hotspot/src/share/vm/prims/jvmtiImpl.cpp index 398f5720b13..20905222276 100644 --- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp +++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ #include "prims/jvmtiEventController.inline.hpp" #include "prims/jvmtiImpl.hpp" #include "prims/jvmtiRedefineClasses.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/deoptimization.hpp" #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp" diff --git a/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp b/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp index 003f12f0c0a..3ce6cf760b4 100644 --- a/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "prims/jvmtiRawMonitor.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/thread.inline.hpp" diff --git a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp index fa9d5131e31..b2cf5660865 100644 --- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp +++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp @@ -3119,6 +3119,11 @@ inline bool VM_HeapWalkOperation::collect_stack_roots(JavaThread* java_thread, } } + // Follow oops from compiled nmethod + if (jvf->cb() != NULL && jvf->cb()->is_nmethod()) { + blk->set_context(thread_tag, tid, depth, method); + jvf->cb()->as_nmethod()->oops_do(blk); + } } else { blk->set_context(thread_tag, tid, depth, method); if (is_top_frame) { diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp index d7721ec5f55..55a968170a5 100644 --- a/hotspot/src/share/vm/prims/unsafe.cpp +++ b/hotspot/src/share/vm/prims/unsafe.cpp @@ -32,7 +32,7 @@ #include "prims/jni.h" #include "prims/jvm.h" #include "prims/unsafe.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/orderAccess.inline.hpp" @@ -1047,7 +1047,7 @@ UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, if (event.should_commit()) { oop obj = thread->current_park_blocker(); - event.set_klass((obj != NULL) ? obj->klass() : NULL); + event.set_parkedClass((obj != NULL) ? obj->klass() : NULL); event.set_timeout(time); event.set_address((obj != NULL) ? (TYPE_ADDRESS) cast_from_oop(obj) : 0); event.commit(); diff --git a/hotspot/src/share/vm/runtime/atomic.hpp b/hotspot/src/share/vm/runtime/atomic.hpp index c71a2d3f3a5..ccf24669fa1 100644 --- a/hotspot/src/share/vm/runtime/atomic.hpp +++ b/hotspot/src/share/vm/runtime/atomic.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ #define SHARE_VM_RUNTIME_ATOMIC_HPP #include "memory/allocation.hpp" +#include "utilities/macros.hpp" enum cmpxchg_memory_order { memory_order_relaxed, @@ -75,6 +76,7 @@ class Atomic : AllStatic { // Atomically add to a location. Returns updated value. add*() provide: // add-value-to-dest + inline static jshort add (jshort add_value, volatile jshort* dest); inline static jint add (jint add_value, volatile jint* dest); inline static size_t add (size_t add_value, volatile size_t* dest); inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest); @@ -119,24 +121,120 @@ class Atomic : AllStatic { inline static void* cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order = memory_order_conservative); }; -// To use Atomic::inc(jshort* dest) and Atomic::dec(jshort* dest), the address must be specially -// aligned, such that (*dest) occupies the upper 16 bits of an aligned 32-bit word. The best way to -// achieve is to place your short value next to another short value, which doesn't need atomic ops. -// -// Example -// ATOMIC_SHORT_PAIR( -// volatile short _refcount, // needs atomic operation -// unsigned short _length // number of UTF8 characters in the symbol (does not need atomic op) -// ); +// platform specific in-line definitions - must come before shared definitions -#ifdef VM_LITTLE_ENDIAN - #define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \ - non_atomic_decl; \ - atomic_decl -#else - #define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \ - atomic_decl; \ - non_atomic_decl +#include OS_CPU_HEADER(atomic) + +// shared in-line definitions + +// size_t casts... +#if (SIZE_MAX != UINTPTR_MAX) +#error size_t is not WORD_SIZE, interesting platform, but missing implementation here #endif +inline size_t Atomic::add(size_t add_value, volatile size_t* dest) { + return (size_t) add_ptr((intptr_t) add_value, (volatile intptr_t*) dest); +} + +inline void Atomic::inc(volatile size_t* dest) { + inc_ptr((volatile intptr_t*) dest); +} + +inline void Atomic::dec(volatile size_t* dest) { + dec_ptr((volatile intptr_t*) dest); +} + +#ifndef VM_HAS_SPECIALIZED_CMPXCHG_BYTE +/* + * This is the default implementation of byte-sized cmpxchg. It emulates jbyte-sized cmpxchg + * in terms of jint-sized cmpxchg. Platforms may override this by defining their own inline definition + * as well as defining VM_HAS_SPECIALIZED_CMPXCHG_BYTE. This will cause the platform specific + * implementation to be used instead. + */ +inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, + jbyte compare_value, cmpxchg_memory_order order) { + STATIC_ASSERT(sizeof(jbyte) == 1); + volatile jint* dest_int = + static_cast(align_ptr_down(dest, sizeof(jint))); + size_t offset = pointer_delta(dest, dest_int, 1); + jint cur = *dest_int; + jbyte* cur_as_bytes = reinterpret_cast(&cur); + + // current value may not be what we are looking for, so force it + // to that value so the initial cmpxchg will fail if it is different + cur_as_bytes[offset] = compare_value; + + // always execute a real cmpxchg so that we get the required memory + // barriers even on initial failure + do { + // value to swap in matches current value ... + jint new_value = cur; + // ... except for the one jbyte we want to update + reinterpret_cast(&new_value)[offset] = exchange_value; + + jint res = cmpxchg(new_value, dest_int, cur, order); + if (res == cur) break; // success + + // at least one jbyte in the jint changed value, so update + // our view of the current jint + cur = res; + // if our jbyte is still as cur we loop and try again + } while (cur_as_bytes[offset] == compare_value); + + return cur_as_bytes[offset]; +} + +#endif // VM_HAS_SPECIALIZED_CMPXCHG_BYTE + +inline unsigned Atomic::xchg(unsigned int exchange_value, volatile unsigned int* dest) { + assert(sizeof(unsigned int) == sizeof(jint), "more work to do"); + return (unsigned int)Atomic::xchg((jint)exchange_value, (volatile jint*)dest); +} + +inline unsigned Atomic::cmpxchg(unsigned int exchange_value, + volatile unsigned int* dest, unsigned int compare_value, + cmpxchg_memory_order order) { + assert(sizeof(unsigned int) == sizeof(jint), "more work to do"); + return (unsigned int)Atomic::cmpxchg((jint)exchange_value, (volatile jint*)dest, + (jint)compare_value, order); +} + +inline jlong Atomic::add(jlong add_value, volatile jlong* dest) { + jlong old = load(dest); + jlong new_value = old + add_value; + while (old != cmpxchg(new_value, dest, old)) { + old = load(dest); + new_value = old + add_value; + } + return old; +} + +inline jshort Atomic::add(jshort add_value, volatile jshort* dest) { + // Most platforms do not support atomic add on a 2-byte value. However, + // if the value occupies the most significant 16 bits of an aligned 32-bit + // word, then we can do this with an atomic add of (add_value << 16) + // to the 32-bit word. + // + // The least significant parts of this 32-bit word will never be affected, even + // in case of overflow/underflow. + // + // Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment. +#ifdef VM_LITTLE_ENDIAN + assert((intx(dest) & 0x03) == 0x02, "wrong alignment"); + jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest-1)); +#else + assert((intx(dest) & 0x03) == 0x00, "wrong alignment"); + jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest)); +#endif + return (jshort)(new_value >> 16); // preserves sign +} + +inline void Atomic::inc(volatile jshort* dest) { + (void)add(1, dest); +} + +inline void Atomic::dec(volatile jshort* dest) { + (void)add(-1, dest); +} + #endif // SHARE_VM_RUNTIME_ATOMIC_HPP diff --git a/hotspot/src/share/vm/runtime/atomic.inline.hpp b/hotspot/src/share/vm/runtime/atomic.inline.hpp deleted file mode 100644 index 690be7daaf1..00000000000 --- a/hotspot/src/share/vm/runtime/atomic.inline.hpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP -#define SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "utilities/macros.hpp" - -#include OS_CPU_HEADER_INLINE(atomic) - -// size_t casts... -#if (SIZE_MAX != UINTPTR_MAX) -#error size_t is not WORD_SIZE, interesting platform, but missing implementation here -#endif - -inline size_t Atomic::add(size_t add_value, volatile size_t* dest) { - return (size_t) add_ptr((intptr_t) add_value, (volatile intptr_t*) dest); -} - -inline void Atomic::inc(volatile size_t* dest) { - inc_ptr((volatile intptr_t*) dest); -} - -inline void Atomic::dec(volatile size_t* dest) { - dec_ptr((volatile intptr_t*) dest); -} - -#ifndef VM_HAS_SPECIALIZED_CMPXCHG_BYTE -/* - * This is the default implementation of byte-sized cmpxchg. It emulates jbyte-sized cmpxchg - * in terms of jint-sized cmpxchg. Platforms may override this by defining their own inline definition - * as well as defining VM_HAS_SPECIALIZED_CMPXCHG_BYTE. This will cause the platform specific - * implementation to be used instead. - */ -inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte *dest, jbyte comparand, cmpxchg_memory_order order) -{ - assert(sizeof(jbyte) == 1, "assumption."); - uintptr_t dest_addr = (uintptr_t)dest; - uintptr_t offset = dest_addr % sizeof(jint); - volatile jint* dest_int = (volatile jint*)(dest_addr - offset); - jint cur = *dest_int; - jbyte* cur_as_bytes = (jbyte*)(&cur); - jint new_val = cur; - jbyte* new_val_as_bytes = (jbyte*)(&new_val); - new_val_as_bytes[offset] = exchange_value; - while (cur_as_bytes[offset] == comparand) { - jint res = cmpxchg(new_val, dest_int, cur, order); - if (res == cur) break; - cur = res; - new_val = cur; - new_val_as_bytes[offset] = exchange_value; - } - return cur_as_bytes[offset]; -} -#endif // VM_HAS_SPECIALIZED_CMPXCHG_BYTE - -inline unsigned Atomic::xchg(unsigned int exchange_value, volatile unsigned int* dest) { - assert(sizeof(unsigned int) == sizeof(jint), "more work to do"); - return (unsigned int)Atomic::xchg((jint)exchange_value, (volatile jint*)dest); -} - -inline unsigned Atomic::cmpxchg(unsigned int exchange_value, - volatile unsigned int* dest, unsigned int compare_value, - cmpxchg_memory_order order) { - assert(sizeof(unsigned int) == sizeof(jint), "more work to do"); - return (unsigned int)Atomic::cmpxchg((jint)exchange_value, (volatile jint*)dest, - (jint)compare_value, order); -} - -inline jlong Atomic::add(jlong add_value, volatile jlong* dest) { - jlong old = load(dest); - jlong new_value = old + add_value; - while (old != cmpxchg(new_value, dest, old)) { - old = load(dest); - new_value = old + add_value; - } - return old; -} - -inline void Atomic::inc(volatile short* dest) { - // Most platforms do not support atomic increment on a 2-byte value. However, - // if the value occupies the most significant 16 bits of an aligned 32-bit - // word, then we can do this with an atomic add of 0x10000 to the 32-bit word. - // - // The least significant parts of this 32-bit word will never be affected, even - // in case of overflow/underflow. - // - // Use the ATOMIC_SHORT_PAIR macro to get the desired alignment. -#ifdef VM_LITTLE_ENDIAN - assert((intx(dest) & 0x03) == 0x02, "wrong alignment"); - (void)Atomic::add(0x10000, (volatile int*)(dest-1)); -#else - assert((intx(dest) & 0x03) == 0x00, "wrong alignment"); - (void)Atomic::add(0x10000, (volatile int*)(dest)); -#endif -} - -inline void Atomic::dec(volatile short* dest) { -#ifdef VM_LITTLE_ENDIAN - assert((intx(dest) & 0x03) == 0x02, "wrong alignment"); - (void)Atomic::add(-0x10000, (volatile int*)(dest-1)); -#else - assert((intx(dest) & 0x03) == 0x00, "wrong alignment"); - (void)Atomic::add(-0x10000, (volatile int*)(dest)); -#endif -} - -#endif // SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP diff --git a/hotspot/src/share/vm/runtime/biasedLocking.cpp b/hotspot/src/share/vm/runtime/biasedLocking.cpp index 1d5fd538b8d..84349601766 100644 --- a/hotspot/src/share/vm/runtime/biasedLocking.cpp +++ b/hotspot/src/share/vm/runtime/biasedLocking.cpp @@ -28,7 +28,7 @@ #include "oops/klass.inline.hpp" #include "oops/markOop.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/basicLock.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/task.hpp" diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp index b0a0d798bd7..68ec6b058cc 100644 --- a/hotspot/src/share/vm/runtime/globals.cpp +++ b/hotspot/src/share/vm/runtime/globals.cpp @@ -975,8 +975,8 @@ template static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) { E e; e.set_name(name); - e.set_old_value(old_value); - e.set_new_value(new_value); + e.set_oldValue(old_value); + e.set_newValue(new_value); e.set_origin(origin); e.commit(); } diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 20b22a7cc9b..1978313e48e 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2242,7 +2242,7 @@ public: "in a comma separated string. Sub-systems are: " \ "threads, heap, symbol_table, string_table, codecache, " \ "dictionary, classloader_data_graph, metaspace, jni_handles, " \ - "c-heap, codecache_oops") \ + "codecache_oops") \ \ diagnostic(bool, GCParallelVerificationEnabled, true, \ "Enable parallel memory system verification") \ @@ -3008,16 +3008,6 @@ public: notproduct(intx, ZombieALotInterval, 5, \ "Number of exits until ZombieALot kicks in") \ \ - diagnostic(intx, MallocVerifyInterval, 0, \ - "If non-zero, verify C heap after every N calls to " \ - "malloc/realloc/free") \ - range(0, max_intx) \ - \ - diagnostic(intx, MallocVerifyStart, 0, \ - "If non-zero, start verifying C heap after Nth call to " \ - "malloc/realloc/free") \ - range(0, max_intx) \ - \ diagnostic(uintx, MallocMaxTestWords, 0, \ "If non-zero, maximum number of words that malloc/realloc can " \ "allocate (for testing only)") \ diff --git a/hotspot/src/share/vm/runtime/handles.cpp b/hotspot/src/share/vm/runtime/handles.cpp index baa4e2f508d..a8b6f8b9f01 100644 --- a/hotspot/src/share/vm/runtime/handles.cpp +++ b/hotspot/src/share/vm/runtime/handles.cpp @@ -26,7 +26,7 @@ #include "memory/allocation.inline.hpp" #include "oops/constantPool.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/thread.inline.hpp" diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.cpp b/hotspot/src/share/vm/runtime/interfaceSupport.cpp index cd0d20a65e2..db7ad9ce905 100644 --- a/hotspot/src/share/vm/runtime/interfaceSupport.cpp +++ b/hotspot/src/share/vm/runtime/interfaceSupport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/genCollectedHeap.hpp" #include "memory/resourceArea.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/orderAccess.inline.hpp" diff --git a/hotspot/src/share/vm/runtime/mutex.cpp b/hotspot/src/share/vm/runtime/mutex.cpp index 0fc65b89fb7..86e11841cda 100644 --- a/hotspot/src/share/vm/runtime/mutex.cpp +++ b/hotspot/src/share/vm/runtime/mutex.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/mutex.hpp" #include "runtime/orderAccess.inline.hpp" diff --git a/hotspot/src/share/vm/runtime/objectMonitor.cpp b/hotspot/src/share/vm/runtime/objectMonitor.cpp index 7590d90c9e7..e765ee011eb 100644 --- a/hotspot/src/share/vm/runtime/objectMonitor.cpp +++ b/hotspot/src/share/vm/runtime/objectMonitor.cpp @@ -27,7 +27,7 @@ #include "memory/resourceArea.hpp" #include "oops/markOop.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/mutexLocker.hpp" @@ -390,7 +390,7 @@ void ObjectMonitor::enter(TRAPS) { } if (event.should_commit()) { - event.set_klass(((oop)this->object())->klass()); + event.set_monitorClass(((oop)this->object())->klass()); event.set_previousOwner((TYPE_THREAD)_previous_owner_tid); event.set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr())); event.commit(); @@ -1381,7 +1381,7 @@ void ObjectMonitor::post_monitor_wait_event(EventJavaMonitorWait* event, jlong timeout, bool timedout) { assert(event != NULL, "invariant"); - event->set_klass(((oop)this->object())->klass()); + event->set_monitorClass(((oop)this->object())->klass()); event->set_timeout(timeout); event->set_address((TYPE_ADDRESS)this->object_addr()); event->set_notifier(notifier_tid); diff --git a/hotspot/src/share/vm/runtime/orderAccess.inline.hpp b/hotspot/src/share/vm/runtime/orderAccess.inline.hpp index 0907a43d71a..f7830c400af 100644 --- a/hotspot/src/share/vm/runtime/orderAccess.inline.hpp +++ b/hotspot/src/share/vm/runtime/orderAccess.inline.hpp @@ -26,7 +26,7 @@ #ifndef SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP #define SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "utilities/macros.hpp" diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index e9ff778760c..7089f6a6629 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -44,7 +44,7 @@ #include "prims/jvm_misc.hpp" #include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/frame.inline.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/java.hpp" @@ -596,8 +596,6 @@ void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) { } #endif - NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); - // For the test flag -XX:MallocMaxTestWords if (has_reached_max_malloc_test_peak(size)) { return NULL; @@ -658,7 +656,6 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCa // NMT support void* membase = MemTracker::malloc_base(memblock); verify_memory(membase); - NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); if (size == 0) { return NULL; } @@ -695,7 +692,6 @@ void os::free(void *memblock) { } void* membase = MemTracker::record_free(memblock); verify_memory(membase); - NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); GuardedMemory guarded(membase); size_t size = guarded.get_user_size(); diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index 0cf1bd6e068..431e7b2a985 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -709,7 +709,6 @@ class os: AllStatic { static void* realloc (void *memblock, size_t size, MEMFLAGS flag); static void free (void *memblock); - static bool check_heap(bool force = false); // verify C heap integrity static char* strdup(const char *, MEMFLAGS flags = mtInternal); // Like strdup // Like strdup, but exit VM when strdup() returns NULL static char* strdup_check_oom(const char*, MEMFLAGS flags = mtInternal); diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index 7b2753e516f..ae574a4edbf 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -446,7 +446,7 @@ static bool can_relax_access_check_for(const Klass* accessor, (accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION && accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) { return classloader_only && - Verifier::relax_verify_for(accessor_ik->class_loader()) && + Verifier::relax_access_for(accessor_ik->class_loader()) && accessor_ik->protection_domain() == accessee_ik->protection_domain() && accessor_ik->class_loader() == accessee_ik->class_loader(); } diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index 28f00fdbe03..50cae3cc396 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -39,7 +39,7 @@ #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" @@ -173,7 +173,7 @@ void SafepointSynchronize::begin() { // block itself when it attempts transitions to a new state. // { - EventSafepointStateSync sync_event; + EventSafepointStateSynchronization sync_event; int initial_running = 0; _state = _synchronizing; diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index 11e7f834dba..c2bf3c00778 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -49,7 +49,7 @@ #include "prims/methodHandles.hpp" #include "prims/nativeLookup.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/handles.inline.hpp" diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp index 16cf5cde781..60fc91c43e6 100644 --- a/hotspot/src/share/vm/runtime/sweeper.cpp +++ b/hotspot/src/share/vm/runtime/sweeper.cpp @@ -30,7 +30,7 @@ #include "compiler/compileBroker.hpp" #include "memory/resourceArea.hpp" #include "oops/method.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/orderAccess.inline.hpp" @@ -485,7 +485,7 @@ void NMethodSweeper::sweep_code_cache() { if (event.should_commit()) { event.set_starttime(sweep_start_counter); event.set_endtime(sweep_end_counter); - event.set_sweepIndex(_traversals); + event.set_sweepId(_traversals); event.set_sweptCount(swept_count); event.set_flushedCount(flushed_count); event.set_zombifiedCount(zombified_count); diff --git a/hotspot/src/share/vm/runtime/synchronizer.cpp b/hotspot/src/share/vm/runtime/synchronizer.cpp index ef8a271106a..b9004d62860 100644 --- a/hotspot/src/share/vm/runtime/synchronizer.cpp +++ b/hotspot/src/share/vm/runtime/synchronizer.cpp @@ -30,7 +30,7 @@ #include "memory/resourceArea.hpp" #include "oops/markOop.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" @@ -1819,7 +1819,7 @@ static void post_monitor_inflate_event(EventJavaMonitorInflate& event, const ObjectSynchronizer::InflateCause cause) { #if INCLUDE_TRACE assert(event.should_commit(), "check outside"); - event.set_klass(obj->klass()); + event.set_monitorClass(obj->klass()); event.set_address((TYPE_ADDRESS)(uintptr_t)(void*)obj); event.set_cause((u1)cause); event.commit(); diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index c87de622492..f3481dad820 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -57,7 +57,7 @@ #include "prims/jvmtiThreadState.hpp" #include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/commandLineFlagConstraintList.hpp" #include "runtime/commandLineFlagWriteableList.hpp" diff --git a/hotspot/src/share/vm/runtime/thread.inline.hpp b/hotspot/src/share/vm/runtime/thread.inline.hpp index b8c7a142612..bb1fb9c80eb 100644 --- a/hotspot/src/share/vm/runtime/thread.inline.hpp +++ b/hotspot/src/share/vm/runtime/thread.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #define SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.inline.hpp" #include "runtime/thread.hpp" diff --git a/hotspot/src/share/vm/runtime/vmThread.cpp b/hotspot/src/share/vm/runtime/vmThread.cpp index d7c0137a1f4..5b3fda00fd9 100644 --- a/hotspot/src/share/vm/runtime/vmThread.cpp +++ b/hotspot/src/share/vm/runtime/vmThread.cpp @@ -279,7 +279,6 @@ void VMThread::run() { HandleMark hm(VMThread::vm_thread()); // Among other things, this ensures that Eden top is correct. Universe::heap()->prepare_for_verify(); - os::check_heap(); // Silent verification so as not to pollute normal output, // unless we really asked for it. Universe::verify(); diff --git a/hotspot/src/share/vm/services/mallocTracker.cpp b/hotspot/src/share/vm/services/mallocTracker.cpp index ea399401115..16a0cde04c4 100644 --- a/hotspot/src/share/vm/services/mallocTracker.cpp +++ b/hotspot/src/share/vm/services/mallocTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "runtime/atomic.hpp" -#include "runtime/atomic.inline.hpp" #include "services/mallocSiteTable.hpp" #include "services/mallocTracker.hpp" #include "services/mallocTracker.inline.hpp" diff --git a/hotspot/src/share/vm/services/memTracker.hpp b/hotspot/src/share/vm/services/memTracker.hpp index f05d39f3b4c..1682cb91f42 100644 --- a/hotspot/src/share/vm/services/memTracker.hpp +++ b/hotspot/src/share/vm/services/memTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,6 @@ class MemTracker : AllStatic { #else -#include "runtime/atomic.hpp" #include "runtime/threadCritical.hpp" #include "services/mallocTracker.hpp" #include "services/virtualMemoryTracker.hpp" diff --git a/hotspot/src/share/vm/services/threadService.cpp b/hotspot/src/share/vm/services/threadService.cpp index f89ff8b87bc..3bd7a9f70ca 100644 --- a/hotspot/src/share/vm/services/threadService.cpp +++ b/hotspot/src/share/vm/services/threadService.cpp @@ -31,7 +31,7 @@ #include "oops/instanceKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" #include "runtime/thread.hpp" diff --git a/hotspot/src/share/vm/services/virtualMemoryTracker.cpp b/hotspot/src/share/vm/services/virtualMemoryTracker.cpp index 964af28bf5b..c21aa542b2d 100644 --- a/hotspot/src/share/vm/services/virtualMemoryTracker.cpp +++ b/hotspot/src/share/vm/services/virtualMemoryTracker.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "runtime/threadCritical.hpp" #include "services/memTracker.hpp" diff --git a/hotspot/src/share/vm/shark/sharkRuntime.cpp b/hotspot/src/share/vm/shark/sharkRuntime.cpp index 454c87f657e..fff58022612 100644 --- a/hotspot/src/share/vm/shark/sharkRuntime.cpp +++ b/hotspot/src/share/vm/shark/sharkRuntime.cpp @@ -24,7 +24,7 @@ */ #include "precompiled.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/deoptimization.hpp" #include "runtime/thread.hpp" diff --git a/hotspot/src/share/vm/trace/traceDataTypes.hpp b/hotspot/src/share/vm/trace/traceDataTypes.hpp index 5df07eb1bbe..31be0589f3f 100644 --- a/hotspot/src/share/vm/trace/traceDataTypes.hpp +++ b/hotspot/src/share/vm/trace/traceDataTypes.hpp @@ -32,7 +32,6 @@ enum { CONTENT_TYPE_NONE = 0, CONTENT_TYPE_CLASS = 20, - CONTENT_TYPE_UTF8 = 21, CONTENT_TYPE_THREAD = 22, CONTENT_TYPE_STACKTRACE = 23, CONTENT_TYPE_BYTES = 24, diff --git a/hotspot/src/share/vm/trace/traceMacros.hpp b/hotspot/src/share/vm/trace/traceMacros.hpp index a69acef1f70..67f71f3493c 100644 --- a/hotspot/src/share/vm/trace/traceMacros.hpp +++ b/hotspot/src/share/vm/trace/traceMacros.hpp @@ -30,7 +30,6 @@ typedef u8 traceid; #define EVENT_THREAD_EXIT(thread) #define EVENT_THREAD_DESTRUCT(thread) #define TRACE_KLASS_CREATION(k, p, t) -#define TRACE_KLASS_DEFINITION(k, t) #define TRACE_INIT_KLASS_ID(k) #define TRACE_REMOVE_KLASS_ID(k) diff --git a/hotspot/src/share/vm/trace/traceevents.xml b/hotspot/src/share/vm/trace/traceevents.xml index 10671cfc136..f3b6447127a 100644 --- a/hotspot/src/share/vm/trace/traceevents.xml +++ b/hotspot/src/share/vm/trace/traceevents.xml @@ -76,111 +76,112 @@ Declares a structure type that can be used in other events. - + - + - + - + - + - + - - - + + + - + + has_thread="true" has_stacktrace="true" is_instant="false"> + has_thread="true" has_stacktrace="true" is_instant="true"> + has_thread="true" is_instant="true"> - - - + is_instant="true"> + + + - - - + is_instant="true"> + + + - - - + is_instant="true"> + + + - - - + is_instant="true"> + + + - - - + is_instant="true"> + + + - - - + is_instant="true"> + + + - - - + is_instant="true"> + + + @@ -200,7 +201,7 @@ Declares a structure type that can be used in other events. - + @@ -213,7 +214,7 @@ Declares a structure type that can be used in other events. - + @@ -244,7 +245,7 @@ Declares a structure type that can be used in other events. - + @@ -258,7 +259,7 @@ Declares a structure type that can be used in other events. - + @@ -271,7 +272,7 @@ Declares a structure type that can be used in other events. - + @@ -280,53 +281,53 @@ Declares a structure type that can be used in other events. - - + - - + - - + - - + - - + - - - - - + + + + + - - + + - - + + @@ -334,7 +335,7 @@ Declares a structure type that can be used in other events. - + @@ -347,14 +348,14 @@ Declares a structure type that can be used in other events. - - + + - - + + @@ -366,48 +367,48 @@ Declares a structure type that can be used in other events. - - + + - - + + - - + + - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + + - - + + @@ -415,10 +416,10 @@ Declares a structure type that can be used in other events. - - + + @@ -426,81 +427,76 @@ Declares a structure type that can be used in other events. - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - + - + + description="Information about a G1 heap region type change" is_instant="true"> - - + + - - - - - + + has_thread="true" is_requestable="false" is_constant="false"> - + @@ -509,39 +505,39 @@ Declares a structure type that can be used in other events. + has_thread="true" is_requestable="false" is_constant="false"> - + - - - + + + - - - - + + + + - + has_thread="true" is_instant="true"> + - + - + - + has_thread="true" is_requestable="false" is_constant="false"> + @@ -550,7 +546,7 @@ Declares a structure type that can be used in other events. + has_thread="true" is_requestable="false" is_constant="false" is_instant="true"> @@ -564,14 +560,14 @@ Declares a structure type that can be used in other events. - + - - + @@ -579,46 +575,46 @@ Declares a structure type that can be used in other events. - + - + - - + + - + + description="Execution of a VM Operation" has_thread="true"> - - - - + + + + - - + + - - + + diff --git a/hotspot/src/share/vm/trace/tracerelationdecls.xml b/hotspot/src/share/vm/trace/tracerelationdecls.xml index 06a83aab418..472c5c61c8a 100644 --- a/hotspot/src/share/vm/trace/tracerelationdecls.xml +++ b/hotspot/src/share/vm/trace/tracerelationdecls.xml @@ -27,9 +27,9 @@ - - - - - + + + + + diff --git a/hotspot/src/share/vm/trace/tracetypes.xml b/hotspot/src/share/vm/trace/tracetypes.xml index c4c3ddbf959..003b9016bac 100644 --- a/hotspot/src/share/vm/trace/tracetypes.xml +++ b/hotspot/src/share/vm/trace/tracetypes.xml @@ -43,7 +43,7 @@ jvm_type means defining a new one for our own use. Example: (GcMode) - + This creates a content type CONTENT_TYPE_GCMODE @@ -61,131 +61,131 @@ Now we can use the content + data type in declaring event fields. - - - - + + + + - + - + - + - + - - + + - - + - + - + - + - + - + - + - + - + - + - + - - + - + - + - + - + - + + type="U8" jvm_type="MODULE"> - + + type="U8" jvm_type="PACKAGE"> @@ -288,8 +288,9 @@ Now we can use the content + data type in declaring event fields. - - + @@ -325,8 +326,7 @@ Now we can use the content + data type in declaring event fields. + type="u8" sizeop="sizeof(u8)"/> - + - + - + - + - + - + - + - + diff --git a/hotspot/src/share/vm/utilities/accessFlags.cpp b/hotspot/src/share/vm/utilities/accessFlags.cpp index 9cc0f1bb95a..17c47b3e363 100644 --- a/hotspot/src/share/vm/utilities/accessFlags.cpp +++ b/hotspot/src/share/vm/utilities/accessFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/accessFlags.hpp" void AccessFlags::atomic_set_bits(jint bits) { diff --git a/hotspot/src/share/vm/utilities/bitMap.cpp b/hotspot/src/share/vm/utilities/bitMap.cpp index c9c8c73a92c..b0b7d567f8e 100644 --- a/hotspot/src/share/vm/utilities/bitMap.cpp +++ b/hotspot/src/share/vm/utilities/bitMap.cpp @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/bitMap.inline.hpp" #include "utilities/copy.hpp" #include "utilities/debug.hpp" diff --git a/hotspot/src/share/vm/utilities/bitMap.inline.hpp b/hotspot/src/share/vm/utilities/bitMap.inline.hpp index 1b3a9bb11f0..ae890e90cde 100644 --- a/hotspot/src/share/vm/utilities/bitMap.inline.hpp +++ b/hotspot/src/share/vm/utilities/bitMap.inline.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_VM_UTILITIES_BITMAP_INLINE_HPP #define SHARE_VM_UTILITIES_BITMAP_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/bitMap.hpp" inline void BitMap::set_bit(idx_t bit) { diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp index 95fd3b67e44..d48479c303d 100644 --- a/hotspot/src/share/vm/utilities/debug.cpp +++ b/hotspot/src/share/vm/utilities/debug.cpp @@ -38,7 +38,7 @@ #include "oops/oop.inline.hpp" #include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/frame.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index aec8ab9d7bc..a7ebde3ed54 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -327,11 +327,12 @@ inline address_word castable_address(void* x) { return address_w // and then additions like // ... top() + size ... // are safe because we know that top() is at least size below end(). -inline size_t pointer_delta(const void* left, - const void* right, +inline size_t pointer_delta(const volatile void* left, + const volatile void* right, size_t element_size) { return (((uintptr_t) left) - ((uintptr_t) right)) / element_size; } + // A version specialized for HeapWord*'s. inline size_t pointer_delta(const HeapWord* left, const HeapWord* right) { return pointer_delta(left, right, sizeof(HeapWord)); @@ -516,6 +517,10 @@ inline void* align_ptr_down(void* ptr, size_t alignment) { return (void*)align_size_down((intptr_t)ptr, (intptr_t)alignment); } +inline volatile void* align_ptr_down(volatile void* ptr, size_t alignment) { + return (volatile void*)align_size_down((intptr_t)ptr, (intptr_t)alignment); +} + // Align metaspace objects by rounding up to natural word boundary inline intptr_t align_metadata_size(intptr_t size) { diff --git a/hotspot/src/share/vm/utilities/histogram.cpp b/hotspot/src/share/vm/utilities/histogram.cpp index f4d7091cd22..6787fce2f33 100644 --- a/hotspot/src/share/vm/utilities/histogram.cpp +++ b/hotspot/src/share/vm/utilities/histogram.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/histogram.hpp" #ifdef ASSERT diff --git a/hotspot/src/share/vm/utilities/macros.hpp b/hotspot/src/share/vm/utilities/macros.hpp index ebcaaee043d..9904650b01d 100644 --- a/hotspot/src/share/vm/utilities/macros.hpp +++ b/hotspot/src/share/vm/utilities/macros.hpp @@ -486,4 +486,24 @@ #define OS_CPU_HEADER(basename) XSTR(OS_CPU_HEADER_STEM(basename).hpp) #define OS_CPU_HEADER_INLINE(basename) XSTR(OS_CPU_HEADER_STEM(basename).inline.hpp) +// To use Atomic::inc(jshort* dest) and Atomic::dec(jshort* dest), the address must be specially +// aligned, such that (*dest) occupies the upper 16 bits of an aligned 32-bit word. The best way to +// achieve is to place your short value next to another short value, which doesn't need atomic ops. +// +// Example +// ATOMIC_SHORT_PAIR( +// volatile short _refcount, // needs atomic operation +// unsigned short _length // number of UTF8 characters in the symbol (does not need atomic op) +// ); + +#ifdef VM_LITTLE_ENDIAN + #define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \ + non_atomic_decl; \ + atomic_decl +#else + #define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \ + atomic_decl; \ + non_atomic_decl +#endif + #endif // SHARE_VM_UTILITIES_MACROS_HPP diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index 4a2ac95995b..8ae3d5222e3 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -31,7 +31,7 @@ #include "logging/logConfiguration.hpp" #include "prims/whitebox.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/frame.inline.hpp" #include "runtime/init.hpp" #include "runtime/os.hpp" diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index c87769b91e1..2fdda388eea 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -407,6 +407,11 @@ hotspot_runtime_tier2_platform_agnostic = \ runtime/SelectionResolution \ -:hotspot_fast_runtime +hotspot_runtime_minimalvm = \ + runtime/MinimalVM \ + runtime/ErrorHandling \ + runtime/logging + #All tests that depends on nashorn extension. # needs_nashorn = \ diff --git a/hotspot/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java b/hotspot/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java index 973b213e221..b56d1b4e5bf 100644 --- a/hotspot/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java +++ b/hotspot/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java @@ -36,11 +36,11 @@ package compiler.intrinsics.unsafe; import jdk.internal.misc.Unsafe; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; public class TestUnsafeMismatchedArrayFieldAccess { - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); static { try { diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java index c04196acf5b..c1c382d768d 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java @@ -45,7 +45,7 @@ package compiler.jvmci.compilerToVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject; @@ -114,7 +114,7 @@ public class GetResolvedJavaMethodTest { abstract HotSpotResolvedJavaMethod getResolvedJavaMethod(); } - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); private static final WhiteBox WB = WhiteBox.getWhiteBox(); private static final Field METASPACE_METHOD_FIELD; private static final Class TEST_CLASS = GetResolvedJavaMethodTest.class; diff --git a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java index 4d0d5b84445..80021f8e79b 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java @@ -53,7 +53,7 @@ package compiler.jvmci.compilerToVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; @@ -154,7 +154,7 @@ public class GetResolvedJavaTypeTest { abstract HotSpotResolvedObjectType getResolvedJavaType(); } - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); private static final WhiteBox WB = WhiteBox.getWhiteBox(); private static final Class TEST_CLASS = GetResolvedJavaTypeTest.class; /* a compressed parameter for tested method is set to false because diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java index a7307936124..4985773a831 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java @@ -53,7 +53,7 @@ import compiler.jvmci.compilerToVM.ConstantPoolTestsHelper.DummyClasses; import jdk.internal.misc.Unsafe; import jdk.internal.org.objectweb.asm.Opcodes; import jdk.test.lib.Asserts; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; import jdk.vm.ci.meta.ConstantPool; @@ -69,7 +69,7 @@ import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.CON */ public class ResolveFieldInPoolTest { - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); public static void main(String[] args) throws Exception { Map typeTests = new HashMap<>(); diff --git a/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java b/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java index b6164e0c4d2..e6416fdbab6 100644 --- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java +++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java @@ -52,6 +52,7 @@ import compiler.jvmci.common.testcases.SingleSubclassedClass; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; @@ -60,7 +61,7 @@ import java.util.HashSet; import java.util.Set; public class ResolveMethodTest { - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); public static void main(String args[]) { ResolveMethodTest test = new ResolveMethodTest(); diff --git a/hotspot/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java b/hotspot/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java index 02361b9719c..686e2f465e2 100644 --- a/hotspot/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java +++ b/hotspot/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java @@ -34,7 +34,7 @@ package compiler.loopopts.superword; import jdk.internal.misc.Unsafe; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; public class TestVectorizationWithInvariant { @@ -43,7 +43,7 @@ public class TestVectorizationWithInvariant { private static final long CHAR_ARRAY_OFFSET; static { - unsafe = Utils.getUnsafe(); + unsafe = UnsafeHelper.getUnsafe(); BYTE_ARRAY_OFFSET = unsafe.arrayBaseOffset(byte[].class); CHAR_ARRAY_OFFSET = unsafe.arrayBaseOffset(char[].class); } diff --git a/hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java b/hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java index 85fd007b41d..a6e285a4737 100644 --- a/hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java +++ b/hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java @@ -28,6 +28,7 @@ * @library /test/lib / * @modules java.base/jdk.internal.misc * java.management + * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -ea -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java index 6605ef1adcf..e45212e268d 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java @@ -49,7 +49,7 @@ import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -125,7 +125,7 @@ public class TestRTMAbortRatio extends CommandLineOptionTest { public static class Test implements CompilableTest { private static final int TOTAL_ITERATIONS = 10000; private static final int WARMUP_ITERATIONS = 1000; - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); private final Object monitor = new Object(); // Following field have to be static in order to avoid escape analysis. @SuppressWarnings("UnsuedDeclaration") diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java index 4f43be68d4f..21c1a612b6f 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java @@ -51,7 +51,7 @@ import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -158,7 +158,7 @@ public class TestRTMAfterNonRTMDeopt extends CommandLineOptionTest { private static int field = 0; private static final int ITERATIONS = 10000; private static final int RANGE_CHECK_AT = ITERATIONS / 2; - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); private final Object monitor = new Object(); @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java index 9386321d7d0..6807d82463a 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java @@ -48,7 +48,7 @@ import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -133,7 +133,7 @@ public class TestRTMDeoptOnLowAbortRatio extends CommandLineOptionTest { } public static class Test implements CompilableTest { - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); private final Object monitor = new Object(); @Override diff --git a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java index 0f6ccbf591e..0dfea49a526 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java @@ -49,7 +49,7 @@ import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -142,7 +142,7 @@ public class TestRTMLockingThreshold extends CommandLineOptionTest { @SuppressWarnings("UnsuedDeclaration") private static int field = 0; private static final int TOTAL_ITERATIONS = 10000; - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); private final Object monitor = new Object(); diff --git a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java index 29f560d39f0..e7158d4f670 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java @@ -49,7 +49,7 @@ import compiler.testlibrary.rtm.predicate.SupportedVM; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -113,7 +113,7 @@ public class TestRTMTotalCountIncrRate extends CommandLineOptionTest { public static class Test implements CompilableTest { private static final long TOTAL_ITERATIONS = 10000L; - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); private final Object monitor = new Object(); // Following field have to be static in order to avoid escape analysis. @SuppressWarnings("UnsuedDeclaration") diff --git a/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java b/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java index b7891eecad5..ab476b311c2 100644 --- a/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java +++ b/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java @@ -25,7 +25,7 @@ package compiler.testlibrary.rtm; import jdk.internal.misc.Unsafe; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; /** * Current RTM locking implementation force transaction abort @@ -35,7 +35,7 @@ class XAbortProvoker extends AbortProvoker { // Following field have to be static in order to avoid escape analysis. @SuppressWarnings("UnsuedDeclaration") private static int field = 0; - private static final Unsafe UNSAFE = Utils.getUnsafe(); + private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); public XAbortProvoker() { this(new Object()); diff --git a/hotspot/test/compiler/unsafe/UnsafeRaw.java b/hotspot/test/compiler/unsafe/UnsafeRaw.java index 269ca5483e9..3bf38ca941d 100644 --- a/hotspot/test/compiler/unsafe/UnsafeRaw.java +++ b/hotspot/test/compiler/unsafe/UnsafeRaw.java @@ -35,6 +35,7 @@ package compiler.unsafe; import jdk.internal.misc.Unsafe; import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import java.util.Random; @@ -81,7 +82,7 @@ public class UnsafeRaw { } public static void main(String[] args) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); final int array_size = 128; final int element_size = 4; final int magic = 0x12345678; diff --git a/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java b/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java index 45d447840a1..0238ae8b37a 100644 --- a/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java +++ b/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,16 +29,16 @@ * @key gc * @key regression * @requires vm.gc=="null" - * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages - * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages - * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages - * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages - * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:+UseLargePages TestAlignmentToUseLargePages - * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:-UseLargePages TestAlignmentToUseLargePages - * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:+UseLargePages TestAlignmentToUseLargePages - * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:-UseLargePages TestAlignmentToUseLargePages - * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:+UseLargePages TestAlignmentToUseLargePages - * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseSerialGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseSerialGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseConcMarkSweepGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseConcMarkSweepGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseG1GC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms71M -Xmx91M -XX:+UseG1GC -XX:-UseLargePages TestAlignmentToUseLargePages */ public class TestAlignmentToUseLargePages { diff --git a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java index 08a5b16fc3b..51cc5550559 100644 --- a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java +++ b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java @@ -37,6 +37,7 @@ import java.util.Collections; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; public class TestMaxMinHeapFreeRatioFlags { @@ -133,7 +134,7 @@ public class TestMaxMinHeapFreeRatioFlags { */ public static class RatioVerifier { - private static final Unsafe unsafe = Utils.getUnsafe(); + private static final Unsafe unsafe = UnsafeHelper.getUnsafe(); // Size of byte array that will be allocated public static final int CHUNK_SIZE = 1024; diff --git a/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java b/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java index af91d12ddd3..2f980e5f325 100644 --- a/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java +++ b/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java @@ -46,6 +46,7 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import sun.hotspot.WhiteBox; /* In order to test that TargetSurvivorRatio affects survivor space occupancy @@ -248,7 +249,7 @@ public class TestTargetSurvivorRatioFlag { public static class TargetSurvivorRatioVerifier { static final WhiteBox wb = WhiteBox.getWhiteBox(); - static final Unsafe unsafe = Utils.getUnsafe(); + static final Unsafe unsafe = UnsafeHelper.getUnsafe(); // Desired size of memory allocated at once public static final int CHUNK_SIZE = 1024; diff --git a/hotspot/test/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java b/hotspot/test/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java index f2291ee7a49..db2be6d6468 100644 --- a/hotspot/test/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java +++ b/hotspot/test/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java @@ -43,12 +43,12 @@ import jdk.test.lib.process.ProcessTools; public class TestVerifyBeforeAndAfterGCFlags { - // VerifyBeforeGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand C-heap code cache ] + // VerifyBeforeGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand code cache ] public static final String VERIFY_BEFORE_GC_PATTERN = "Verifying Before GC"; // VerifyBeforeGC: VerifyBeforeGC: VerifyBeforeGC: public static final String VERIFY_BEFORE_GC_CORRUPTED_PATTERN = "VerifyBeforeGC:(?!\\[Verifying[^]]+\\])"; - // VerifyAfterGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand C-heap code cache ] + // VerifyAfterGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand code cache ] public static final String VERIFY_AFTER_GC_PATTERN = "Verifying After GC"; // VerifyAfterGC: VerifyAfterGC: VerifyAfterGC: public static final String VERIFY_AFTER_GC_CORRUPTED_PATTERN = "VerifyAfterGC:(?!\\[Verifying[^]]+\\])"; diff --git a/hotspot/test/gc/cms/TestBubbleUpRef.java b/hotspot/test/gc/cms/TestBubbleUpRef.java index 9cc5ffd2fd3..90a9aa5510b 100644 --- a/hotspot/test/gc/cms/TestBubbleUpRef.java +++ b/hotspot/test/gc/cms/TestBubbleUpRef.java @@ -35,7 +35,7 @@ import java.util.ListIterator; * stays nearly full. * @run main/othervm * -XX:+UseConcMarkSweepGC -XX:-CMSYield -XX:-CMSPrecleanRefLists1 - * -XX:CMSInitiatingOccupancyFraction=0 -Xmx8m TestBubbleUpRef 16000 50 10000 + * -XX:CMSInitiatingOccupancyFraction=0 -Xmx80m TestBubbleUpRef 16000 50 10000 */ /** @@ -53,7 +53,7 @@ import java.util.ListIterator; * Do it again. * * Use the following VM options - * -Xmx8m -XX:-CMSYield [-XX:+UseConcMarkSweepGC] -XX:-CMSPrecleanRefLists1 + * -Xmx80m -XX:-CMSYield [-XX:+UseConcMarkSweepGC] -XX:-CMSPrecleanRefLists1 * -XX:CMSInitiatingOccupancyFraction=0 * * Use parameter: diff --git a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java index e86819c75b4..9db2d02193b 100644 --- a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java +++ b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java @@ -21,6 +21,7 @@ * questions. */ +import java.lang.management.GarbageCollectorMXBean; import java.util.List; import java.util.ArrayList; @@ -28,6 +29,8 @@ import jdk.test.lib.ByteCodeLoader; import jdk.test.lib.InMemoryJavaCompiler; import jdk.test.lib.Platform; +import sun.management.ManagementFactoryHelper; + import static jdk.test.lib.Asserts.*; /* @test TestMetaspacePerfCounters @@ -38,7 +41,7 @@ import static jdk.test.lib.Asserts.*; * space exists and works. * @modules java.base/jdk.internal.misc * java.compiler - * java.management + * java.management/sun.management * jdk.jvmstat/sun.jvmstat.monitor * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters @@ -51,6 +54,7 @@ import static jdk.test.lib.Asserts.*; public class TestMetaspacePerfCounters { public static Class fooClass = null; private static final String[] counterNames = {"minCapacity", "maxCapacity", "capacity", "used"}; + private static final List gcBeans = ManagementFactoryHelper.getGarbageCollectorMXBeans(); public static void main(String[] args) throws Exception { String metaspace = "sun.gc.metaspace"; @@ -68,10 +72,27 @@ public class TestMetaspacePerfCounters { } private static void checkPerfCounters(String ns) throws Exception { - long minCapacity = getMinCapacity(ns); - long maxCapacity = getMaxCapacity(ns); - long capacity = getCapacity(ns); - long used = getUsed(ns); + long gcCountBefore; + long gcCountAfter; + long minCapacity; + long maxCapacity; + long capacity; + long used; + + // The perf counter values are updated during GC and to be able to + // do the assertions below we need to ensure that the values are from + // the same GC cycle. + do { + gcCountBefore = currentGCCount(); + + minCapacity = getMinCapacity(ns); + maxCapacity = getMaxCapacity(ns); + capacity = getCapacity(ns); + used = getUsed(ns); + + gcCountAfter = currentGCCount(); + assertGTE(gcCountAfter, gcCountBefore); + } while(gcCountAfter > gcCountBefore); assertGTE(minCapacity, 0L); assertGTE(used, minCapacity); @@ -130,4 +151,12 @@ public class TestMetaspacePerfCounters { private static long getUsed(String ns) throws Exception { return PerfCounters.findByName(ns + ".used").longValue(); } + + private static long currentGCCount() { + long gcCount = 0; + for (GarbageCollectorMXBean bean : gcBeans) { + gcCount += bean.getCollectionCount(); + } + return gcCount; + } } diff --git a/hotspot/test/native/logging/logTestFixture.cpp b/hotspot/test/native/logging/logTestFixture.cpp new file mode 100644 index 00000000000..d22a6f74d92 --- /dev/null +++ b/hotspot/test/native/logging/logTestFixture.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logTestFixture.hpp" +#include "logTestUtils.inline.hpp" +#include "logging/logConfiguration.hpp" +#include "memory/resourceArea.hpp" +#include "unittest.hpp" +#include "utilities/ostream.hpp" + +LogTestFixture::LogTestFixture() { + // Set up TestLogFileName to include PID, testcase name and test name + int ret = jio_snprintf(_filename, sizeof(_filename), "testlog.pid%d.%s.%s.log", + os::current_process_id(), + ::testing::UnitTest::GetInstance()->current_test_info()->test_case_name(), + ::testing::UnitTest::GetInstance()->current_test_info()->name()); + EXPECT_GT(ret, 0) << "_filename buffer issue"; + TestLogFileName = _filename; +} + +LogTestFixture::~LogTestFixture() { + restore_default_log_config(); + delete_file(TestLogFileName); +} + +bool LogTestFixture::set_log_config(const char* output, + const char* what, + const char* decorators, + const char* options, + bool allow_failure) { + ResourceMark rm; + stringStream stream; + bool success = LogConfiguration::parse_log_arguments(output, what, decorators, options, &stream); + if (!allow_failure) { + const char* errmsg = stream.as_string(); + EXPECT_STREQ("", errmsg) << "Unexpected error reported"; + EXPECT_TRUE(success) << "Shouldn't cause errors"; + } + return success; +} + +void LogTestFixture::restore_default_log_config() { + LogConfiguration::disable_logging(); + set_log_config("stdout", "all=warning"); +} diff --git a/hotspot/test/native/logging/logTestFixture.hpp b/hotspot/test/native/logging/logTestFixture.hpp new file mode 100644 index 00000000000..d9c1c8b02df --- /dev/null +++ b/hotspot/test/native/logging/logTestFixture.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "unittest.hpp" +#include "utilities/globalDefinitions.hpp" + +// A fixture base class for tests that need to change the log configuration, +// or use a log file. After each test, the fixture will automatically restore +// the log configuration and remove the test file (if used). +// Provides TestLogFileName which is unique for each test, and is automatically +// deleted after the test completes. +class LogTestFixture : public testing::Test { + private: + char _filename[2 * K]; + + protected: + const char* TestLogFileName; + + LogTestFixture(); + ~LogTestFixture(); + + static bool set_log_config(const char* output, + const char* what, + const char* decorators = "", + const char* options = "", + bool allow_failure = false); + + static void restore_default_log_config(); +}; + diff --git a/hotspot/test/native/logging/logTestUtils.inline.hpp b/hotspot/test/native/logging/logTestUtils.inline.hpp new file mode 100644 index 00000000000..bf39dfdbd9e --- /dev/null +++ b/hotspot/test/native/logging/logTestUtils.inline.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "runtime/os.hpp" +#include "unittest.hpp" + +#define LOG_TEST_STRING_LITERAL "a (hopefully) unique log message for testing" + +static inline bool string_contains_substring(const char* haystack, const char* needle) { + return strstr(haystack, needle) != NULL; +} + +static inline bool file_exists(const char* filename) { + struct stat st; + return os::stat(filename, &st) == 0; +} + +static inline void delete_file(const char* filename) { + if (!file_exists(filename)) { + return; + } + int ret = remove(filename); + EXPECT_TRUE(ret == 0 || errno == ENOENT) << "failed to remove file '" << filename << "': " + << os::strerror(errno) << " (" << errno << ")"; +} diff --git a/hotspot/test/native/logging/test_logConfiguration.cpp b/hotspot/test/native/logging/test_logConfiguration.cpp new file mode 100644 index 00000000000..528111ef31b --- /dev/null +++ b/hotspot/test/native/logging/test_logConfiguration.cpp @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logTestFixture.hpp" +#include "logTestUtils.inline.hpp" +#include "logging/logConfiguration.hpp" +#include "logging/logLevel.hpp" +#include "logging/logOutput.hpp" +#include "logging/logTag.hpp" +#include "logging/logTagSet.hpp" +#include "memory/resourceArea.hpp" +#include "unittest.hpp" +#include "utilities/ostream.hpp" + +class LogConfigurationTest : public LogTestFixture { + protected: + static char _all_decorators[256]; + + public: + static void SetUpTestCase(); +}; + +char LogConfigurationTest::_all_decorators[256]; + +// Prepare _all_decorators to contain the full list of decorators (comma separated) +void LogConfigurationTest::SetUpTestCase() { + char *pos = _all_decorators; + for (size_t i = 0; i < LogDecorators::Count; i++) { + pos += jio_snprintf(pos, sizeof(_all_decorators) - (pos - _all_decorators), "%s%s", + (i == 0 ? "" : ","), + LogDecorators::name(static_cast(i))); + } +} + +// Check if the given text is included by LogConfiguration::describe() +static bool is_described(const char* text) { + ResourceMark rm; + stringStream ss; + LogConfiguration::describe(&ss); + return string_contains_substring(ss.as_string(), text); +} + +TEST_F(LogConfigurationTest, describe) { + ResourceMark rm; + stringStream ss; + LogConfiguration::describe(&ss); + const char* description = ss.as_string(); + + // Verify that stdout and stderr are listed by default + EXPECT_PRED2(string_contains_substring, description, LogOutput::Stdout->name()); + EXPECT_PRED2(string_contains_substring, description, LogOutput::Stderr->name()); + + // Verify that each tag, level and decorator is listed + for (size_t i = 0; i < LogTag::Count; i++) { + EXPECT_PRED2(string_contains_substring, description, LogTag::name(static_cast(i))); + } + for (size_t i = 0; i < LogLevel::Count; i++) { + EXPECT_PRED2(string_contains_substring, description, LogLevel::name(static_cast(i))); + } + for (size_t i = 0; i < LogDecorators::Count; i++) { + EXPECT_PRED2(string_contains_substring, description, LogDecorators::name(static_cast(i))); + } + + // Verify that the default configuration is printed + char expected_buf[256]; + int ret = jio_snprintf(expected_buf, sizeof(expected_buf), "=%s", LogLevel::name(LogLevel::Default)); + ASSERT_NE(-1, ret); + EXPECT_PRED2(string_contains_substring, description, expected_buf); + EXPECT_PRED2(string_contains_substring, description, "#1: stderr all=off"); + + // Verify default decorators are listed + LogDecorators default_decorators; + expected_buf[0] = '\0'; + for (size_t i = 0; i < LogDecorators::Count; i++) { + LogDecorators::Decorator d = static_cast(i); + if (default_decorators.is_decorator(d)) { + ASSERT_LT(strlen(expected_buf), sizeof(expected_buf)); + ret = jio_snprintf(expected_buf + strlen(expected_buf), + sizeof(expected_buf) - strlen(expected_buf), + "%s%s", + strlen(expected_buf) > 0 ? "," : "", + LogDecorators::name(d)); + ASSERT_NE(-1, ret); + } + } + EXPECT_PRED2(string_contains_substring, description, expected_buf); + + // Add a new output and verify that it gets described after it has been added + const char* what = "all=trace"; + EXPECT_FALSE(is_described(TestLogFileName)) << "Test output already exists!"; + set_log_config(TestLogFileName, what); + EXPECT_TRUE(is_described(TestLogFileName)); + EXPECT_TRUE(is_described("logging=trace")); +} + +// Test updating an existing log output +TEST_F(LogConfigurationTest, update_output) { + // Update stdout twice, first using it's name, and the second time its index # + const char* test_outputs[] = { "stdout", "#0" }; + for (size_t i = 0; i < ARRAY_SIZE(test_outputs); i++) { + set_log_config(test_outputs[i], "all=info"); + + // Verify configuration using LogConfiguration::describe + EXPECT_TRUE(is_described("#0: stdout")); + EXPECT_TRUE(is_described("logging=info")); + + // Verify by iterating over tagsets + LogOutput* o = LogOutput::Stdout; + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_TRUE(ts->has_output(o)); + EXPECT_TRUE(ts->is_level(LogLevel::Info)); + EXPECT_FALSE(ts->is_level(LogLevel::Debug)); + } + + // Now change the level and verify the change propagated + set_log_config(test_outputs[i], "all=debug"); + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_TRUE(ts->has_output(o)); + EXPECT_TRUE(ts->is_level(LogLevel::Debug)); + EXPECT_FALSE(ts->is_level(LogLevel::Trace)); + } + } +} + +// Test adding a new output to the configuration +TEST_F(LogConfigurationTest, add_new_output) { + const char* what = "all=trace"; + + ASSERT_FALSE(is_described(TestLogFileName)); + set_log_config(TestLogFileName, what); + + // Verify new output using LogConfiguration::describe + EXPECT_TRUE(is_described(TestLogFileName)); + EXPECT_TRUE(is_described("logging=trace")); + + // Also verify by iterating over tagsets, checking levels on tagsets + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_TRUE(ts->is_level(LogLevel::Trace)); + } +} + +TEST_F(LogConfigurationTest, disable_logging) { + // Add TestLogFileName as an output + set_log_config(TestLogFileName, "logging=info"); + + LogConfiguration::disable_logging(); + + // Verify TestLogFileName was disabled + EXPECT_FALSE(is_described(TestLogFileName)); + + // Verify that no tagset has logging enabled + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_FALSE(ts->has_output(LogOutput::Stdout)); + EXPECT_FALSE(ts->has_output(LogOutput::Stderr)); + EXPECT_FALSE(ts->is_level(LogLevel::Error)); + } +} + +// Test disabling a particular output +TEST_F(LogConfigurationTest, disable_output) { + // Disable the default configuration for stdout + set_log_config("stdout", "all=off"); + + // Verify configuration using LogConfiguration::describe + EXPECT_TRUE(is_described("#0: stdout all=off")); + + // Verify by iterating over tagsets + LogOutput* o = LogOutput::Stdout; + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_FALSE(ts->has_output(o)); + EXPECT_FALSE(ts->is_level(LogLevel::Error)); + } + + // Add a new file output + const char* what = "all=debug"; + set_log_config(TestLogFileName, what); + EXPECT_TRUE(is_described(TestLogFileName)); + + // Now disable it, verifying it is removed completely + set_log_config(TestLogFileName, "all=off"); + EXPECT_FALSE(is_described(TestLogFileName)); + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_FALSE(ts->is_level(LogLevel::Error)); + } +} + +// Test reconfiguration of the selected decorators for an output +TEST_F(LogConfigurationTest, reconfigure_decorators) { + // Configure stderr with all decorators + set_log_config("stderr", "all=off", _all_decorators); + char buf[256]; + int ret = jio_snprintf(buf, sizeof(buf), "#1: stderr all=off %s", _all_decorators); + ASSERT_NE(-1, ret); + EXPECT_TRUE(is_described(buf)) << "'" << buf << "' not described after reconfiguration"; + + // Now reconfigure logging on stderr with no decorators + set_log_config("stderr", "all=off", "none"); + EXPECT_TRUE(is_described("#1: stderr all=off \n")) << "Expecting no decorators"; +} + +// Test that invalid options cause configuration errors +TEST_F(LogConfigurationTest, invalid_configure_options) { + LogConfiguration::disable_logging(); + const char* invalid_outputs[] = { "#2", "invalidtype=123", ":invalid/path}to*file?" }; + for (size_t i = 0; i < ARRAY_SIZE(invalid_outputs); i++) { + EXPECT_FALSE(set_log_config(invalid_outputs[i], "", "", "", true)) + << "Accepted invalid output '" << invalid_outputs[i] << "'"; + } + EXPECT_FALSE(LogConfiguration::parse_command_line_arguments("all=invalid_level")); + EXPECT_FALSE(LogConfiguration::parse_command_line_arguments("what=invalid")); + EXPECT_FALSE(LogConfiguration::parse_command_line_arguments("all::invalid_decorator")); +} + +// Test empty configuration options +TEST_F(LogConfigurationTest, parse_empty_command_line_arguments) { + const char* empty_variations[] = { "", ":", "::", ":::", "::::" }; + for (size_t i = 0; i < ARRAY_SIZE(empty_variations); i++) { + const char* cmdline = empty_variations[i]; + bool ret = LogConfiguration::parse_command_line_arguments(cmdline); + EXPECT_TRUE(ret) << "Error parsing command line arguments '" << cmdline << "'"; + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_EQ(LogLevel::Unspecified, ts->level_for(LogOutput::Stdout)); + } + } +} + +// Test basic command line parsing & configuration +TEST_F(LogConfigurationTest, parse_command_line_arguments) { + // Prepare a command line for logging*=debug on stderr with all decorators + int ret; + char buf[256]; + ret = jio_snprintf(buf, sizeof(buf), "logging*=debug:stderr:%s", _all_decorators); + ASSERT_NE(-1, ret); + + bool success = LogConfiguration::parse_command_line_arguments(buf); + EXPECT_TRUE(success) << "Error parsing valid command line arguments '" << buf << "'"; + // Ensure the new configuration applied + EXPECT_TRUE(is_described("logging=debug")); + EXPECT_TRUE(is_described(_all_decorators)); + + // Test the configuration of file outputs as well + ret = jio_snprintf(buf, sizeof(buf), ":%s", TestLogFileName); + ASSERT_NE(-1, ret); + EXPECT_TRUE(LogConfiguration::parse_command_line_arguments(buf)); +} + +// Test split up log configuration arguments +TEST_F(LogConfigurationTest, parse_log_arguments) { + ResourceMark rm; + stringStream ss; + // Verify that it's possible to configure each individual tag + for (size_t t = 1 /* Skip _NO_TAG */; t < LogTag::Count; t++) { + const LogTagType tag = static_cast(t); + EXPECT_TRUE(LogConfiguration::parse_log_arguments("stdout", LogTag::name(tag), "", "", &ss)); + } + // Same for each level + for (size_t l = 0; l < LogLevel::Count; l++) { + const LogLevelType level = static_cast(l); + char expected_buf[256]; + int ret = jio_snprintf(expected_buf, sizeof(expected_buf), "all=%s", LogLevel::name(level)); + ASSERT_NE(-1, ret); + EXPECT_TRUE(LogConfiguration::parse_log_arguments("stderr", expected_buf, "", "", &ss)); + } + // And for each decorator + for (size_t d = 0; d < LogDecorators::Count; d++) { + const LogDecorators::Decorator decorator = static_cast(d); + EXPECT_TRUE(LogConfiguration::parse_log_arguments("#0", "", LogDecorators::name(decorator), "", &ss)); + } + EXPECT_STREQ("", ss.as_string()) << "Error reported while parsing: " << ss.as_string(); +} diff --git a/hotspot/test/native/logging/test_logDecorations.cpp b/hotspot/test/native/logging/test_logDecorations.cpp new file mode 100644 index 00000000000..324792b24b8 --- /dev/null +++ b/hotspot/test/native/logging/test_logDecorations.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logging/logDecorations.hpp" +#include "logging/logTagSet.hpp" +#include "runtime/os.hpp" +#include "unittest.hpp" +#include "utilities/globalDefinitions.hpp" + +static const LogTagSet& tagset = LogTagSetMapping::tagset(); +static const LogDecorators default_decorators; + +TEST(LogDecorations, level) { + for (uint l = LogLevel::First; l <= LogLevel::Last; l++) { + LogLevelType level = static_cast(l); + // Create a decorations object for the current level + LogDecorations decorations(level, tagset, default_decorators); + // Verify that the level decoration matches the specified level + EXPECT_STREQ(LogLevel::name(level), decorations.decoration(LogDecorators::level_decorator)); + + // Test changing level after object creation time + LogLevelType other_level; + if (l != LogLevel::Last) { + other_level = static_cast(l + 1); + } else { + other_level = static_cast(LogLevel::First); + } + decorations.set_level(other_level); + EXPECT_STREQ(LogLevel::name(other_level), decorations.decoration(LogDecorators::level_decorator)) + << "Decoration reports incorrect value after changing the level"; + } +} + +TEST(LogDecorations, uptime) { + // Verify the format of the decoration + int a, b; + char decimal_point; + LogDecorations decorations(LogLevel::Info, tagset, default_decorators); + const char* uptime = decorations.decoration(LogDecorators::uptime_decorator); + int read = sscanf(uptime, "%d%c%ds", &a, &decimal_point, &b); + EXPECT_EQ(3, read) << "Invalid uptime decoration: " << uptime; + EXPECT_TRUE(decimal_point == '.' || decimal_point == ',') << "Invalid uptime decoration: " << uptime; + + // Verify that uptime increases + double prev = 0; + for (int i = 0; i < 3; i++) { + os::naked_short_sleep(10); + LogDecorations d(LogLevel::Info, tagset, default_decorators); + double cur = strtod(d.decoration(LogDecorators::uptime_decorator), NULL); + ASSERT_LT(prev, cur); + prev = cur; + } +} + +TEST(LogDecorations, tags) { + char expected_tags[1 * K]; + tagset.label(expected_tags, sizeof(expected_tags)); + // Verify that the expected tags are included in the tags decoration + LogDecorations decorations(LogLevel::Info, tagset, default_decorators); + EXPECT_STREQ(expected_tags, decorations.decoration(LogDecorators::tags_decorator)); +} + +// Test each variation of the different timestamp decorations (ms, ns, uptime ms, uptime ns) +TEST(LogDecorations, timestamps) { + struct { + const LogDecorators::Decorator decorator; + const char* suffix; + } test_decorator[] = { + { LogDecorators::timemillis_decorator, "ms" }, + { LogDecorators::uptimemillis_decorator, "ms" }, + { LogDecorators::timenanos_decorator, "ns" }, + { LogDecorators::uptimenanos_decorator, "ns" } + }; + + for (uint i = 0; i < ARRAY_SIZE(test_decorator); i++) { + LogDecorators::Decorator decorator = test_decorator[i].decorator; + LogDecorators decorator_selection; + ASSERT_TRUE(decorator_selection.parse(LogDecorators::name(decorator))); + + // Create decorations with the decorator we want to test included + LogDecorations decorations(LogLevel::Info, tagset, decorator_selection); + const char* decoration = decorations.decoration(decorator); + + // Verify format of timestamp + const char* suffix; + for (suffix = decoration; isdigit(*suffix); suffix++) { + // Skip over digits + } + EXPECT_STREQ(test_decorator[i].suffix, suffix); + + // Verify timestamp values + julong prev = 0; + for (int i = 0; i < 3; i++) { + os::naked_short_sleep(5); + LogDecorations d(LogLevel::Info, tagset, decorator_selection); + julong val = strtoull(d.decoration(decorator), NULL, 10); + ASSERT_LT(prev, val); + prev = val; + } + } +} + +// Test the time decoration +TEST(LogDecorations, iso8601_time) { + LogDecorators decorator_selection; + ASSERT_TRUE(decorator_selection.parse("time")); + LogDecorations decorations(LogLevel::Info, tagset, decorator_selection); + + const char *timestr = decorations.decoration(LogDecorators::time_decorator); + time_t expected_ts = time(NULL); + + // Verify format + int y, M, d, h, m; + double s; + int read = sscanf(timestr, "%d-%d-%dT%d:%d:%lfZ", &y, &M, &d, &h, &m, &s); + ASSERT_EQ(6, read); + + // Verify reported time & date + struct tm reported_time = {0}; + reported_time.tm_year = y - 1900; + reported_time.tm_mon = M - 1; + reported_time.tm_mday = d; + reported_time.tm_hour = h; + reported_time.tm_min = m; + reported_time.tm_sec = s; + reported_time.tm_isdst = daylight; + time_t reported_ts = mktime(&reported_time); + expected_ts = mktime(localtime(&expected_ts)); + time_t diff = reported_ts - expected_ts; + if (diff < 0) { + diff = -diff; + } + // Allow up to 10 seconds in difference + ASSERT_LE(diff, 10) << "Reported time: " << reported_ts << " (" << timestr << ")" + << ", expected time: " << expected_ts; +} + +// Test the pid and tid decorations +TEST(LogDecorations, identifiers) { + LogDecorators decorator_selection; + ASSERT_TRUE(decorator_selection.parse("pid,tid")); + LogDecorations decorations(LogLevel::Info, tagset, decorator_selection); + + struct { + intx expected; + LogDecorators::Decorator decorator; + } ids[] = { + { os::current_process_id(), LogDecorators::pid_decorator }, + { os::current_thread_id(), LogDecorators::tid_decorator }, + }; + + for (uint i = 0; i < ARRAY_SIZE(ids); i++) { + const char* reported = decorations.decoration(ids[i].decorator); + + // Verify format + const char* str; + for (str = reported; isdigit(*str); str++) { + // Skip over digits + } + EXPECT_EQ('\0', *str) << "Should only contain digits"; + + // Verify value + EXPECT_EQ(ids[i].expected, strtol(reported, NULL, 10)); + } +} diff --git a/hotspot/test/native/logging/test_logDecorators.cpp b/hotspot/test/native/logging/test_logDecorators.cpp new file mode 100644 index 00000000000..beaa925e320 --- /dev/null +++ b/hotspot/test/native/logging/test_logDecorators.cpp @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logging/logDecorators.hpp" +#include "unittest.hpp" + +static LogDecorators::Decorator decorator_array[] = { +#define DECORATOR(name, abbr) LogDecorators::name##_decorator, + DECORATOR_LIST +#undef DECORATOR +}; + +static const char* decorator_name_array[] = { +#define DECORATOR(name, abbr) #name, + DECORATOR_LIST +#undef DECORATOR +}; + +static const char* decorator_abbr_array[] = { +#define DECORATOR(name, abbr) #abbr, + DECORATOR_LIST +#undef DECORATOR +}; + +// Assert that the given decorators object has the default decorators (uptime, level, tags) +// If exclusive = true, also assert that no other decorators are selected +static void assert_default_decorators(LogDecorators* decorators, bool exclusive = true) { + for (int i = 0; i < LogDecorators::Count; i++) { + LogDecorators::Decorator decorator = decorator_array[i]; + if (decorator == LogDecorators::uptime_decorator || + decorator == LogDecorators::level_decorator || + decorator == LogDecorators::tags_decorator) { + EXPECT_TRUE(decorators->is_decorator(decorator)); + } else if (exclusive) { + EXPECT_FALSE(decorators->is_decorator(decorator)); + } + } +} + +TEST(LogDecorators, defaults) { + LogDecorators decorators; + assert_default_decorators(&decorators); +} + +// Test converting between name and decorator (string and enum) +TEST(LogDecorators, from_and_to_name) { + EXPECT_EQ(LogDecorators::Invalid, LogDecorators::from_string("unknown")); + EXPECT_EQ(LogDecorators::Invalid, LogDecorators::from_string("")); + + for (int i = 0; i < LogDecorators::Count; i++) { + LogDecorators::Decorator decorator = decorator_array[i]; + + const char* name = LogDecorators::name(decorator); + EXPECT_STREQ(decorator_name_array[i], name); + + LogDecorators::Decorator decorator2 = LogDecorators::from_string(name); + EXPECT_EQ(decorator, decorator2); + + // Test case insensitivity + char* name_cpy = strdup(name); + name_cpy[0] = toupper(name_cpy[0]); + decorator2 = LogDecorators::from_string(name_cpy); + free(name_cpy); + EXPECT_EQ(decorator, decorator2); + } +} + +// Test decorator abbreviations +TEST(LogDecorators, from_and_to_abbr) { + for (int i = 0; i < LogDecorators::Count; i++) { + LogDecorators::Decorator decorator = decorator_array[i]; + + const char* abbr = LogDecorators::abbreviation(decorator); + EXPECT_STREQ(decorator_abbr_array[i], abbr); + + LogDecorators::Decorator decorator2 = LogDecorators::from_string(abbr); + ASSERT_EQ(decorator, decorator2); + + // Test case insensitivity + char* abbr_cpy = strdup(abbr); + abbr_cpy[0] = toupper(abbr_cpy[0]); + decorator2 = LogDecorators::from_string(abbr_cpy); + free(abbr_cpy); + EXPECT_EQ(decorator, decorator2); + } +} + +TEST(LogDecorators, parse_default) { + LogDecorators decorators; + decorators.parse(""); // Empty string means we should use the default decorators + assert_default_decorators(&decorators); +} + +// Test that "none" gives no decorators at all +TEST(LogDecorators, parse_none) { + LogDecorators decorators; + decorators.parse("none"); + for (int i = 0; i < LogDecorators::Count; i++) { + EXPECT_FALSE(decorators.is_decorator(decorator_array[i])); + } +} + +// Test a few invalid decorator selections +TEST(LogDecorators, parse_invalid) { + LogDecorators decorators; + EXPECT_FALSE(decorators.parse("invalid")); + EXPECT_FALSE(decorators.parse(",invalid")); + EXPECT_FALSE(decorators.parse(",invalid,")); + assert_default_decorators(&decorators); +} + +// Assert that the given decorator has all decorators between first and last +static void assert_decorations_between(const LogDecorators* decorator, size_t first, size_t last) { + for (size_t i = 0; i < ARRAY_SIZE(decorator_array); i++) { + if (i >= first && i <= last) { + EXPECT_TRUE(decorator->is_decorator(decorator_array[i])); + } else { + EXPECT_FALSE(decorator->is_decorator(decorator_array[i])); + } + } +} + +TEST(LogDecorators, parse) { + LogDecorators decorators; + + // Verify a bunch of different decorator selections + char decstr[1 * K]; + decstr[0] = '\0'; + size_t written = 0; + for (size_t i = 0; i < ARRAY_SIZE(decorator_array); i++) { + for (size_t j = i; j < ARRAY_SIZE(decorator_array); j++) { + for (size_t k = i; k <= j; k++) { + ASSERT_LT(written, sizeof(decstr)) << "decstr overflow"; + int ret = jio_snprintf(decstr + written, sizeof(decstr) - written, "%s%s", + written == 0 ? "" : ",", + ((k + j) % 2 == 0) ? decorator_name_array[k] : decorator_abbr_array[k]); + ASSERT_NE(-1, ret); + written += ret; + } + EXPECT_TRUE(decorators.parse(decstr)) << "Valid decorator selection did not parse: " << decstr; + assert_decorations_between(&decorators, i, j); + written = 0; + decstr[0] = '\0'; + } + } +} + +TEST(LogDecorators, combine_with) { + LogDecorators dec1; + LogDecorators dec2; + + // Select first and third decorator for dec1 + char input[64]; + sprintf(input, "%s,%s", decorator_name_array[0], decorator_name_array[2]); + dec1.parse(input); + EXPECT_TRUE(dec1.is_decorator(decorator_array[0])); + EXPECT_TRUE(dec1.is_decorator(decorator_array[2])); + + // Select the default decorators for dec2 + EXPECT_FALSE(dec2.is_decorator(decorator_array[0])); + EXPECT_FALSE(dec2.is_decorator(decorator_array[2])); + assert_default_decorators(&dec2); + + // Combine and verify that the combination includes first, third and default decorators + dec2.combine_with(dec1); + EXPECT_TRUE(dec2.is_decorator(decorator_array[0])); + EXPECT_TRUE(dec2.is_decorator(decorator_array[2])); + assert_default_decorators(&dec2, false); +} + +TEST(LogDecorators, clear) { + // Start with default decorators and then clear it + LogDecorators dec; + EXPECT_FALSE(dec.is_empty()); + + dec.clear(); + EXPECT_TRUE(dec.is_empty()); + for (size_t i = 0; i < LogDecorators::Count; i++) { + EXPECT_FALSE(dec.is_decorator(decorator_array[i])); + } +} + +// Test the decorator constant None +TEST(LogDecorators, none) { + LogDecorators dec = LogDecorators::None; + for (size_t i = 0; i < LogDecorators::Count; i++) { + EXPECT_FALSE(dec.is_decorator(decorator_array[i])); + } +} + +TEST(LogDecorators, is_empty) { + LogDecorators def, none = LogDecorators::None; + EXPECT_FALSE(def.is_empty()); + EXPECT_TRUE(none.is_empty()); +} diff --git a/hotspot/test/native/logging/test_logFileOutput.cpp b/hotspot/test/native/logging/test_logFileOutput.cpp new file mode 100644 index 00000000000..da13e539412 --- /dev/null +++ b/hotspot/test/native/logging/test_logFileOutput.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logging/logFileOutput.hpp" +#include "memory/resourceArea.hpp" +#include "runtime/os.hpp" +#include "unittest.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/ostream.hpp" + +static const char* name = "testlog.pid%p.%t.log"; + +// Test parsing a bunch of valid file output options +TEST(LogFileOutput, parse_valid) { + const char* valid_options[] = { + "", "filecount=10", "filesize=512", + "filecount=11,filesize=256", + "filesize=256,filecount=11", + "filesize=0", "filecount=1", + "filesize=1m", "filesize=1M", + "filesize=1k", "filesize=1G" + }; + + // Override LogOutput's vm_start time to get predictable file name + LogFileOutput::set_file_name_parameters(0); + char expected_filename[1 * K]; + int ret = jio_snprintf(expected_filename, sizeof(expected_filename), + "testlog.pid%d.1970-01-01_01-00-00.log", + os::current_process_id()); + ASSERT_GT(ret, 0) << "Buffer too small"; + + for (size_t i = 0; i < ARRAY_SIZE(valid_options); i++) { + ResourceMark rm; + stringStream ss; + { + LogFileOutput fo(name); + EXPECT_STREQ(name, fo.name()); + EXPECT_TRUE(fo.initialize(valid_options[i], &ss)) + << "Did not accept valid option(s) '" << valid_options[i] << "': " << ss.as_string(); + } + remove(expected_filename); + } +} + +// Test parsing a bunch of invalid file output options +TEST(LogFileOutput, parse_invalid) { + const char* invalid_options[] = { + "invalidopt", "filecount=", + "filesize=,filecount=10", + "fileco=10", "ilesize=512", + "filecount=11,,filesize=256", + ",filesize=256,filecount=11", + "filesize=256,filecount=11,", + "filesize=-1", "filecount=0.1", + "filecount=-2", "filecount=2.0", + "filecount= 2", "filesize=2 ", + "filecount=ab", "filesize=0xz", + "filecount=1MB", "filesize=99bytes", + "filesize=9999999999999999999999999" + "filecount=9999999999999999999999999" + }; + + for (size_t i = 0; i < ARRAY_SIZE(invalid_options); i++) { + ResourceMark rm; + stringStream ss; + LogFileOutput fo(name); + EXPECT_FALSE(fo.initialize(invalid_options[i], &ss)) + << "Accepted invalid option(s) '" << invalid_options[i] << "': " << ss.as_string(); + } +} + +// Test for overflows with filesize +TEST(LogFileOutput, filesize_overflow) { + char buf[256]; + int ret = jio_snprintf(buf, sizeof(buf), "filesize=" SIZE_FORMAT "K", SIZE_MAX); + ASSERT_GT(ret, 0) << "Buffer too small"; + + ResourceMark rm; + stringStream ss; + LogFileOutput fo(name); + EXPECT_FALSE(fo.initialize(buf, &ss)) << "Accepted filesize that overflows"; +} diff --git a/hotspot/test/native/logging/test_logLevel.cpp b/hotspot/test/native/logging/test_logLevel.cpp new file mode 100644 index 00000000000..00004bb334d --- /dev/null +++ b/hotspot/test/native/logging/test_logLevel.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logging/logLevel.hpp" +#include "unittest.hpp" + +TEST(LogLevel, from_string) { + LogLevelType level; + + // Verify each name defined in the LOG_LEVEL_LIST +#define LOG_LEVEL(lname, lstring) \ + level = LogLevel::from_string(#lstring); \ + EXPECT_EQ(level, LogLevel::lname); + LOG_LEVEL_LIST +#undef LOG_LEVEL + + // Verify a few invalid level strings + EXPECT_EQ(LogLevel::Invalid, LogLevel::from_string("bad level")); + EXPECT_EQ(LogLevel::Invalid, LogLevel::from_string("debugger")); + EXPECT_EQ(LogLevel::Invalid, LogLevel::from_string("inf")); + EXPECT_EQ(LogLevel::Invalid, LogLevel::from_string("info ")); + EXPECT_EQ(LogLevel::Invalid, LogLevel::from_string(" info")); + EXPECT_EQ(LogLevel::Invalid, LogLevel::from_string("=info")); + EXPECT_EQ(LogLevel::Invalid, LogLevel::from_string("infodebugwarning")); +} + +TEST(LogLevel, name) { + // Use names from macro as reference +#define LOG_LEVEL(lname, lstring) \ + EXPECT_STREQ(LogLevel::name(LogLevel::lname), #lstring); + LOG_LEVEL_LIST +#undef LOG_LEVEL +} diff --git a/hotspot/test/native/logging/test_logOutputList.cpp b/hotspot/test/native/logging/test_logOutputList.cpp new file mode 100644 index 00000000000..d5853526d89 --- /dev/null +++ b/hotspot/test/native/logging/test_logOutputList.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logging/logLevel.hpp" +#include "logging/logOutput.hpp" +#include "logging/logOutputList.hpp" +#include "runtime/os.hpp" +#include "unittest.hpp" + +// Count the outputs in the given list, starting from the specified level +static size_t output_count(LogOutputList* list, LogLevelType from = LogLevel::Error) { + size_t count = 0; + for (LogOutputList::Iterator it = list->iterator(from); it != list->end(); it++) { + count++; + } + return count; +} + +// Get the level for an output in the given list +static LogLevelType find_output_level(LogOutputList* list, LogOutput* o) { + for (size_t levelnum = 1; levelnum < LogLevel::Count; levelnum++) { + LogLevelType level = static_cast(levelnum); + for (LogOutputList::Iterator it = list->iterator(level); it != list->end(); it++) { + if (*it == o) { + return level; + } + } + } + return LogLevel::Off; +} + +// Create a dummy output pointer with the specified id. +// This dummy pointer should not be used for anything +// but pointer comparisons with other dummies. +static LogOutput* dummy_output(size_t id) { + return reinterpret_cast(id + 1); +} + +// Randomly update and verify some outputs some number of times +TEST(LogOutputList, set_output_level_update) { + const size_t TestOutputCount = 10; + const size_t TestIterations = 10000; + LogOutputList list; + size_t outputs_on_level[LogLevel::Count]; + LogLevelType expected_level_for_output[TestOutputCount]; + + os::init_random(0x4711); + for (size_t i = 0; i < LogLevel::Count; i++) { + outputs_on_level[i] = 0; + } + outputs_on_level[LogLevel::Off] = TestOutputCount; + for (size_t i = 0; i < TestOutputCount; i++) { + expected_level_for_output[i] = LogLevel::Off; + } + + for (size_t iteration = 0; iteration < TestIterations; iteration++) { + size_t output_idx = os::random() % TestOutputCount; + size_t levelnum = os::random() % LogLevel::Count; + LogLevelType level = static_cast(levelnum); + + // Update the expectations + outputs_on_level[expected_level_for_output[output_idx]]--; + outputs_on_level[levelnum]++; + expected_level_for_output[output_idx] = level; + + // Update the actual list + list.set_output_level(dummy_output(output_idx), level); + + // Verify expected levels + for (size_t i = 0; i < TestOutputCount; i++) { + ASSERT_EQ(expected_level_for_output[i], find_output_level(&list, dummy_output(i))); + } + // Verify output counts + size_t expected_count = 0; + for (size_t i = 1; i < LogLevel::Count; i++) { + expected_count += outputs_on_level[i]; + ASSERT_EQ(expected_count, output_count(&list, static_cast(i))); + } + ASSERT_EQ(TestOutputCount, expected_count + outputs_on_level[LogLevel::Off]); + } +} + +// Test removing outputs from a LogOutputList +TEST(LogOutputList, set_output_level_remove) { + LogOutputList list; + + // Add three dummy outputs per loglevel + for (size_t i = 1; i < LogLevel::Count; i++) { + list.set_output_level(dummy_output(i), static_cast(i)); + list.set_output_level(dummy_output(i*10), static_cast(i)); + list.set_output_level(dummy_output(i*100), static_cast(i)); + } + + // Verify that they have been added successfully + // (Count - 1 since we don't count LogLevel::Off) + EXPECT_EQ(3u * (LogLevel::Count - 1), output_count(&list)); + // Now remove the second output from each loglevel + for (size_t i = 1; i < LogLevel::Count; i++) { + list.set_output_level(dummy_output(i*10), LogLevel::Off); + } + // Make sure they have been successfully removed + EXPECT_EQ(2u * (LogLevel::Count - 1), output_count(&list)); + + // Now remove the remaining outputs + for (size_t i = 1; i < LogLevel::Count; i++) { + list.set_output_level(dummy_output(i), LogLevel::Off); + list.set_output_level(dummy_output(i*100), LogLevel::Off); + } + EXPECT_EQ(0u, output_count(&list)); +} + +// Test adding to a LogOutputList +TEST(LogOutputList, set_output_level_add) { + LogOutputList list; + + // First add 5 outputs to Info level + for (size_t i = 10; i < 15; i++) { + list.set_output_level(dummy_output(i), LogLevel::Info); + } + + // Verify that they have been added successfully + size_t count = 0; + for (LogOutputList::Iterator it = list.iterator(); it != list.end(); it++) { + ASSERT_EQ(dummy_output(10 + count++), *it); + } + ASSERT_EQ(5u, count); + + // Now add more outputs, but on all different levels + for (size_t i = 5; i < 10; i++) { + list.set_output_level(dummy_output(i), LogLevel::Warning); + } + for (size_t i = 0; i < 5; i++) { + list.set_output_level(dummy_output(i), LogLevel::Error); + } + for (size_t i = 15; i < 20; i++) { + list.set_output_level(dummy_output(i), LogLevel::Debug); + } + for (size_t i = 20; i < 25; i++) { + list.set_output_level(dummy_output(i), LogLevel::Trace); + } + + // Verify that that all outputs have been added, and that the order is Error, Warning, Info, Debug, Trace + count = 0; + for (LogOutputList::Iterator it = list.iterator(); it != list.end(); it++) { + ASSERT_EQ(dummy_output(count++), *it); + } + ASSERT_EQ(25u, count); +} + +// Test is_level() on lists with a single output on different levels +TEST(LogOutputList, is_level_single_output) { + for (size_t i = LogLevel::First; i < LogLevel::Count; i++) { + LogLevelType level = static_cast(i); + LogOutputList list; + list.set_output_level(LogOutput::Stdout, level); + for (size_t j = LogLevel::First; j < LogLevel::Count; j++) { + LogLevelType other = static_cast(j); + // Verify that levels finer than the current level for stdout are reported as disabled, + // and levels equal to or included in the current level are reported as enabled + if (other >= level) { + EXPECT_TRUE(list.is_level(other)) + << LogLevel::name(other) << " >= " << LogLevel::name(level) << " but is_level() returns false"; + } else { + EXPECT_FALSE(list.is_level(other)) + << LogLevel::name(other) << " < " << LogLevel::name(level) << " but is_level() returns true"; + } + } + } +} + +// Test is_level() with an empty list +TEST(LogOutputList, is_level_empty) { + LogOutputList emptylist; + for (size_t i = LogLevel::First; i < LogLevel::Count; i++) { + LogLevelType other = static_cast(i); + EXPECT_FALSE(emptylist.is_level(other)) << "is_level() returns true even though the list is empty"; + } +} + +// Test is_level() on lists with two outputs on different levels +TEST(LogOutputList, is_level_multiple_outputs) { + for (size_t i = LogLevel::First; i < LogLevel::Count - 1; i++) { + LogOutput* dummy1 = LogOutput::Stdout; + LogOutput* dummy2 = LogOutput::Stderr; + LogLevelType first = static_cast(i); + LogLevelType second = static_cast(i + 1); + LogOutputList list; + list.set_output_level(dummy1, first); + list.set_output_level(dummy2, second); + for (size_t j = LogLevel::First; j < LogLevel::Count; j++) { + LogLevelType other = static_cast(j); + // The first output's level will be the finest, expect it's level to be reported by the list + if (other >= first) { + EXPECT_TRUE(list.is_level(other)) + << LogLevel::name(other) << " >= " << LogLevel::name(first) << " but is_level() returns false"; + } else { + EXPECT_FALSE(list.is_level(other)) + << LogLevel::name(other) << " < " << LogLevel::name(first) << " but is_level() returns true"; + } + } + } +} + +TEST(LogOutputList, level_for) { + LogOutputList list; + + // Ask the empty list about stdout, stderr + EXPECT_EQ(LogLevel::Off, list.level_for(LogOutput::Stdout)); + EXPECT_EQ(LogLevel::Off, list.level_for(LogOutput::Stderr)); + + // Ask for level in a list with two outputs on different levels + list.set_output_level(LogOutput::Stdout, LogLevel::Info); + list.set_output_level(LogOutput::Stderr, LogLevel::Trace); + EXPECT_EQ(LogLevel::Info, list.level_for(LogOutput::Stdout)); + EXPECT_EQ(LogLevel::Trace, list.level_for(LogOutput::Stderr)); + + // Remove and ask again + list.set_output_level(LogOutput::Stdout, LogLevel::Off); + EXPECT_EQ(LogLevel::Off, list.level_for(LogOutput::Stdout)); + EXPECT_EQ(LogLevel::Trace, list.level_for(LogOutput::Stderr)); + + // Ask about an unknown output + LogOutput* dummy = dummy_output(4711); + EXPECT_EQ(LogLevel::Off, list.level_for(dummy)); + + for (size_t i = LogLevel::First; i <= LogLevel::Last; i++) { + LogLevelType level = static_cast(i); + list.set_output_level(dummy, level); + EXPECT_EQ(level, list.level_for(dummy)); + } + + // Make sure the stderr level is still the same + EXPECT_EQ(LogLevel::Trace, list.level_for(LogOutput::Stderr)); +} diff --git a/hotspot/test/native/logging/test_logTag.cpp b/hotspot/test/native/logging/test_logTag.cpp new file mode 100644 index 00000000000..3017a2da4fb --- /dev/null +++ b/hotspot/test/native/logging/test_logTag.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logging/logTag.hpp" +#include "unittest.hpp" + +TEST(LogTag, from_string) { + // Verify for all tags defined in LOG_TAG_LIST +#define LOG_TAG(tag) \ + EXPECT_EQ(PREFIX_LOG_TAG(tag), LogTag::from_string(#tag)); + LOG_TAG_LIST +#undef LOG_TAG + + // Verify a couple of invalid strings parsing as invalid tags + const char* invalid_tag[] = { + "bad tag", ".^@", "**", "*", "gcc", "+gc", "gc+", "gc+safepoint", + "gc+safepoint=warning", "warning", "=info", "gcsafepointlogging", + "gc+safepointlogging", "gclogging", "+", " gc", "logging ", "," + }; + for (size_t i = 0; i < sizeof(invalid_tag) / sizeof(*invalid_tag); i++) { + EXPECT_EQ(LogTag::__NO_TAG, LogTag::from_string(invalid_tag[i])) + << "'" << invalid_tag[i] << "' did not parse as an invalid tag"; + } +} + +TEST(LogTag, name) { + // Verify for each tag from the macro +#define LOG_TAG(tag) \ + EXPECT_STREQ(#tag, LogTag::name(PREFIX_LOG_TAG(tag))); + LOG_TAG_LIST +#undef LOG_TAG +} diff --git a/hotspot/test/native/logging/test_logTagLevelExpression.cpp b/hotspot/test/native/logging/test_logTagLevelExpression.cpp new file mode 100644 index 00000000000..72bd244a5ca --- /dev/null +++ b/hotspot/test/native/logging/test_logTagLevelExpression.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logging/logLevel.hpp" +#include "logging/logTagLevelExpression.hpp" +#include "logging/logTagSet.hpp" +#include "unittest.hpp" +#include "utilities/globalDefinitions.hpp" + +TEST(LogTagLevelExpression, parse) { + char buf[256]; + const char* invalid_substr[] = { + "=", "+", " ", "+=", "+=*", "*+", " +", "**", "++", ".", ",", ",," ",+", + " *", "all+", "all*", "+all", "+all=Warning", "==Info", "=InfoWarning", + "BadTag+", "logging++", "logging*+", ",=", "gc+gc+gc+gc+gc+gc" + }; + const char* valid_expression[] = { + "all", "gc", "gc,logging", "gc+logging", "logging+gc", "logging+gc,gc", "logging+gc*", "gc=trace", + "gc=trace,logging=info", "logging+gc=trace", "logging+gc=trace,gc+logging=warning,logging", + "gc,all=info", "logging*", "logging*=info", "gc+logging*=error", "logging*,gc=info" + }; + + // Verify valid expressions parse without problems + for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) { + LogTagLevelExpression expr; + EXPECT_TRUE(expr.parse(valid_expression[i])) << "Valid expression '" << valid_expression[i] << "' did not parse"; + } + + // Verify we can use 'all' with each available level + for (uint level = LogLevel::First; level <= LogLevel::Last; level++) { + char buf[32]; + int ret = jio_snprintf(buf, sizeof(buf), "all=%s", LogLevel::name(static_cast(level))); + ASSERT_NE(ret, -1); + + LogTagLevelExpression expr; + EXPECT_TRUE(expr.parse(buf)); + } + + // Verify invalid expressions do not parse + for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) { + for (size_t j = 0; j < ARRAY_SIZE(invalid_substr); j++) { + // Prefix with invalid substr + LogTagLevelExpression expr; + jio_snprintf(buf, sizeof(buf), "%s%s", invalid_substr[j], valid_expression[i]); + EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal"; + + // Suffix with invalid substr + LogTagLevelExpression expr1; + jio_snprintf(buf, sizeof(buf), "%s%s", valid_expression[i], invalid_substr[j]); + EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal"; + + // Use only the invalid substr + LogTagLevelExpression expr2; + EXPECT_FALSE(expr2.parse(invalid_substr[j])) << "'" << invalid_substr[j] << "'" << " considered legal"; + } + + // Suffix/prefix with some unique invalid prefixes/suffixes + LogTagLevelExpression expr; + jio_snprintf(buf, sizeof(buf), "*%s", valid_expression[i]); + EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal"; + + LogTagLevelExpression expr1; + jio_snprintf(buf, sizeof(buf), "logging*%s", valid_expression[i]); + EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal"; + } +} + +// Test the level_for() function for an empty expression +TEST(LogTagLevelExpression, level_for_empty) { + LogTagLevelExpression emptyexpr; + ASSERT_TRUE(emptyexpr.parse("")); + // All tagsets should be unspecified since the expression doesn't involve any tagset + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_EQ(LogLevel::Unspecified, emptyexpr.level_for(*ts)); + } +} + +// Test level_for() with "all" without any specified level +TEST(LogTagLevelExpression, level_for_all) { + LogTagLevelExpression allexpr; + ASSERT_TRUE(allexpr.parse("all")); + // Level will be unspecified since no level was given + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_EQ(LogLevel::Unspecified, allexpr.level_for(*ts)); + } +} + +// Test level_for() with "all=debug" +TEST(LogTagLevelExpression, level_for_all_debug) { + LogTagLevelExpression alldebugexpr; + ASSERT_TRUE(alldebugexpr.parse("all=debug")); + // All tagsets should report debug level + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_EQ(LogLevel::Debug, alldebugexpr.level_for(*ts)); + } +} + +// Test level_for() with "all=off" +TEST(LogTagLevelExpression, level_for_all_off) { + LogTagLevelExpression alloffexpr; + ASSERT_TRUE(alloffexpr.parse("all=off")); + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + EXPECT_EQ(LogLevel::Off, alloffexpr.level_for(*ts)); + } +} + +// Test level_for() with an expression that has overlap (last subexpression should be used) +TEST(LogTagLevelExpression, level_for_overlap) { + LogTagLevelExpression overlapexpr; + // The all=warning will be overridden with gc=info and/or logging+safepoint*=trace + ASSERT_TRUE(overlapexpr.parse("all=warning,gc=info,logging+safepoint*=trace")); + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + if (ts->contains(PREFIX_LOG_TAG(gc)) && ts->ntags() == 1) { + EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(*ts)); + } else if (ts->contains(PREFIX_LOG_TAG(logging)) && ts->contains(PREFIX_LOG_TAG(safepoint))) { + EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(*ts)); + } else { + EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(*ts)); + } + } + EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Trace, + overlapexpr.level_for(LogTagSetMapping::tagset())); +} + +// Test level_for() with an expression containing two independent subexpressions +TEST(LogTagLevelExpression, level_for_disjoint) { + LogTagLevelExpression reducedexpr; + ASSERT_TRUE(reducedexpr.parse("gc+logging=trace,class*=error")); + EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Trace, reducedexpr.level_for(LogTagSetMapping::tagset())); +} + +// Test level_for() with an expression that is completely overridden in the last part of the expression +TEST(LogTagLevelExpression, level_for_override) { + LogTagLevelExpression overrideexpr; + // No matter what, everything should be set to error level because of the last part + ASSERT_TRUE(overrideexpr.parse("logging,gc*=trace,all=error")); + EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping::tagset())); +} + +// Test level_for() with a mixed expression with a bit of everything +TEST(LogTagLevelExpression, level_for_mixed) { + LogTagLevelExpression mixedexpr; + ASSERT_TRUE(mixedexpr.parse("all=warning,gc*=debug,gc=trace,safepoint*=off")); + EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping::tagset())); + EXPECT_EQ(LogLevel::Trace, mixedexpr.level_for(LogTagSetMapping::tagset())); +} diff --git a/hotspot/test/native/logging/test_logTagSet.cpp b/hotspot/test/native/logging/test_logTagSet.cpp new file mode 100644 index 00000000000..327a0afc9b2 --- /dev/null +++ b/hotspot/test/native/logging/test_logTagSet.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * ac_heapanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" +#include "logging/logLevel.hpp" +#include "logging/logOutput.hpp" +#include "logging/logTag.hpp" +#include "logging/logTagSet.hpp" +#include "unittest.hpp" + +// Test the default level for each tagset +TEST(LogTagSet, defaults) { + for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) { + char buf[256]; + ts->label(buf, sizeof(buf)); + SCOPED_TRACE(buf); + EXPECT_TRUE(ts->is_level(LogLevel::Error)); + EXPECT_TRUE(ts->is_level(LogLevel::Warning)); + EXPECT_FALSE(ts->is_level(LogLevel::Info)); + EXPECT_TRUE(ts->has_output(LogOutput::Stdout)); + EXPECT_FALSE(ts->has_output(LogOutput::Stderr)); + } +} + +TEST(LogTagSet, has_output) { + LogTagSet& ts = LogTagSetMapping::tagset(); + ts.set_output_level(LogOutput::Stderr, LogLevel::Trace); + EXPECT_TRUE(ts.has_output(LogOutput::Stderr)); + EXPECT_FALSE(ts.has_output(NULL)); + ts.set_output_level(LogOutput::Stderr, LogLevel::Off); + EXPECT_FALSE(ts.has_output(LogOutput::Stderr)); +} + +TEST(LogTagSet, ntags) { + const LogTagSet& ts = LogTagSetMapping::tagset(); + EXPECT_EQ(1u, ts.ntags()); + const LogTagSet& ts2 = LogTagSetMapping::tagset(); + EXPECT_EQ(5u, ts2.ntags()); +} + +TEST(LogTagSet, is_level) { + LogTagSet& ts = LogTagSetMapping::tagset(); + // Set info level on stdout and verify that is_level() reports correctly + ts.set_output_level(LogOutput::Stdout, LogLevel::Info); + EXPECT_TRUE(ts.is_level(LogLevel::Error)); + EXPECT_TRUE(ts.is_level(LogLevel::Warning)); + EXPECT_TRUE(ts.is_level(LogLevel::Info)); + EXPECT_FALSE(ts.is_level(LogLevel::Debug)); + EXPECT_FALSE(ts.is_level(LogLevel::Trace)); + ts.set_output_level(LogOutput::Stdout, LogLevel::Default); + EXPECT_TRUE(ts.is_level(LogLevel::Default)); +} + +TEST(LogTagSet, level_for) { + LogOutput* output = LogOutput::Stdout; + LogTagSet& ts = LogTagSetMapping::tagset(); + for (uint i = 0; i < LogLevel::Count; i++) { + LogLevelType level = static_cast(i); + // Set the level and verify that level_for() reports it back + ts.set_output_level(output, level); + EXPECT_EQ(level, ts.level_for(output)); + } + ts.set_output_level(output, LogLevel::Default); +} + +TEST(LogTagSet, contains) { + // Verify that contains works as intended for a few predetermined tagsets + const LogTagSet& ts = LogTagSetMapping::tagset(); + EXPECT_TRUE(ts.contains(PREFIX_LOG_TAG(logging))); + EXPECT_FALSE(ts.contains(PREFIX_LOG_TAG(gc))); + EXPECT_FALSE(ts.contains(PREFIX_LOG_TAG(class))); + + const LogTagSet& ts2 = LogTagSetMapping::tagset(); + EXPECT_TRUE(ts2.contains(PREFIX_LOG_TAG(logging))); + EXPECT_TRUE(ts2.contains(PREFIX_LOG_TAG(gc))); + EXPECT_FALSE(ts2.contains(PREFIX_LOG_TAG(class))); + + const LogTagSet& ts3 = LogTagSetMapping::tagset(); + EXPECT_TRUE(ts3.contains(PREFIX_LOG_TAG(logging))); + EXPECT_TRUE(ts3.contains(PREFIX_LOG_TAG(gc))); + EXPECT_TRUE(ts3.contains(PREFIX_LOG_TAG(class))); + EXPECT_FALSE(ts3.contains(PREFIX_LOG_TAG(safepoint))); + + const LogTagSet& ts4 = LogTagSetMapping::tagset(); + EXPECT_TRUE(ts4.contains(PREFIX_LOG_TAG(logging))); + EXPECT_TRUE(ts4.contains(PREFIX_LOG_TAG(gc))); + EXPECT_TRUE(ts4.contains(PREFIX_LOG_TAG(class))); + EXPECT_TRUE(ts4.contains(PREFIX_LOG_TAG(safepoint))); + EXPECT_TRUE(ts4.contains(PREFIX_LOG_TAG(heap))); +} + +TEST(LogTagSet, label) { + char buf[256]; + const LogTagSet& ts = LogTagSetMapping::tagset(); + ASSERT_NE(-1, ts.label(buf, sizeof(buf))); + EXPECT_STREQ("logging,safepoint", buf); + // Verify using a custom separator + ASSERT_NE(-1, ts.label(buf, sizeof(buf), "++")); + EXPECT_STREQ("logging++safepoint", buf); + + // Verify with three tags + const LogTagSet& ts1 = LogTagSetMapping::tagset(); + ASSERT_NE(-1, ts1.label(buf, sizeof(buf))); + EXPECT_STREQ("logging,safepoint,jni", buf); + + // Verify with a single tag + const LogTagSet& ts2 = LogTagSetMapping::tagset(); + ASSERT_NE(-1, ts2.label(buf, sizeof(buf))); + EXPECT_STREQ("logging", buf); +} diff --git a/hotspot/test/runtime/ClassFile/BadHelloWorld.jcod b/hotspot/test/runtime/ClassFile/BadHelloWorld.jcod new file mode 100644 index 00000000000..9b984e602d6 --- /dev/null +++ b/hotspot/test/runtime/ClassFile/BadHelloWorld.jcod @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file fuzzes the class name #15 to have a leading 'L' and ending ';'. + */ + +class BadHelloWorld { + 0xCAFEBABE; + 0; // minor version + 52; // version + [31] { // Constant Pool + ; // first element is empty + Utf8 "BadHelloWorld"; // #1 at 0x0A + class #1; // #2 at 0x1A + Utf8 "java/lang/Object"; // #3 at 0x1D + class #3; // #4 at 0x30 + Utf8 ""; // #5 at 0x33 + Utf8 "()V"; // #6 at 0x3C + NameAndType #5 #6; // #7 at 0x42 + Method #4 #7; // #8 at 0x47 + Utf8 "toString"; // #9 at 0x4C + Utf8 "()Ljava/lang/String;"; // #10 at 0x57 + Utf8 "Hello, world!"; // #11 at 0x6E + String #11; // #12 at 0x7E + Utf8 "main"; // #13 at 0x81 + Utf8 "([Ljava/lang/String;)V"; // #14 at 0x88 + Utf8 "LBadHelloWorld;"; // #15 at 0xA1 + class #15; // #16 at 0xB3 + Method #16 #7; // #17 at 0xB6 + Utf8 "java/lang/System"; // #18 at 0xBB + class #18; // #19 at 0xCE + Utf8 "out"; // #20 at 0xD1 + Utf8 "Ljava/io/PrintStream;"; // #21 at 0xD7 + NameAndType #20 #21; // #22 at 0xEF + Field #19 #22; // #23 at 0xF4 + Utf8 "java/io/PrintStream"; // #24 at 0xF9 + class #24; // #25 at 0x010F + Utf8 "println"; // #26 at 0x0112 + Utf8 "(Ljava/lang/Object;)V"; // #27 at 0x011C + NameAndType #26 #27; // #28 at 0x0134 + Method #25 #28; // #29 at 0x0139 + Utf8 "Code"; // #30 at 0x013E + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #4;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [3] { // methods + { // Member at 0x0151 + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [1] { // Attributes + Attr(#30, 17) { // Code at 0x0159 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70008B1; + }; + [0] { // Traps + } // end Traps + [0] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x0170 + 0x0001; // access + #9; // name_cpx + #10; // sig_cpx + [1] { // Attributes + Attr(#30, 15) { // Code at 0x0178 + 1; // max_stack + 1; // max_locals + Bytes[3]{ + 0x120CB0; + }; + [0] { // Traps + } // end Traps + [0] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x018D + 0x0089; // access + #13; // name_cpx + #14; // sig_cpx + [1] { // Attributes + Attr(#30, 28) { // Code at 0x0195 + 2; // max_stack + 2; // max_locals + Bytes[16]{ + 0xBB001059B700114C; + 0xB200172BB6001DB1; + }; + [0] { // Traps + } // end Traps + [0] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [0] { // Attributes + } // Attributes +} // end class BadHelloWorld diff --git a/hotspot/test/runtime/ClassFile/FormatCheckingTest.java b/hotspot/test/runtime/ClassFile/FormatCheckingTest.java new file mode 100644 index 00000000000..243f00f2cf1 --- /dev/null +++ b/hotspot/test/runtime/ClassFile/FormatCheckingTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8148854 + * @summary Ensure class name loaded by app class loader is format checked by default + * @library /test/lib + * @compile BadHelloWorld.jcod + * @modules java.base/jdk.internal.misc + * java.management + * @run main FormatCheckingTest + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class FormatCheckingTest { + public static void main(String args[]) throws Throwable { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("BadHelloWorld"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("java.lang.ClassFormatError: Illegal class name"); + output.shouldHaveExitValue(1); + } +} diff --git a/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java b/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java index b6a7d1311a2..a5a19fed1df 100644 --- a/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java +++ b/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java @@ -34,13 +34,13 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.Platform; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; public class CreateCoredumpOnCrash { private static class Crasher { public static void main(String[] args) { - Utils.getUnsafe().putInt(0L, 0); + UnsafeHelper.getUnsafe().putInt(0L, 0); } } diff --git a/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java b/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java index 768ffae1994..e3b88c29673 100644 --- a/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java +++ b/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java @@ -35,14 +35,14 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; public class ProblematicFrameTest { private static class Crasher { public static void main(String[] args) { - Utils.getUnsafe().getInt(0); + UnsafeHelper.getUnsafe().getInt(0); } } diff --git a/hotspot/test/runtime/MinimalVM/CDS.java b/hotspot/test/runtime/MinimalVM/CDS.java new file mode 100644 index 00000000000..e166d961fac --- /dev/null +++ b/hotspot/test/runtime/MinimalVM/CDS.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @requires vm.flavor == "minimal" + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @run driver CDS + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class CDS { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb; + + pb = ProcessTools.createJavaProcessBuilder("-minimal", "-Xshare:dump"); + new OutputAnalyzer(pb.start()) + .shouldContain("Shared spaces are not supported in this VM") + .shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-minimal", "-Xshare:on"); + new OutputAnalyzer(pb.start()) + .shouldContain("Shared spaces are not supported in this VM") + .shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-minimal", "-Xshare:auto", "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Shared spaces are not supported in this VM") + .shouldHaveExitValue(0); + } +} diff --git a/hotspot/test/runtime/MinimalVM/CheckJNI.java b/hotspot/test/runtime/MinimalVM/CheckJNI.java new file mode 100644 index 00000000000..14219653574 --- /dev/null +++ b/hotspot/test/runtime/MinimalVM/CheckJNI.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @requires vm.flavor == "minimal" + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @run driver CheckJNI + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class CheckJNI { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-minimal", "-Xcheck:jni", "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Minimal VM warning: JNI CHECKING is not supported in this VM") + .shouldHaveExitValue(0); + } +} diff --git a/hotspot/test/runtime/MinimalVM/Instrumentation.java b/hotspot/test/runtime/MinimalVM/Instrumentation.java new file mode 100644 index 00000000000..c5c56cead35 --- /dev/null +++ b/hotspot/test/runtime/MinimalVM/Instrumentation.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @library /test/lib + * @requires vm.flavor == "minimal" + * @modules java.base/jdk.internal.misc + * java.instrument + * @run driver Instrumentation + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class Instrumentation { + + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-minimal", "-javaagent:redefineagent.jar", "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Instrumentation agents are not supported in this VM") + .shouldHaveExitValue(1); + } +} diff --git a/hotspot/test/runtime/MinimalVM/JMX.java b/hotspot/test/runtime/MinimalVM/JMX.java new file mode 100644 index 00000000000..e57325ebaa7 --- /dev/null +++ b/hotspot/test/runtime/MinimalVM/JMX.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @requires vm.flavor == "minimal" + * @library /test/lib + * @run main/othervm JMX + */ + +import jdk.test.lib.JDKToolFinder; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class JMX { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb; + + pb = ProcessTools.createJavaProcessBuilder("-minimal", "-XX:+ManagementServer", "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("ManagementServer is not supported in this VM.") + .shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-minimal", "-Dcom.sun.management ", "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("-Dcom.sun.management is not supported in this VM.") + .shouldHaveExitValue(1); + + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), Long.toString(ProcessTools.getProcessId()), "VM.print_threads"}); + new OutputAnalyzer(pb.start()) + .shouldContain("Could not find any processes matching ") + .shouldHaveExitValue(1); + } +} diff --git a/hotspot/test/runtime/MinimalVM/JVMTI.java b/hotspot/test/runtime/MinimalVM/JVMTI.java new file mode 100644 index 00000000000..ef3f481d15d --- /dev/null +++ b/hotspot/test/runtime/MinimalVM/JVMTI.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @requires vm.flavor == "minimal" + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @run driver JVMTI + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class JVMTI { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-minimal", + "-agentlib:jdwp=server=y,transport=dt_socket,address=5000,suspend=n", + "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Debugging agents are not supported in this VM") + .shouldHaveExitValue(1); + + } +} diff --git a/hotspot/test/runtime/MinimalVM/NMT.java b/hotspot/test/runtime/MinimalVM/NMT.java new file mode 100644 index 00000000000..815fa6d0195 --- /dev/null +++ b/hotspot/test/runtime/MinimalVM/NMT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @requires vm.flavor == "minimal" + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @run driver NMT + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class NMT { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb; + + pb = ProcessTools.createJavaProcessBuilder("-minimal", "-XX:NativeMemoryTracking=detail", "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Native Memory Tracking is not supported in this VM") + .shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-minimal", "-XX:NativeMemoryTracking=summary", "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Native Memory Tracking is not supported in this VM") + .shouldHaveExitValue(1); + + pb = ProcessTools.createJavaProcessBuilder("-minimal", "-XX:NativeMemoryTracking=off", "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Native Memory Tracking is not supported in this VM") + .shouldHaveExitValue(1); + + + } +} diff --git a/hotspot/test/runtime/MinimalVM/Xprof.java b/hotspot/test/runtime/MinimalVM/Xprof.java new file mode 100644 index 00000000000..dd3e337cc66 --- /dev/null +++ b/hotspot/test/runtime/MinimalVM/Xprof.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @requires vm.flavor == "minimal" + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @run driver Xprof + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class Xprof { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-minimal", "-Xprof", "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Flat profiling is not supported in this VM.") + .shouldHaveExitValue(1); + + } +} diff --git a/hotspot/test/runtime/RedefineObject/TestRedefineObject.java b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java index 7479dff7839..1b50e0efbb8 100644 --- a/hotspot/test/runtime/RedefineObject/TestRedefineObject.java +++ b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java @@ -42,7 +42,7 @@ import jdk.test.lib.process.OutputAnalyzer; * @build Agent * @run main ClassFileInstaller Agent * @run main TestRedefineObject - * @run main/othervm -javaagent:agent.jar -XX:TraceRedefineClasses=5 Agent + * @run main/othervm -javaagent:agent.jar -Xlog:redefine+class+load=debug,redefine+class+timer=info Agent */ public class TestRedefineObject { public static void main(String[] args) throws Exception { diff --git a/hotspot/test/runtime/RedefineTests/RedefineRunningMethods.java b/hotspot/test/runtime/RedefineTests/RedefineRunningMethods.java index 25aaa16a90d..d1c5545492e 100644 --- a/hotspot/test/runtime/RedefineTests/RedefineRunningMethods.java +++ b/hotspot/test/runtime/RedefineTests/RedefineRunningMethods.java @@ -31,7 +31,7 @@ * java.instrument * jdk.jartool/sun.tools.jar * @run main RedefineClassHelper - * @run main/othervm -javaagent:redefineagent.jar -XX:TraceRedefineClasses=0x600 RedefineRunningMethods + * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace RedefineRunningMethods */ public class RedefineRunningMethods { diff --git a/hotspot/test/runtime/RedefineTests/RedefineRunningMethodsWithResolutionErrors.java b/hotspot/test/runtime/RedefineTests/RedefineRunningMethodsWithResolutionErrors.java index 4d068a25711..3560e9472c0 100644 --- a/hotspot/test/runtime/RedefineTests/RedefineRunningMethodsWithResolutionErrors.java +++ b/hotspot/test/runtime/RedefineTests/RedefineRunningMethodsWithResolutionErrors.java @@ -31,7 +31,7 @@ * java.instrument * jdk.jartool/sun.tools.jar * @run main RedefineClassHelper - * @run main/othervm -javaagent:redefineagent.jar -XX:TraceRedefineClasses=0x600 RedefineRunningMethodsWithResolutionErrors + * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace RedefineRunningMethodsWithResolutionErrors */ import jdk.internal.org.objectweb.asm.ClassWriter; diff --git a/hotspot/test/runtime/Unsafe/AllocateInstance.java b/hotspot/test/runtime/Unsafe/AllocateInstance.java index 56c7f8f95d0..ca2d56dd749 100644 --- a/hotspot/test/runtime/Unsafe/AllocateInstance.java +++ b/hotspot/test/runtime/Unsafe/AllocateInstance.java @@ -30,12 +30,12 @@ * @run main AllocateInstance */ -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class AllocateInstance { - static final Unsafe UNSAFE = Utils.getUnsafe(); + static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); class TestClass { public boolean calledConstructor = false; diff --git a/hotspot/test/runtime/Unsafe/AllocateMemory.java b/hotspot/test/runtime/Unsafe/AllocateMemory.java index c32ef73664f..afb48c24488 100644 --- a/hotspot/test/runtime/Unsafe/AllocateMemory.java +++ b/hotspot/test/runtime/Unsafe/AllocateMemory.java @@ -31,13 +31,13 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m AllocateMemory */ -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class AllocateMemory { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); // Allocate a byte, write to the location and read back the value long address = unsafe.allocateMemory(1); diff --git a/hotspot/test/runtime/Unsafe/CopyMemory.java b/hotspot/test/runtime/Unsafe/CopyMemory.java index 3afe405db3a..0b832c3ee67 100644 --- a/hotspot/test/runtime/Unsafe/CopyMemory.java +++ b/hotspot/test/runtime/Unsafe/CopyMemory.java @@ -30,14 +30,14 @@ * @run main CopyMemory */ -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class CopyMemory { final static int LENGTH = 8; public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); long src = unsafe.allocateMemory(LENGTH); long dst = unsafe.allocateMemory(LENGTH); assertNotEquals(src, 0L); diff --git a/hotspot/test/runtime/Unsafe/DefineClass.java b/hotspot/test/runtime/Unsafe/DefineClass.java index 44f8aeaef27..613e9afef6f 100644 --- a/hotspot/test/runtime/Unsafe/DefineClass.java +++ b/hotspot/test/runtime/Unsafe/DefineClass.java @@ -34,13 +34,13 @@ import java.security.ProtectionDomain; import java.io.InputStream; import jdk.test.lib.InMemoryJavaCompiler; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class DefineClass { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); TestClassLoader classloader = new TestClassLoader(); ProtectionDomain pd = new ProtectionDomain(null, null); diff --git a/hotspot/test/runtime/Unsafe/FieldOffset.java b/hotspot/test/runtime/Unsafe/FieldOffset.java index 43bdf871e5f..b4d425b8421 100644 --- a/hotspot/test/runtime/Unsafe/FieldOffset.java +++ b/hotspot/test/runtime/Unsafe/FieldOffset.java @@ -31,14 +31,14 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import java.lang.reflect.*; import static jdk.test.lib.Asserts.*; public class FieldOffset { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Field[] fields = Test.class.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { diff --git a/hotspot/test/runtime/Unsafe/GetField.java b/hotspot/test/runtime/Unsafe/GetField.java index 3aa5ede2c0f..48533068f31 100644 --- a/hotspot/test/runtime/Unsafe/GetField.java +++ b/hotspot/test/runtime/Unsafe/GetField.java @@ -30,14 +30,14 @@ * @run main GetField */ -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import java.lang.reflect.*; import static jdk.test.lib.Asserts.*; public class GetField { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); // Unsafe.INVALID_FIELD_OFFSET is a static final int field, // make sure getField returns the correct field Field field = Unsafe.class.getField("INVALID_FIELD_OFFSET"); diff --git a/hotspot/test/runtime/Unsafe/GetPutAddress.java b/hotspot/test/runtime/Unsafe/GetPutAddress.java index 0b18d4d26c8..07fa4afa429 100644 --- a/hotspot/test/runtime/Unsafe/GetPutAddress.java +++ b/hotspot/test/runtime/Unsafe/GetPutAddress.java @@ -31,13 +31,13 @@ */ import jdk.test.lib.Platform; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutAddress { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); int addressSize = unsafe.addressSize(); // Ensure the size returned from Unsafe.addressSize is correct assertEquals(unsafe.addressSize(), Platform.is32bit() ? 4 : 8); diff --git a/hotspot/test/runtime/Unsafe/GetPutBoolean.java b/hotspot/test/runtime/Unsafe/GetPutBoolean.java index 03bddbfd5dd..fe53ad4f911 100644 --- a/hotspot/test/runtime/Unsafe/GetPutBoolean.java +++ b/hotspot/test/runtime/Unsafe/GetPutBoolean.java @@ -31,13 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutBoolean { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("b1"); diff --git a/hotspot/test/runtime/Unsafe/GetPutByte.java b/hotspot/test/runtime/Unsafe/GetPutByte.java index 10ccbfdcf59..9e2909e4e7d 100644 --- a/hotspot/test/runtime/Unsafe/GetPutByte.java +++ b/hotspot/test/runtime/Unsafe/GetPutByte.java @@ -31,13 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutByte { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("b"); diff --git a/hotspot/test/runtime/Unsafe/GetPutChar.java b/hotspot/test/runtime/Unsafe/GetPutChar.java index 8a05acd7018..7fcfeea8c26 100644 --- a/hotspot/test/runtime/Unsafe/GetPutChar.java +++ b/hotspot/test/runtime/Unsafe/GetPutChar.java @@ -31,13 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutChar { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("c"); diff --git a/hotspot/test/runtime/Unsafe/GetPutDouble.java b/hotspot/test/runtime/Unsafe/GetPutDouble.java index f9ccd548873..fb7210ae2ff 100644 --- a/hotspot/test/runtime/Unsafe/GetPutDouble.java +++ b/hotspot/test/runtime/Unsafe/GetPutDouble.java @@ -31,13 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutDouble { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("d"); diff --git a/hotspot/test/runtime/Unsafe/GetPutFloat.java b/hotspot/test/runtime/Unsafe/GetPutFloat.java index 005b2301591..26821864435 100644 --- a/hotspot/test/runtime/Unsafe/GetPutFloat.java +++ b/hotspot/test/runtime/Unsafe/GetPutFloat.java @@ -31,13 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutFloat { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("f"); diff --git a/hotspot/test/runtime/Unsafe/GetPutInt.java b/hotspot/test/runtime/Unsafe/GetPutInt.java index a43b7e17ef0..56b4d762974 100644 --- a/hotspot/test/runtime/Unsafe/GetPutInt.java +++ b/hotspot/test/runtime/Unsafe/GetPutInt.java @@ -30,13 +30,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutInt { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("i"); diff --git a/hotspot/test/runtime/Unsafe/GetPutLong.java b/hotspot/test/runtime/Unsafe/GetPutLong.java index 8feef0bce3c..d039e2275aa 100644 --- a/hotspot/test/runtime/Unsafe/GetPutLong.java +++ b/hotspot/test/runtime/Unsafe/GetPutLong.java @@ -31,13 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutLong { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("l"); diff --git a/hotspot/test/runtime/Unsafe/GetPutObject.java b/hotspot/test/runtime/Unsafe/GetPutObject.java index aa6c75dbbe0..1ffc7b4d756 100644 --- a/hotspot/test/runtime/Unsafe/GetPutObject.java +++ b/hotspot/test/runtime/Unsafe/GetPutObject.java @@ -31,13 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutObject { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Test t = new Test(); Object o = new Object(); Field field = Test.class.getField("o"); diff --git a/hotspot/test/runtime/Unsafe/GetPutShort.java b/hotspot/test/runtime/Unsafe/GetPutShort.java index 7a95ec23d61..ae1cb97d9ad 100644 --- a/hotspot/test/runtime/Unsafe/GetPutShort.java +++ b/hotspot/test/runtime/Unsafe/GetPutShort.java @@ -31,13 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutShort { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("s"); diff --git a/hotspot/test/runtime/Unsafe/GetUncompressedObject.java b/hotspot/test/runtime/Unsafe/GetUncompressedObject.java index f9a70e65450..380ab8438aa 100644 --- a/hotspot/test/runtime/Unsafe/GetUncompressedObject.java +++ b/hotspot/test/runtime/Unsafe/GetUncompressedObject.java @@ -30,13 +30,13 @@ import static jdk.test.lib.Asserts.*; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; public class GetUncompressedObject { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); // Allocate some memory and fill it with non-zero values. final int size = 32; diff --git a/hotspot/test/runtime/Unsafe/NestedUnsafe.java b/hotspot/test/runtime/Unsafe/NestedUnsafe.java index 1acd3e505f4..32d9bb74fbd 100644 --- a/hotspot/test/runtime/Unsafe/NestedUnsafe.java +++ b/hotspot/test/runtime/Unsafe/NestedUnsafe.java @@ -35,7 +35,7 @@ import java.security.ProtectionDomain; import java.io.InputStream; import java.lang.*; import jdk.test.lib.InMemoryJavaCompiler; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; @@ -50,7 +50,7 @@ public class NestedUnsafe { " } } "); public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); Class klass = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf, new Object[0]); unsafe.ensureClassInitialized(klass); diff --git a/hotspot/test/runtime/Unsafe/PageSize.java b/hotspot/test/runtime/Unsafe/PageSize.java index 39b6c7cf7fa..a0b487a4dff 100644 --- a/hotspot/test/runtime/Unsafe/PageSize.java +++ b/hotspot/test/runtime/Unsafe/PageSize.java @@ -31,13 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class PageSize { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); int pageSize = unsafe.pageSize(); for (int n = 1; n != 0; n <<= 1) { diff --git a/hotspot/test/runtime/Unsafe/RangeCheck.java b/hotspot/test/runtime/Unsafe/RangeCheck.java index 76ccea330e5..e9e9f224a29 100644 --- a/hotspot/test/runtime/Unsafe/RangeCheck.java +++ b/hotspot/test/runtime/Unsafe/RangeCheck.java @@ -33,7 +33,7 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.Platform; -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; @@ -60,7 +60,7 @@ public class RangeCheck { public static class DummyClassWithMainRangeCheck { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); unsafe.getObject(new DummyClassWithMainRangeCheck(), Short.MAX_VALUE); } } diff --git a/hotspot/test/runtime/Unsafe/Reallocate.java b/hotspot/test/runtime/Unsafe/Reallocate.java index 5dec176fa04..837e587fc28 100644 --- a/hotspot/test/runtime/Unsafe/Reallocate.java +++ b/hotspot/test/runtime/Unsafe/Reallocate.java @@ -31,13 +31,13 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m Reallocate */ -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class Reallocate { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); long address = unsafe.allocateMemory(1); assertNotEquals(address, 0L); diff --git a/hotspot/test/runtime/Unsafe/SetMemory.java b/hotspot/test/runtime/Unsafe/SetMemory.java index a426c741a3d..77eed63f60a 100644 --- a/hotspot/test/runtime/Unsafe/SetMemory.java +++ b/hotspot/test/runtime/Unsafe/SetMemory.java @@ -30,13 +30,13 @@ * @run main SetMemory */ -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class SetMemory { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); long address = unsafe.allocateMemory(1); assertNotEquals(address, 0L); unsafe.setMemory(address, 1, (byte)17); diff --git a/hotspot/test/runtime/Unsafe/ThrowException.java b/hotspot/test/runtime/Unsafe/ThrowException.java index 5056000acb3..465618c3cff 100644 --- a/hotspot/test/runtime/Unsafe/ThrowException.java +++ b/hotspot/test/runtime/Unsafe/ThrowException.java @@ -30,13 +30,13 @@ * @run main ThrowException */ -import jdk.test.lib.Utils; +import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class ThrowException { public static void main(String args[]) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); + Unsafe unsafe = UnsafeHelper.getUnsafe(); try { unsafe.throwException(new TestException()); } catch (Throwable t) { diff --git a/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java b/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java deleted file mode 100644 index 6af55b5fdf9..00000000000 --- a/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import jdk.test.lib.JDKToolLauncher; -import jdk.test.lib.process.OutputBuffer; -import jdk.test.lib.Platform; -import jdk.test.lib.process.ProcessTools; - -import java.io.File; - -/* - * @test - * @bug 8028623 - * @summary Test hashing of extended characters in Serviceability Agent. - * @library /test/lib - * @modules java.base/jdk.internal.misc - * java.compiler - * java.management - * jdk.jvmstat/sun.jvmstat.monitor - * @compile -encoding utf8 Test8028623.java - * @run main/othervm -XX:+UsePerfData Test8028623 - */ -public class Test8028623 { - - public static int \u00CB = 1; - public static String dumpFile = "heap.bin"; - - public static void main (String[] args) { - - System.out.println(\u00CB); - - try { - if (!Platform.shouldSAAttach()) { - System.out.println("SA attach not expected to work - test skipped."); - return; - } - long pid = ProcessTools.getProcessId(); - JDKToolLauncher jmap = JDKToolLauncher.create("jhsdb") - .addToolArg("jmap") - .addToolArg("--binaryheap") - .addToolArg("--pid") - .addToolArg(Long.toString(pid)); - ProcessBuilder pb = new ProcessBuilder(jmap.getCommand()); - OutputBuffer output = ProcessTools.getOutput(pb); - Process p = pb.start(); - int e = p.waitFor(); - System.out.println("stdout:"); - System.out.println(output.getStdout()); - System.out.println("stderr:"); - System.out.println(output.getStderr()); - - if (e != 0) { - throw new RuntimeException("jmap returns: " + e); - } - if (! new File(dumpFile).exists()) { - throw new RuntimeException("dump file NOT created: '" + dumpFile + "'"); - } - } catch (Throwable t) { - t.printStackTrace(); - throw new RuntimeException("Test failed with: " + t); - } - } -} diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java index a8e149161f4..a86010c84ae 100644 --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java @@ -39,7 +39,7 @@ import java.util.regex.Pattern; * Concrete subclasses should implement method {@link #process()}. */ public abstract class PathHandler { - private static final Unsafe UNSAFE = jdk.test.lib.Utils.getUnsafe(); + private static final Unsafe UNSAFE = jdk.test.lib.unsafe.UnsafeHelper.getUnsafe(); private static final AtomicLong CLASS_COUNT = new AtomicLong(0L); private static volatile boolean CLASSES_LIMIT_REACHED = false; private static final Pattern JAR_IN_DIR_PATTERN diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 380d39ea6ab..e81f2084cef 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -375,3 +375,4 @@ bdc3c0b737efbf899709eb3121ce760dcfb51151 jdk-9+127 e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130 874082a9b565a7092a40bfa934a6e3e3c3455a60 jdk-9+131 907445d85e680ea410fe2c83c0ec64b5508e4f3e jdk-9+132 +9490ba2e5e41685c858a0ca2a6ec87611eb011c6 jdk-9+133 diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java index 52f944101dc..4f0ce4794e8 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java @@ -1,15 +1,15 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2001-2004 The Apache Software Foundation. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -169,6 +169,14 @@ public class ErrorMessages extends ListResourceBundle { {ErrorMsg.INVALID_URI_ERR, "Invalid URI ''{0}''."}, + /* + * Note to translators: This message is displayed when the URI + * mentioned in the substitution text is not well-formed syntactically. + */ + {ErrorMsg.CATALOG_EXCEPTION, + "JAXP08090001: The CatalogResolver is enabled with the catalog \"{0}\", " + + "but a CatalogException is returned."}, + /* * Note to translators: The file or URI named in the substitution text * exists but could not be opened. diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java index 4192cf2d7e6..69d410b2fa5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java @@ -1,15 +1,15 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2001-2004 The Apache Software Foundation. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,9 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: ErrorMsg.java,v 1.2.4.1 2005/09/15 10:18:01 pvedula Exp $ - */ package com.sun.org.apache.xalan.internal.xsltc.compiler.util; @@ -60,6 +57,7 @@ public final class ErrorMsg { public static final String ARGUMENT_CONVERSION_ERR = "ARGUMENT_CONVERSION_ERR"; public static final String FILE_NOT_FOUND_ERR = "FILE_NOT_FOUND_ERR"; public static final String INVALID_URI_ERR = "INVALID_URI_ERR"; + public static final String CATALOG_EXCEPTION = "CATALOG_EXCEPTION"; public static final String FILE_ACCESS_ERR = "FILE_ACCESS_ERR"; public static final String MISSING_ROOT_ERR = "MISSING_ROOT_ERR"; public static final String NAMESPACE_UNDEF_ERR = "NAMESPACE_UNDEF_ERR"; diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java index 84ed22dcd21..c0b29dbf0e9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java @@ -51,10 +51,11 @@ import java.util.Vector; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.xml.XMLConstants; +import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures.Feature; import javax.xml.catalog.CatalogManager; -import javax.xml.catalog.CatalogUriResolver; +import javax.xml.catalog.CatalogResolver; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.ErrorListener; @@ -241,7 +242,7 @@ public class TransformerFactoryImpl // type checking private Map _xsltcExtensionFunctions; - CatalogUriResolver _catalogUriResolver; + CatalogResolver _catalogUriResolver; CatalogFeatures _catalogFeatures; CatalogFeatures.Builder cfBuilder = CatalogFeatures.builder(); // Catalog features @@ -634,7 +635,7 @@ public class TransformerFactoryImpl } // Inefficient, but array is small - for (int i = 0; i < features.length; i++) { + for (int i =0; i < features.length; i++) { if (name.equals(features[i])) { return true; } @@ -923,7 +924,7 @@ public class TransformerFactoryImpl String transletClassName = getTransletBaseName(source); if (_packageName != null) - transletClassName = _packageName + "." + transletClassName; + transletClassName = _packageName + "." + transletClassName; if (_jarFileName != null) bytecodes = getBytecodesFromJar(source, transletClassName); @@ -1327,7 +1328,7 @@ public class TransformerFactoryImpl if (source == null && _catalogFiles != null && _xmlFeatures.getFeature(JdkXmlFeatures.XmlFeature.USE_CATALOG)) { if (_catalogUriResolver == null) { - _catalogUriResolver = CatalogManager.catalogUriResolver(_catalogFeatures); + _catalogUriResolver = CatalogManager.catalogResolver(_catalogFeatures); } source = _catalogUriResolver.resolve(href, context); } @@ -1340,6 +1341,10 @@ public class TransformerFactoryImpl final ErrorMsg msg = new ErrorMsg(ErrorMsg.INVALID_URI_ERR, href + "\n" + e.getMessage(), this); xsltc.getParser().reportError(Constants.FATAL, msg); } + catch (CatalogException e) { + final ErrorMsg msg = new ErrorMsg(ErrorMsg.CATALOG_EXCEPTION, href + "\n" + e.getMessage(), this); + xsltc.getParser().reportError(Constants.FATAL, msg); + } return null; } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java index 46dd7b60c56..97de2fdfbdf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java @@ -60,9 +60,10 @@ import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; import javax.xml.XMLConstants; +import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogManager; -import javax.xml.catalog.CatalogUriResolver; +import javax.xml.catalog.CatalogResolver; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -224,7 +225,7 @@ public final class TransformerImpl extends Transformer // Catalog features CatalogFeatures _catalogFeatures; - CatalogUriResolver _catalogUriResolver; + CatalogResolver _catalogUriResolver; // Catalog is enabled by default boolean _useCatalog = true; @@ -1337,7 +1338,7 @@ public final class TransformerImpl extends Transformer if (resolvedSource == null && _useCatalog && _catalogFeatures.get(CatalogFeatures.Feature.FILES) != null) { if (_catalogUriResolver == null) { - _catalogUriResolver = CatalogManager.catalogUriResolver(_catalogFeatures); + _catalogUriResolver = CatalogManager.catalogResolver(_catalogFeatures); } resolvedSource = _catalogUriResolver.resolve(href, baseURI); } @@ -1350,7 +1351,7 @@ public final class TransformerImpl extends Transformer return getDOM(resolvedSource); } - catch (TransformerException e) { + catch (TransformerException | CatalogException e) { if (_errorListener != null) postErrorToListener("File not found: " + e.getMessage()); return(null); diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index bf1b53b1b32..6cd1fd0435c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -511,7 +511,8 @@ public class XMLDocumentFragmentScannerImpl //fDocumentHandler.endElement(getElementQName(),null); break; default : - throw new InternalError("processing event: " + event); + // Errors should have already been handled by the Scanner + return false; } //System.out.println("here in before calling next"); diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index 8e25a0b286a..d3b848c9847 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java @@ -20,8 +20,6 @@ package com.sun.org.apache.xerces.internal.impl ; -import com.sun.org.apache.xerces.internal.impl.Constants; -import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader; import com.sun.org.apache.xerces.internal.impl.io.UCSReader; import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader; @@ -42,7 +40,6 @@ import com.sun.xml.internal.stream.StaxEntityResolverWrapper; import com.sun.xml.internal.stream.StaxXMLInputSource; import com.sun.xml.internal.stream.XMLEntityStorage; import java.io.*; -import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URISyntaxException; import java.net.URL; @@ -59,7 +56,6 @@ import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures.Feature; import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import javax.xml.stream.XMLInputFactory; import javax.xml.transform.Source; import jdk.xml.internal.JdkXmlUtils; @@ -420,7 +416,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { private boolean fUseCatalog = true; CatalogFeatures fCatalogFeatures; CatalogResolver fCatalogResolver; - CatalogUriResolver fCatalogUriResolver; private String fCatalogFile; private String fDefer; @@ -1044,12 +1039,18 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { } fCatalogFile = fCatalogFeatures.get(Feature.FILES); if (fUseCatalog && fCatalogFile != null) { - if (fCatalogResolver == null) { - fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); - } - InputSource is = fCatalogResolver.resolveEntity(publicId, literalSystemId); - if (is != null && !is.isEmpty()) { - staxInputSource = new StaxXMLInputSource(new XMLInputSource(is, true), true); + try { + if (fCatalogResolver == null) { + fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); + } + InputSource is = fCatalogResolver.resolveEntity(publicId, literalSystemId); + if (is != null && !is.isEmpty()) { + staxInputSource = new StaxXMLInputSource(new XMLInputSource(is, true), true); + } + } catch (CatalogException e) { + fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"CatalogException", + new Object[]{SecuritySupport.sanitizePath(fCatalogFile)}, + XMLErrorReporter.SEVERITY_FATAL_ERROR, e ); } } } @@ -1140,7 +1141,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { if (fUseCatalog && fCatalogFile != null) { /* since the method can be called from various processors, both - CatalogResolver and CatalogUriResolver are used to attempt to find + EntityResolver and URIResolver are used to attempt to find a match */ InputSource is = null; @@ -1153,13 +1154,20 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { is = fCatalogResolver.resolveEntity(pid, literalSystemId); } } catch (CatalogException e) {} + if (is != null && !is.isEmpty()) { xmlInputSource = new XMLInputSource(is, true); } else if (literalSystemId != null) { - if (fCatalogUriResolver == null) { - fCatalogUriResolver = CatalogManager.catalogUriResolver(fCatalogFeatures); + if (fCatalogResolver == null) { + fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); + } + + Source source = null; + try { + source = fCatalogResolver.resolve(literalSystemId, baseSystemId); + } catch (CatalogException e) { + throw new XNIException(e); } - Source source = fCatalogUriResolver.resolve(literalSystemId, baseSystemId); if (source != null && !source.isEmpty()) { xmlInputSource = new XMLInputSource(publicId, source.getSystemId(), baseSystemId, true); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties index 01531f7ae62..9707c7690ca 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties @@ -303,3 +303,5 @@ MaxElementDepthLimit=JAXP00010006: The element \"{0}\" has a depth of \"{1}\" that exceeds the limit \"{2}\" set by \"{3}\". EntityReplacementLimit=JAXP00010007: The total number of nodes in entity references is \"{0}\" that is over the limit \"{1}\" set by \"{2}\". +# Catalog 09 + CatalogException=JAXP00090001: The CatalogResolver is enabled with the catalog \"{0}\", but a CatalogException is returned. \ No newline at end of file diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/EntityResolverWrapper.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/EntityResolverWrapper.java index 9cca074e1af..333342ce562 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/EntityResolverWrapper.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/EntityResolverWrapper.java @@ -1,13 +1,13 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2001, 2002,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -28,6 +28,7 @@ import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; +import javax.xml.catalog.CatalogException; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; @@ -132,6 +133,10 @@ public class EntityResolverWrapper } throw new XNIException(ex); } + + catch (CatalogException e) { + throw new XNIException(e); + } } // unable to resolve entity diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java index b1ccb1bc9cc..3f5410c1741 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -75,7 +75,6 @@ import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import javax.xml.transform.Source; import jdk.xml.internal.JdkXmlUtils; import org.xml.sax.InputSource; @@ -371,7 +370,6 @@ public class XIncludeHandler private boolean fUseCatalog = true; CatalogFeatures fCatalogFeatures; CatalogResolver fCatalogResolver; - CatalogUriResolver fCatalogUriResolver; private String fCatalogFile; private String fDefer; @@ -1638,10 +1636,10 @@ public class XIncludeHandler */ Source source = null; try { - if (fCatalogUriResolver == null) { - fCatalogUriResolver = CatalogManager.catalogUriResolver(fCatalogFeatures); + if (fCatalogResolver == null) { + fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); } - source = fCatalogUriResolver.resolve(href, fCurrentBaseURI.getExpandedSystemId()); + source = fCatalogResolver.resolve(href, fCurrentBaseURI.getExpandedSystemId()); } catch (CatalogException e) {} if (source != null && !source.isEmpty()) { @@ -1669,7 +1667,7 @@ public class XIncludeHandler includedSource.getBaseSystemId(), accept, acceptLanguage); } } - catch (IOException e) { + catch (IOException | CatalogException e) { reportResourceError( "XMLResourceError", new Object[] { href, e.getMessage()}); diff --git a/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/StaxEntityResolverWrapper.java b/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/StaxEntityResolverWrapper.java index d3b50721bae..d531ca0b3be 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/StaxEntityResolverWrapper.java +++ b/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/StaxEntityResolverWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ import javax.xml.stream.XMLStreamReader; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; +import javax.xml.catalog.CatalogException; /** * @@ -58,11 +59,11 @@ public class StaxEntityResolverWrapper { public StaxXMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) throws XNIException, java.io.IOException { Object object = null ; - try{ + try { object = fStaxResolver.resolveEntity(resourceIdentifier.getPublicId(), resourceIdentifier.getLiteralSystemId(), resourceIdentifier.getBaseSystemId(), null); return getStaxInputSource(object) ; - }catch(XMLStreamException streamException){ + } catch(XMLStreamException | CatalogException streamException){ throw new XNIException(streamException) ; } } diff --git a/jaxp/src/java.xml/share/classes/javax/xml/catalog/Catalog.java b/jaxp/src/java.xml/share/classes/javax/xml/catalog/Catalog.java index 848472c3111..16f70ad7581 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/Catalog.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/Catalog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,9 +42,9 @@ import java.util.stream.Stream; *

* A catalog can be used in two situations: *

    - *
  • Locate the replacement text for an external entity; + *
  • Locate the external resources with a public or system identifier; *
  • - *
  • Locate an alternate URI reference for a resource. + *
  • Locate an alternate URI reference with an URI. *
  • *
*

diff --git a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java index 2e3c5b4f74b..bc8518685f7 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,17 +76,6 @@ public final class CatalogManager { return new CatalogResolverImpl(catalog); } - /** - * Creates an instance of a {@code CatalogUriResolver} using the specified catalog. - * - * @param catalog the catalog instance - * @return an instance of a {@code CatalogResolver} - */ - public static CatalogUriResolver catalogUriResolver(Catalog catalog) { - if (catalog == null) CatalogMessages.reportNPEOnNull("catalog", null); - return new CatalogUriResolverImpl(catalog); - } - /** * Creates an instance of a {@code CatalogResolver} using the specified feature * settings and path to one or more catalog files. @@ -115,33 +104,4 @@ public final class CatalogManager { Catalog catalog = catalog(features, paths); return new CatalogResolverImpl(catalog); } - - /** - * Creates an instance of a {@code CatalogUriResolver} using the specified - * feature settings and path to one or more catalog files. - *

- * If {@code paths} is empty, system property {@code javax.xml.catalog.files} - * will be read to locate the initial list of catalog files. - *

- * If more than one catalog files are specified through the paths argument or - * {@code javax.xml.catalog.files} property, the first entry is considered - * the main catalog, while others are treated as alternative catalogs after - * those referenced by the {@code nextCatalog} elements in the main catalog. - *

- * As specified in - * - * XML Catalogs, OASIS Standard V1.1, invalid path entries will be ignored. - * No error will be reported. In case all entries are invalid, the resolver - * will return as no mapping is found. - * - * @param features the catalog features - * @param paths the path(s) to one or more catalogs - * - * @return an instance of a {@code CatalogUriResolver} - * @throws CatalogException If an error occurs while parsing the catalog - */ - public static CatalogUriResolver catalogUriResolver(CatalogFeatures features, String... paths) { - Catalog catalog = catalog(features, paths); - return new CatalogUriResolverImpl(catalog); - } } diff --git a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolver.java b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolver.java index b517f0713f1..ecf506f5cab 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolver.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,32 +24,90 @@ */ package javax.xml.catalog; +import java.io.InputStream; +import javax.xml.stream.XMLResolver; +import javax.xml.transform.Source; +import javax.xml.transform.URIResolver; +import org.w3c.dom.ls.LSInput; +import org.w3c.dom.ls.LSResourceResolver; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; /** - * A SAX EntityResolver that uses catalogs to resolve references. + * A Catalog Resolver that implements SAX {@link org.xml.sax.EntityResolver}, + * StAX {@link javax.xml.stream.XMLResolver}, + * DOM LS {@link org.w3c.dom.ls.LSResourceResolver} used by Schema Validation, and + * Transform {@link javax.xml.transform.URIResolver}, and resolves + * external references using catalogs. + *

+ * The + * Catalog Standard distinguished {@code external identifiers} from {@code uri entries} + * as being used to solely identify DTDs, while {@code uri entries} for + * other resources such as stylesheets and schema. The Java APIs, such as + * {@link javax.xml.stream.XMLResolver} and {@link org.w3c.dom.ls.LSResourceResolver} + * however, make no such distinction. + * In consistent with the existing Java API, this CatalogResolver recognizes a + * system identifier as an URI and will search both {@code system} and {@code uri} + * entries in a catalog in order to find a matching entry. + *

+ * The search is started in the current catalog. If a match is found, + * no further attempt will be made. Only if there is no match in the current + * catalog, will alternate catalogs including delegate and next catalogs be considered. + *

+ *

Search Order

+ * The resolver will first search the system-type of entries with the specified + * {@code systemId}. The system entries include {@code system}, + * {@code rewriteSystem} and {@code systemSuffix} entries. + *

+ * If no match is found, {@code public} entries may be searched in accordance with + * the {@code prefer} attribute. + *

+ * The {@code prefer} attribute: if the {@code prefer} is public, + * and there is no match found through the system entries, {@code public} entries + * will be considered. If it is not specified, the {@code prefer} is public + * by default (Note that by the OASIS standard, system entries will always + * be considered before public entries. Prefer public means that public entries + * will be matched when both system and public identifiers are specified. + * In general therefore, prefer public is recommended.) + *

+ * If no match is found with the {@code systemId} and {@code public} identifier, + * the resolver will continue searching {@code uri} entries + * with the specified {@code systemId} or {@code href}. The {@code uri} entries + * include {@code uri}, {@code rewriteURI}, and {@code uriSuffix} entries. + * + *

+ *

Error Handling

+ * The interfaces that the CatalogResolver extend specified checked exceptions, including: + *
    + *
  • + * {@link org.xml.sax.SAXException} and {@link java.io.IOException} by + * {@link org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)} + *
  • + *
  • + * {@link javax.xml.stream.XMLStreamException} by + * {@link javax.xml.stream.XMLResolver#resolveEntity(java.lang.String, java.lang.String, java.lang.String, java.lang.String)} + *
  • + *
  • + * {@link javax.xml.transform.TransformerException} by + * {@link javax.xml.transform.URIResolver#resolve(java.lang.String, java.lang.String)} + *
  • + *
+ *

+ * The CatalogResolver however, will throw {@link javax.xml.catalog.CatalogException} + * only when {@code javax.xml.catalog.resolve} is specified as {@code strict}. + * For applications that expect to handle the checked Exceptions, it may be + * necessary to use a custom resolver to wrap the CatalogResolver or implement it + * with a {@link javax.xml.catalog.Catalog} object. * * @since 9 */ -public interface CatalogResolver extends EntityResolver { +public interface CatalogResolver extends EntityResolver, XMLResolver, + URIResolver, LSResourceResolver { /** - * The method searches through the catalog entries in the main and - * alternative catalogs to attempt to find a match with the specified publicId - * or systemId. - *

- * For resolving external entities, system entries will be matched before - * the public entries. - *

- * The {@code prefer} attribute: if the {@code prefer} is public, - * and there is no match found through the system entries, public entries - * will be considered. If it is not specified, the {@code prefer} is public - * by default (Note that by the OASIS standard, system entries will always - * be considered first when the external system identifier is specified. - * Prefer public means that public entries will be matched when both system - * and public identifiers are specified. In general therefore, prefer - * public is recommended.) + * Implements {@link org.xml.sax.EntityResolver}. The method searches through + * the catalog entries in the main and alternative catalogs to attempt to find + * a match with the specified {@code publicId} or systemId. * * @param publicId the public identifier of the external entity being * referenced, or null if none was supplied @@ -59,15 +117,123 @@ public interface CatalogResolver extends EntityResolver { * requires a system identifier on all external entities, so this value is * always specified. * - * @return a {@link org.xml.sax.InputSource} object if a mapping is found. If no mapping is - * found, returns a {@link org.xml.sax.InputSource} object containing an empty - * {@link java.io.Reader} if the {@code javax.xml.catalog.resolve} property - * is set to {@code ignore}; returns null if the + * @return a {@link org.xml.sax.InputSource} object if a mapping is found. + * If no mapping is found, returns a {@link org.xml.sax.InputSource} object + * containing an empty {@link java.io.Reader} if the + * {@code javax.xml.catalog.resolve} property is set to {@code ignore}; + * returns null if the * {@code javax.xml.catalog.resolve} property is set to {@code continue}. * * @throws CatalogException if no mapping is found and - * {@code javax.xml.catalog.resolve} is specified as strict + * {@code javax.xml.catalog.resolve} is specified as {@code strict} */ @Override public InputSource resolveEntity(String publicId, String systemId); + + + /** + * Implements URIResolver. The method searches through the catalog entries + * in the main and alternative catalogs to attempt to find a match + * with the specified {@code href} attribute. The {@code href} attribute will + * be used literally, with no attempt to be made absolute to the {@code base}. + *

+ * If the value is an URN, the {@code href} attribute is recognized as a + * {@code publicId}, and used to search {@code public} entries. + * If the value is an URI, it is taken as a {@code systemId}, and used to + * search both {@code system} and {@code uri} entries. + * + * + * @param href the href attribute that specifies the URI of a style sheet, + * which may be relative or absolute + * @param base The base URI against which the href attribute will be made + * absolute if the absolute URI is required + * + * @return a {@link javax.xml.transform.Source} object if a mapping is found. + * If no mapping is found, returns an empty {@link javax.xml.transform.Source} + * object if the {@code javax.xml.catalog.resolve} property is set to + * {@code ignore}; + * returns a {@link javax.xml.transform.Source} object with the original URI + * (href, or href resolved with base if base is not null) if the + * {@code javax.xml.catalog.resolve} property is set to {@code continue}. + * + * @throws CatalogException if no mapping is found and + * {@code javax.xml.catalog.resolve} is specified as {@code strict} + */ + @Override + public Source resolve(String href, String base); + + /** + * Implements {@link javax.xml.stream.XMLResolver}. For the purpose of resolving + * {@code publicId} and {@code systemId}, this method is equivalent to + * {@link #resolveEntity(java.lang.String, java.lang.String) }. + *

+ * The {@code systemId} will be used literally, with no attempt to be made + * absolute to the {@code baseUri}. The {@code baseUri} and {@code namespace} + * are not used in the search for a match in a catalog. However, a relative + * {@code systemId} in an xml source may have been made absolute by the parser + * with the {@code baseURI}, thus making it unable to find a {@code system} entry. + * In such a case, a {@code systemSuffix} entry is recommended over a + * {@code system} entry. + * + * @param publicId the public identifier of the external entity being + * referenced, or null if none was supplied + * + * @param systemId the system identifier of the external entity being + * referenced. A system identifier is required on all external entities. XML + * requires a system identifier on all external entities, so this value is + * always specified. + * @param baseUri the absolute base URI, not used by the CatalogResolver + * @param namespace the namespace of the entity to resolve, not used by the + * CatalogResolver. + * + * @return an {@link java.io.InputStream} object if a mapping is found; null + * if no mapping is found and the {@code javax.xml.catalog.resolve} property + * is set to {@code continue} or {@code ignore}. Note that for XMLResolver, + * it is not possible to ignore a reference, {@code ignore} is therefore + * treated the same as {@code continue}. + * + * @throws CatalogException if no mapping is found and + * {@code javax.xml.catalog.resolve} is specified as {@code strict} + */ + @Override + public InputStream resolveEntity(String publicId, String systemId, + String baseUri, String namespace); + + /** + * Implements {@link org.w3c.dom.ls.LSResourceResolver}. For the purpose of + * resolving {@code publicId} and {@code systemId}, this method is equivalent + * to {@link #resolveEntity(java.lang.String, java.lang.String) }. + *

+ * The {@code systemId} will be used literally, with no attempt to be made + * absolute to the {@code baseUri}. The {@code baseUri}, {@code namespaceUri} + * and {@code type} are not used in the search for a match in a catalog. + * However, a relative {@code systemId} in a source may have been made absolute + * by the parser with the {@code baseURI}, thus making it unable to find a + * {@code system} entry. In such a case, a {@code systemSuffix} entry is + * recommended over a {@code system} entry. + * + * @param type the type of the resource being resolved, + * not used by the CatalogResolver + * @param namespaceUri the namespace of the resource being resolved, + * not used by the CatalogResolver + * @param publicId the public identifier of the external entity being + * referenced, or {@code null} if no public identifier was + * supplied or if the resource is not an entity. + * @param systemId the system identifier, an URI reference of the + * external resource being referenced + * @param baseUri the absolute base URI, not used by the CatalogResolver + * + * @return a {@link org.w3c.dom.ls.LSInput} object if a mapping is found; null + * if no mapping is found and the {@code javax.xml.catalog.resolve} property + * is set to {@code continue} or {@code ignore}. Note that for + * {@link org.w3c.dom.ls.LSResourceResolver}, it is not possible to ignore a + * reference, {@code ignore} is therefore treated the same as {@code continue}. + * + * @throws CatalogException if no mapping is found and + * {@code javax.xml.catalog.resolve} is specified as {@code strict} + */ + @Override + public LSInput resolveResource(String type, String namespaceUri, + String publicId, String systemId, String baseUri); + } diff --git a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java index 326e61ad542..9bf8b357adc 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java @@ -24,15 +24,27 @@ */ package javax.xml.catalog; +import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; import java.io.StringReader; -import java.util.Iterator; +import java.net.URL; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXSource; +import org.w3c.dom.ls.LSInput; import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; /** - * A SAX EntityResolver/JAXP URIResolver that uses catalogs. + * Implements CatalogResolver. * *

- * This class implements both a SAX EntityResolver and a JAXP URIResolver. + * This class implements a SAX EntityResolver, StAX XMLResolver, + * Schema Validation LSResourceResolver and Transform URIResolver. * * * @since 9 @@ -49,9 +61,14 @@ final class CatalogResolverImpl implements CatalogResolver { this.catalog = catalog; } + /* + Implements the EntityResolver interface + */ @Override public InputSource resolveEntity(String publicId, String systemId) { + //8150187: NPE expected if the system identifier is null for CatalogResolver CatalogMessages.reportNPEOnNull("systemId", systemId); + //Normalize publicId and systemId systemId = Normalizer.normalizeURI(Util.getNotNullOrEmpty(systemId)); publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId))); @@ -87,4 +104,242 @@ final class CatalogResolverImpl implements CatalogResolver { return null; } + /* + Implements the URIResolver interface + */ + CatalogResolverImpl entityResolver; + + @Override + public Source resolve(String href, String base) { + CatalogMessages.reportNPEOnNull("href", href); + + href = Util.getNotNullOrEmpty(href); + base = Util.getNotNullOrEmpty(base); + + String result = null; + CatalogImpl c = (CatalogImpl)catalog; + String uri = Normalizer.normalizeURI(href); + //check whether uri is an urn + if (uri != null && uri.startsWith(Util.URN)) { + String publicId = Normalizer.decodeURN(uri); + if (publicId != null) { + result = Util.resolve(c, publicId, null); + } + } + + //if no match with a public id, continue search for an URI + if (result == null) { + //remove fragment if any. + int hashPos = uri.indexOf("#"); + if (hashPos >= 0) { + uri = uri.substring(0, hashPos); + } + + //search the current catalog + result = Util.resolve(c, null, uri); + } + + //Report error or return the URI as is when no match is found + if (result == null) { + GroupEntry.ResolveType resolveType = c.getResolve(); + switch (resolveType) { + case IGNORE: + return new SAXSource(new InputSource(new StringReader(""))); + case STRICT: + CatalogMessages.reportError(CatalogMessages.ERR_NO_URI_MATCH, + new Object[]{href, base}); + } + try { + URL url = null; + + if (base == null) { + url = new URL(uri); + result = url.toString(); + } else { + URL baseURL = new URL(base); + url = (href.length() == 0 ? baseURL : new URL(baseURL, uri)); + result = url.toString(); + } + } catch (java.net.MalformedURLException mue) { + CatalogMessages.reportError(CatalogMessages.ERR_CREATING_URI, + new Object[]{href, base}); + } + } + + SAXSource source = new SAXSource(); + source.setInputSource(new InputSource(result)); + setEntityResolver(source); + return source; + } + + /** + * Establish an entityResolver for newly resolved URIs. + *

+ * This is called from the URIResolver to set an EntityResolver on the SAX + * parser to be used for new XML documents that are encountered as a result + * of the document() function, xsl:import, or xsl:include. This is done + * because the XSLT processor calls out to the SAXParserFactory itself to + * create a new SAXParser to parse the new document. The new parser does not + * automatically inherit the EntityResolver of the original (although + * arguably it should). Quote from JAXP specification on Class + * SAXTransformerFactory: + *

+ * {@code If an application wants to set the ErrorHandler or EntityResolver + * for an XMLReader used during a transformation, it should use a URIResolver + * to return the SAXSource which provides (with getXMLReader) a reference to + * the XMLReader} + * + */ + private void setEntityResolver(SAXSource source) { + XMLReader reader = source.getXMLReader(); + if (reader == null) { + SAXParserFactory spFactory = new SAXParserFactoryImpl(); + spFactory.setNamespaceAware(true); + try { + reader = spFactory.newSAXParser().getXMLReader(); + } catch (ParserConfigurationException | SAXException ex) { + CatalogMessages.reportRunTimeError(CatalogMessages.ERR_PARSER_CONF, ex); + } + } + if (entityResolver != null) { + entityResolver = new CatalogResolverImpl(catalog); + } + reader.setEntityResolver(entityResolver); + source.setXMLReader(reader); + } + + @Override + public InputStream resolveEntity(String publicId, String systemId, String baseUri, String namespace) { + InputSource is = resolveEntity(publicId, systemId); + + if (is != null && !is.isEmpty()) { + + try { + return new URL(is.getSystemId()).openStream(); + } catch (IOException ex) { + //considered as no mapping. + } + + } + + GroupEntry.ResolveType resolveType = ((CatalogImpl) catalog).getResolve(); + switch (resolveType) { + case IGNORE: + return null; + case STRICT: + CatalogMessages.reportError(CatalogMessages.ERR_NO_MATCH, + new Object[]{publicId, systemId}); + } + + //no action, allow the parser to continue + return null; + } + + @Override + public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { + InputSource is = resolveEntity(publicId, systemId); + + if (is != null && !is.isEmpty()) { + return new LSInputImpl(is.getSystemId()); + } + + GroupEntry.ResolveType resolveType = ((CatalogImpl) catalog).getResolve(); + switch (resolveType) { + case IGNORE: + return null; + case STRICT: + CatalogMessages.reportError(CatalogMessages.ERR_NO_MATCH, + new Object[]{publicId, systemId}); + } + + //no action, allow the parser to continue + return null; + } + + /** + * Implements LSInput. All that we need is the systemId since the Catalog + * has already resolved it. + */ + class LSInputImpl implements LSInput { + + private String systemId; + + public LSInputImpl(String systemId) { + this.systemId = systemId; + } + + @Override + public Reader getCharacterStream() { + return null; + } + + @Override + public void setCharacterStream(Reader characterStream) { + } + + @Override + public InputStream getByteStream() { + return null; + } + + @Override + public void setByteStream(InputStream byteStream) { + } + + @Override + public String getStringData() { + return null; + } + + @Override + public void setStringData(String stringData) { + } + + @Override + public String getSystemId() { + return systemId; + } + + @Override + public void setSystemId(String systemId) { + this.systemId = systemId; + } + + @Override + public String getPublicId() { + return null; + } + + @Override + public void setPublicId(String publicId) { + } + + @Override + public String getBaseURI() { + return null; + } + + @Override + public void setBaseURI(String baseURI) { + } + + @Override + public String getEncoding() { + return null; + } + + @Override + public void setEncoding(String encoding) { + } + + @Override + public boolean getCertifiedText() { + return false; + } + + @Override + public void setCertifiedText(boolean certifiedText) { + } + } + } diff --git a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolver.java b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolver.java deleted file mode 100644 index 76ba60dd2eb..00000000000 --- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolver.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.catalog; - -import javax.xml.transform.Source; -import javax.xml.transform.URIResolver; - -/** - * A JAXP URIResolver that uses catalogs to resolve references. - * - * @since 9 - */ -public interface CatalogUriResolver extends URIResolver { - - /** - * The method searches through the catalog entries in the main and - * alternative catalogs to attempt to find a match with the specified URI. - * - * @param href an href attribute, which may be relative or absolute - * @param base The base URI against which the href attribute will be made - * absolute if the absolute URI is required - * - * @return a {@link javax.xml.transform.Source} object if a mapping is found. - * If no mapping is found, returns an empty {@link javax.xml.transform.Source} - * object if the {@code javax.xml.catalog.resolve} property is set to - * {@code ignore}; - * returns a {@link javax.xml.transform.Source} object with the original URI - * (href, or href resolved with base if base is not null) if the - * {@code javax.xml.catalog.resolve} property is set to {@code continue}. - * - * @throws CatalogException if no mapping is found and - * {@code javax.xml.catalog.resolve} is specified as strict - */ - @Override - public Source resolve(String href, String base); -} diff --git a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolverImpl.java b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolverImpl.java deleted file mode 100644 index 497aacf18fd..00000000000 --- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolverImpl.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.catalog; - -import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; -import java.io.StringReader; -import java.net.URL; -import java.util.Iterator; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; -import javax.xml.transform.Source; -import javax.xml.transform.sax.SAXSource; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; - -/** - * A SAX EntityResolver/JAXP URIResolver that uses catalogs. - *

- * This class implements both a SAX EntityResolver and a JAXP URIResolver. - * - * - * @since 9 - */ -final class CatalogUriResolverImpl implements CatalogUriResolver { - - Catalog catalog; - CatalogResolverImpl entityResolver; - - /** - * Construct an instance of the CatalogResolver from a Catalog. - * - * @param catalog A Catalog. - */ - public CatalogUriResolverImpl(Catalog catalog) { - this.catalog = catalog; - } - - @Override - public Source resolve(String href, String base) { - href = Util.getNotNullOrEmpty(href); - base = Util.getNotNullOrEmpty(base); - - if (href == null) return null; - - String result = null; - CatalogImpl c = (CatalogImpl)catalog; - String uri = Normalizer.normalizeURI(href); - //check whether uri is an urn - if (uri != null && uri.startsWith(Util.URN)) { - String publicId = Normalizer.decodeURN(uri); - if (publicId != null) { - result = Util.resolve(c, publicId, null); - } - } - - //if no match with a public id, continue search for an URI - if (result == null) { - //remove fragment if any. - int hashPos = uri.indexOf("#"); - if (hashPos >= 0) { - uri = uri.substring(0, hashPos); - } - - //search the current catalog - result = resolve(c, uri); - } - - //Report error or return the URI as is when no match is found - if (result == null) { - GroupEntry.ResolveType resolveType = c.getResolve(); - switch (resolveType) { - case IGNORE: - return new SAXSource(new InputSource(new StringReader(""))); - case STRICT: - CatalogMessages.reportError(CatalogMessages.ERR_NO_URI_MATCH, - new Object[]{href, base}); - } - try { - URL url = null; - - if (base == null) { - url = new URL(uri); - result = url.toString(); - } else { - URL baseURL = new URL(base); - url = (href.length() == 0 ? baseURL : new URL(baseURL, uri)); - result = url.toString(); - } - } catch (java.net.MalformedURLException mue) { - CatalogMessages.reportError(CatalogMessages.ERR_CREATING_URI, - new Object[]{href, base}); - } - } - - SAXSource source = new SAXSource(); - source.setInputSource(new InputSource(result)); - setEntityResolver(source); - return source; - } - - /** - * Resolves the publicId or systemId to one specified in the catalog. - * @param catalog the catalog - * @param href an href attribute, which may be relative or absolute - * @return the resolved systemId if a match is found, null otherwise - */ - String resolve(CatalogImpl catalog, String href) { - String result = null; - - //search the current catalog - catalog.reset(); - if (href != null) { - result = catalog.matchURI(href); - } - - //mark the catalog as having been searched before trying alternatives - catalog.markAsSearched(); - - //search alternative catalogs - if (result == null) { - Iterator iter = catalog.catalogs().iterator(); - while (iter.hasNext()) { - result = resolve((CatalogImpl)iter.next(), href); - if (result != null) { - break; - } - } - } - - return result; - } - - /** - * Establish an entityResolver for newly resolved URIs. - *

- * This is called from the URIResolver to set an EntityResolver on the SAX - * parser to be used for new XML documents that are encountered as a result - * of the document() function, xsl:import, or xsl:include. This is done - * because the XSLT processor calls out to the SAXParserFactory itself to - * create a new SAXParser to parse the new document. The new parser does not - * automatically inherit the EntityResolver of the original (although - * arguably it should). Quote from JAXP specification on Class - * SAXTransformerFactory: - *

- * {@code If an application wants to set the ErrorHandler or EntityResolver - * for an XMLReader used during a transformation, it should use a URIResolver - * to return the SAXSource which provides (with getXMLReader) a reference to - * the XMLReader} - * - */ - private void setEntityResolver(SAXSource source) { - XMLReader reader = source.getXMLReader(); - if (reader == null) { - SAXParserFactory spFactory = new SAXParserFactoryImpl(); - spFactory.setNamespaceAware(true); - try { - reader = spFactory.newSAXParser().getXMLReader(); - } catch (ParserConfigurationException | SAXException ex) { - CatalogMessages.reportRunTimeError(CatalogMessages.ERR_PARSER_CONF, ex); - } - } - if (entityResolver != null) { - entityResolver = new CatalogResolverImpl(catalog); - } - reader.setEntityResolver(entityResolver); - source.setXMLReader(reader); - } -} diff --git a/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java b/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java index b164f674dbd..f2b00a21ee6 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java @@ -55,6 +55,9 @@ class Util { * prefer "public": attempts to resolve with a system entry; * attempts to resolve with a public entry if no matching * system entry is found. + * + * If no match is found, continue searching uri entries + * * @param catalog the catalog * @param publicId the publicId * @param systemId the systemId @@ -77,6 +80,10 @@ class Util { resolvedSystemId = catalog.matchPublic(publicId); } + if (resolvedSystemId == null && systemId != null) { + resolvedSystemId = catalog.matchURI(systemId); + } + //mark the catalog as having been searched before trying alternatives catalog.markAsSearched(); diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/CatalogReferCircularityTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/CatalogReferCircularityTest.java index 41eda62e4ab..21a6780bb8d 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/CatalogReferCircularityTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/CatalogReferCircularityTest.java @@ -64,4 +64,3 @@ public class CatalogReferCircularityTest { { "catalogReferCircle-left.xml" } }; } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/DefaultFeaturesTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/DefaultFeaturesTest.java index 9a05145738f..0cc05e97da0 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/DefaultFeaturesTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/DefaultFeaturesTest.java @@ -69,4 +69,3 @@ public class DefaultFeaturesTest { { Feature.RESOLVE, CatalogTestUtils.RESOLVE_STRICT } }; } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java index 1f046f3bed5..626943a335b 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java @@ -86,4 +86,3 @@ public class DeferFeatureTest { return (int) method.invoke(catalog); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/DelegatePublicTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/DelegatePublicTest.java index e89c82051b0..b20aba8dbf4 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/DelegatePublicTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/DelegatePublicTest.java @@ -100,4 +100,3 @@ public class DelegatePublicTest { return catalogResolver("delegatePublic.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/DelegateSystemTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/DelegateSystemTest.java index f18b6c2eba2..e8452622462 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/DelegateSystemTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/DelegateSystemTest.java @@ -100,4 +100,3 @@ public class DelegateSystemTest { return catalogResolver("delegateSystem.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/DelegateUriTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/DelegateUriTest.java index 44addf59575..aa8d00efa1f 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/DelegateUriTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/DelegateUriTest.java @@ -27,8 +27,8 @@ import static catalog.CatalogTestUtils.catalogUriResolver; import static catalog.ResolutionChecker.checkUriResolution; import static catalog.ResolutionChecker.expectExceptionOnUri; +import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogException; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; @@ -95,8 +95,7 @@ public class DelegateUriTest { CatalogException.class } }; } - private CatalogUriResolver createResolver() { + private CatalogResolver createResolver() { return catalogUriResolver("delegateUri.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/GroupTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/GroupTest.java index fd2766896cd..80772f98927 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/GroupTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/GroupTest.java @@ -131,4 +131,3 @@ public class GroupTest { return catalogResolver(CATALOG_GROUP); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/LoadCatalogTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/LoadCatalogTest.java index b985876bb07..b2fa3a94ce8 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/LoadCatalogTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/LoadCatalogTest.java @@ -33,7 +33,6 @@ import static catalog.ResolutionChecker.checkUriResolution; import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; @@ -56,6 +55,7 @@ public class LoadCatalogTest { private static final String CATALOG_DUMMY = "dummy.xml"; private static final String ID_ALICE = "http://remote/dtd/alice/docAlice.dtd"; + private static final String ID_ALICE_URI = "http://remote/dtd/uri/alice/docAlice.dtd"; private static final String ID_DUMMY = "http://remote/dtd/doc.dtd"; @Test(dataProvider = "entityResolver") @@ -79,8 +79,8 @@ public class LoadCatalogTest { } @Test(dataProvider = "uriResolver") - public void testMatchOnUriResolver(CatalogUriResolver resolver) { - checkUriResolution(resolver, ID_ALICE, + public void testMatchOnUriResolver(CatalogResolver resolver) { + checkUriResolution(resolver, ID_ALICE_URI, "http://local/dtd/docAliceURI.dtd"); } @@ -121,4 +121,3 @@ public class LoadCatalogTest { { new String[] { CATALOG_LOADCATALOGFILES } } }; } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/NextCatalogTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/NextCatalogTest.java index 3f14dcda3e0..4dfc4d7186d 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/NextCatalogTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/NextCatalogTest.java @@ -30,7 +30,6 @@ import static catalog.ResolutionChecker.checkSysIdResolution; import static catalog.ResolutionChecker.checkUriResolution; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; @@ -154,9 +153,8 @@ public class NextCatalogTest { CATALOG_NEXTCATALOGRIGHT); } - private CatalogUriResolver createUriResolver() { + private CatalogResolver createUriResolver() { return catalogUriResolver(CATALOG_NEXTCATALOGLEFT, CATALOG_NEXTCATALOGRIGHT); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/NormalizationTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/NormalizationTest.java index b7715c0f69b..d66941940cf 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/NormalizationTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/NormalizationTest.java @@ -30,7 +30,6 @@ import static catalog.ResolutionChecker.checkSysIdResolution; import static catalog.ResolutionChecker.checkUriResolution; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; @@ -111,8 +110,7 @@ public class NormalizationTest { return catalogResolver(CATALOG_NORMALIZATION); } - private CatalogUriResolver createUriResolver() { + private CatalogResolver createUriResolver() { return catalogUriResolver(CATALOG_NORMALIZATION); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/PreferFeatureTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/PreferFeatureTest.java index c449771b135..3f783bebbe7 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/PreferFeatureTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/PreferFeatureTest.java @@ -81,4 +81,3 @@ public class PreferFeatureTest { "preferFeature.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/PreferTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/PreferTest.java index 2f73bb7cb4a..c9812ead83d 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/PreferTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/PreferTest.java @@ -92,4 +92,3 @@ public class PreferTest { return catalogResolver("prefer.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/PublicFamilyTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/PublicFamilyTest.java index e149949f98a..68081e29199 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/PublicFamilyTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/PublicFamilyTest.java @@ -70,4 +70,3 @@ public class PublicFamilyTest { return catalogResolver("publicFamily.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/PublicTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/PublicTest.java index 48c103e4203..f7a3ebd4376 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/PublicTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/PublicTest.java @@ -92,4 +92,3 @@ public class PublicTest { return catalogResolver(CATALOG_PUBLIC); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/ResolveFeatureTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/ResolveFeatureTest.java index 9cb29bd3694..7714e66ea12 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/ResolveFeatureTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/ResolveFeatureTest.java @@ -38,7 +38,6 @@ import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures.Feature; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @@ -93,7 +92,7 @@ public class ResolveFeatureTest { */ @Test public void testContinueResolutionOnUriResolver() { - CatalogUriResolver resolver = createUriResolver(RESOLVE_CONTINUE); + CatalogResolver resolver = createUriResolver(RESOLVE_CONTINUE); resolver.resolve("http://remote/dtd/bob/docBobDummy.dtd", null); checkUriResolution(resolver, "http://remote/dtd/bob/docBob.dtd", "http://local/base/dtd/docBobURI.dtd"); @@ -123,7 +122,7 @@ public class ResolveFeatureTest { return catalogResolver(createFeature(resolve), CATALOG_SYSTEM); } - private CatalogUriResolver createUriResolver(String resolve) { + private CatalogResolver createUriResolver(String resolve) { return catalogUriResolver(createFeature(resolve), CATALOG_URI); } @@ -131,4 +130,3 @@ public class ResolveFeatureTest { return builder().with(Feature.RESOLVE, resolve).build(); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/RewriteSystemTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/RewriteSystemTest.java index fb45816981c..c1a42668827 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/RewriteSystemTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/RewriteSystemTest.java @@ -95,4 +95,3 @@ public class RewriteSystemTest { return catalogResolver("rewriteSystem.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/RewriteUriTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/RewriteUriTest.java index 0a449420bd1..f4777dbaaf0 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/RewriteUriTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/RewriteUriTest.java @@ -24,11 +24,11 @@ package catalog; import static catalog.CatalogTestUtils.catalogUriResolver; -import static catalog.ResolutionChecker.checkNoMatch; +import static catalog.ResolutionChecker.checkNoUriMatch; import static catalog.ResolutionChecker.checkUriResolution; +import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogException; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; @@ -88,11 +88,10 @@ public class RewriteUriTest { */ @Test(expectedExceptions = CatalogException.class) public void testNoMatch() { - checkNoMatch(createResolver()); + checkNoUriMatch(createResolver()); } - private CatalogUriResolver createResolver() { + private CatalogResolver createResolver() { return catalogUriResolver("rewriteUri.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/SpecifyCatalogTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/SpecifyCatalogTest.java index 6085e6e60a2..47506989742 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/SpecifyCatalogTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/SpecifyCatalogTest.java @@ -36,7 +36,6 @@ import static javax.xml.catalog.CatalogFeatures.Feature.FILES; import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @@ -68,7 +67,7 @@ public class SpecifyCatalogTest { } /* - * CatalogUriResolver specifies catalog via feature javax.xml.catalog.files. + * CatalogResolver specifies catalog via feature javax.xml.catalog.files. */ @Test public void specifyCatalogOnUriResolver() { @@ -102,7 +101,7 @@ public class SpecifyCatalogTest { checkSysIdResolution(resolver, ID_SYS, matchedUri); } - private void checkResolutionOnUriResolver(CatalogUriResolver resolver, + private void checkResolutionOnUriResolver(CatalogResolver resolver, String matchedUri) { checkUriResolution(resolver, ID_URI, matchedUri); } @@ -111,4 +110,3 @@ public class SpecifyCatalogTest { return builder().with(FILES, getCatalogPath(catalogName)).build(); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/SystemFamilyTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/SystemFamilyTest.java index aa921b5ef50..0c62b7d72ac 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/SystemFamilyTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/SystemFamilyTest.java @@ -84,4 +84,3 @@ public class SystemFamilyTest { return catalogResolver("systemFamily.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/SystemSuffixTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/SystemSuffixTest.java index 97622704682..6b83fdc306e 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/SystemSuffixTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/SystemSuffixTest.java @@ -95,4 +95,3 @@ public class SystemSuffixTest { return catalogResolver("systemSuffix.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/SystemTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/SystemTest.java index d78029319bd..4be1e621e17 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/SystemTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/SystemTest.java @@ -92,4 +92,3 @@ public class SystemTest { return catalogResolver(CATALOG_SYSTEM); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/UriFamilyTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/UriFamilyTest.java index f6104e8d15d..7e7d1c28e82 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/UriFamilyTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/UriFamilyTest.java @@ -24,11 +24,11 @@ package catalog; import static catalog.CatalogTestUtils.catalogUriResolver; -import static catalog.ResolutionChecker.checkNoMatch; +import static catalog.ResolutionChecker.checkNoUriMatch; import static catalog.ResolutionChecker.checkUriResolution; +import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogException; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; @@ -58,7 +58,7 @@ public class UriFamilyTest { return new Object[][] { // The matched URI of the specified URI reference is defined in // a uri entry. - { "http://remote/dtd/alice/docAlice.dtd", + { "http://remote/dtd/uri/alice/docAlice.dtd", "http://local/base/dtd/docAliceURI.dtd" }, // The matched URI of the specified URI reference is defined in @@ -77,11 +77,10 @@ public class UriFamilyTest { */ @Test(expectedExceptions = CatalogException.class) public void testNoMatch() { - checkNoMatch(createResolver()); + checkNoUriMatch(createResolver()); } - private CatalogUriResolver createResolver() { + private CatalogResolver createResolver() { return catalogUriResolver("uriFamily.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/UriSuffixTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/UriSuffixTest.java index 9cc4a2736e2..c27094fda84 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/UriSuffixTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/UriSuffixTest.java @@ -24,11 +24,11 @@ package catalog; import static catalog.CatalogTestUtils.catalogUriResolver; -import static catalog.ResolutionChecker.checkNoMatch; +import static catalog.ResolutionChecker.checkNoUriMatch; import static catalog.ResolutionChecker.checkUriResolution; +import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogException; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; @@ -88,11 +88,10 @@ public class UriSuffixTest { */ @Test(expectedExceptions = CatalogException.class) public void testNoMatch() { - checkNoMatch(createResolver()); + checkNoUriMatch(createResolver()); } - private CatalogUriResolver createResolver() { + private CatalogResolver createResolver() { return catalogUriResolver("uriSuffix.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/UriTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/UriTest.java index ae17e34c6a1..6b6976d6d9e 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/UriTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/UriTest.java @@ -26,12 +26,12 @@ package catalog; import static catalog.CatalogTestUtils.CATALOG_URI; import static catalog.CatalogTestUtils.RESOLVE_CONTINUE; import static catalog.CatalogTestUtils.catalogUriResolver; -import static catalog.ResolutionChecker.checkNoMatch; +import static catalog.ResolutionChecker.checkNoUriMatch; import static catalog.ResolutionChecker.checkUriResolution; +import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogFeatures; -import javax.xml.catalog.CatalogUriResolver; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; @@ -58,7 +58,7 @@ public class UriTest { return new Object[][] { // The matched URI of the specified URI reference is defined in // a uri entry. The match is an absolute path. - { "http://remote/dtd/alice/docAlice.dtd", + { "http://remote/dtd/uri/alice/docAlice.dtd", "http://local/dtd/docAliceURI.dtd" }, // The matched URI of the specified URI reference is defined in @@ -76,7 +76,7 @@ public class UriTest { } /* - * Specify base location via method CatalogUriResolver.resolve(href, base). + * Specify base location via method CatalogResolver.resolve(href, base). */ @Test public void testSpecifyBaseByAPI() { @@ -84,7 +84,7 @@ public class UriTest { "http://remote/dtd/carl/docCarl.dtd", "http://local/carlBase/dtd/docCarlURI.dtd"); - CatalogUriResolver continueResolver = catalogUriResolver( + CatalogResolver continueResolver = catalogUriResolver( CatalogFeatures.builder().with(CatalogFeatures.Feature.RESOLVE, RESOLVE_CONTINUE).build(), CATALOG_URI); checkUriResolution(continueResolver, "docCarl.dtd", @@ -97,11 +97,10 @@ public class UriTest { */ @Test(expectedExceptions = CatalogException.class) public void testNoMatch() { - checkNoMatch(createResolver()); + checkNoUriMatch(createResolver()); } - private CatalogUriResolver createResolver() { + private CatalogResolver createResolver() { return catalogUriResolver(CATALOG_URI); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/UrnUnwrappingTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/UrnUnwrappingTest.java index 468de7ef528..dbdcb446fa7 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/UrnUnwrappingTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/UrnUnwrappingTest.java @@ -67,4 +67,3 @@ public class UrnUnwrappingTest { return catalogResolver("urnUnwrapping.xml"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/ValidateCatalogTest.java b/jaxp/test/javax/xml/jaxp/functional/catalog/ValidateCatalogTest.java index d0194ca4009..dc7bf7a7e7b 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/ValidateCatalogTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/ValidateCatalogTest.java @@ -98,8 +98,7 @@ public class ValidateCatalogTest { "http://remote/dtd/alice/docAlice.dtd", "http://local/dtd/docAliceSys.dtd"); checkUriResolution(catalogUriResolver(catalogName, CATALOG_URI), - "http://remote/dtd/alice/docAlice.dtd", + "http://remote/dtd/uri/alice/docAlice.dtd", "http://local/dtd/docAliceURI.dtd"); } } - diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/deferFeature.xml b/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/deferFeature.xml index 4bdc2591916..d9c58af34ce 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/deferFeature.xml +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/deferFeature.xml @@ -2,7 +2,7 @@ - + diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/uri.xml b/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/uri.xml index 1ce36ea7f7b..9f37a17bc32 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/uri.xml +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/uri.xml @@ -1,7 +1,7 @@ - + diff --git a/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/uriFamily.xml b/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/uriFamily.xml index 2311cf9aa22..bcdc03c060f 100644 --- a/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/uriFamily.xml +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/uriFamily.xml @@ -4,7 +4,7 @@ - + diff --git a/jaxp/test/javax/xml/jaxp/isolatedjdk/catalog/PropertiesTest.java b/jaxp/test/javax/xml/jaxp/isolatedjdk/catalog/PropertiesTest.java index 91b29b1d97b..ce95aa410ce 100644 --- a/jaxp/test/javax/xml/jaxp/isolatedjdk/catalog/PropertiesTest.java +++ b/jaxp/test/javax/xml/jaxp/isolatedjdk/catalog/PropertiesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,6 @@ import java.util.HashMap; import java.util.Map; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; /* * This case tests if the properties FILES, DEFER, PREFER, RESOLVE in @@ -96,7 +95,7 @@ public class PropertiesTest { } private static void testPropertiesOnUriResolver() { - CatalogUriResolver uriResolver = catalogUriResolver((String[]) null); + CatalogResolver uriResolver = catalogUriResolver((String[]) null); uriResolver.resolve("http://remote/uri/dtd/docDummy.dtd", null); "http://local/base/dtd/docURI.dtd".equals(uriResolver.resolve( "http://remote/dtd/doc.dtd", null).getSystemId()); diff --git a/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java b/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java index a0e83d5b810..01d45ff591b 100644 --- a/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java +++ b/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ import java.util.stream.Stream; import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import jaxp.library.JAXPTestUtilities; @@ -101,18 +100,18 @@ final class CatalogTestUtils { /* * Creates catalogUriResolver with a set of catalogs. */ - static CatalogUriResolver catalogUriResolver(String... catalogName) { + static CatalogResolver catalogUriResolver(String... catalogName) { return catalogUriResolver(CatalogFeatures.defaults(), catalogName); } /* * Creates catalogUriResolver with a feature and a set of catalogs. */ - static CatalogUriResolver catalogUriResolver( + static CatalogResolver catalogUriResolver( CatalogFeatures features, String... catalogName) { return (catalogName == null) ? - CatalogManager.catalogUriResolver(features) : - CatalogManager.catalogUriResolver(features, getCatalogPaths(catalogName)); + CatalogManager.catalogResolver(features) : + CatalogManager.catalogResolver(features, getCatalogPaths(catalogName)); } // Gets the paths of the specified catalogs. diff --git a/jaxp/test/javax/xml/jaxp/libs/catalog/ResolutionChecker.java b/jaxp/test/javax/xml/jaxp/libs/catalog/ResolutionChecker.java index 002ec22ede4..81013a5a7bd 100644 --- a/jaxp/test/javax/xml/jaxp/libs/catalog/ResolutionChecker.java +++ b/jaxp/test/javax/xml/jaxp/libs/catalog/ResolutionChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ package catalog; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import org.testng.Assert; @@ -65,7 +64,7 @@ class ResolutionChecker { * Checks the resolution result for specified URI references * with the specified base location. */ - static void checkUriResolution(CatalogUriResolver resolver, + static void checkUriResolution(CatalogResolver resolver, String href, String base, String matchedUri) { Assert.assertEquals(resolver.resolve(href, base).getSystemId(), matchedUri); @@ -74,7 +73,7 @@ class ResolutionChecker { /* * Checks the resolution result for specified URI references. */ - static void checkUriResolution(CatalogUriResolver resolver, + static void checkUriResolution(CatalogResolver resolver, String href, String matchedUri) { checkUriResolution(resolver, href, null, matchedUri); } @@ -92,9 +91,9 @@ class ResolutionChecker { /* * With strict resolution, if no match is found, - * CatalogUriResolver should throw CatalogException. + * CatalogResolver should throw CatalogException. */ - static void checkNoMatch(CatalogUriResolver resolver) { + static void checkNoUriMatch(CatalogResolver resolver) { resolver.resolve("http://uri/noMatch/docNoMatch.dtd", getNotSpecified(null)); } @@ -139,7 +138,7 @@ class ResolutionChecker { * URI reference with a specified base location. */ static void expectExceptionOnUri( - CatalogUriResolver resolver, String href, String base, + CatalogResolver resolver, String href, String base, Class expectedExceptionClass) { expectThrows(expectedExceptionClass, () -> { resolver.resolve(href, base); @@ -151,7 +150,7 @@ class ResolutionChecker { * URI reference without any specified base location. */ static void expectExceptionOnUri( - CatalogUriResolver resolver, String href, + CatalogResolver resolver, String href, Class expectedExceptionClass) { expectExceptionOnUri(resolver, href, null, expectedExceptionClass); } diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.java b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.java index f8dbda9310a..1078d7cd2c0 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.java +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.java @@ -327,4 +327,3 @@ public class CatalogSupport extends CatalogSupportBase { }; } } - diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.xml b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.xml index 22df286942a..f889ac50a78 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.xml +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.xml @@ -11,32 +11,32 @@ - - - - + + + + - + - - + + - - - + + + - + diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport1.java b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport1.java index cac5e33e99c..251a65fc779 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport1.java +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport1.java @@ -268,4 +268,3 @@ public class CatalogSupport1 extends CatalogSupportBase { } } - diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport2.java b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport2.java index 10159d3567c..8332596e329 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport2.java +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport2.java @@ -270,4 +270,3 @@ public class CatalogSupport2 extends CatalogSupportBase { }; } } - diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport3.java b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport3.java index 6760b1981e1..473ca119c90 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport3.java +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport3.java @@ -280,4 +280,3 @@ public class CatalogSupport3 extends CatalogSupportBase { }; } } - diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport4.java b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport4.java index 12b15e64348..b565cf30853 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport4.java +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport4.java @@ -269,4 +269,3 @@ public class CatalogSupport4 extends CatalogSupportBase { }; } } - diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport5.java b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport5.java new file mode 100644 index 00000000000..884f34ddb88 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport5.java @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package catalog; + +import java.io.File; +import java.io.StringReader; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.URIResolver; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stax.StAXSource; +import javax.xml.transform.stream.StreamSource; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; +import org.w3c.dom.ls.LSResourceResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/* + * @test + * @bug 8158084 8163232 + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport5 + * @run testng/othervm catalog.CatalogSupport5 + * @summary extends CatalogSupport tests, verifies that when errors occur, + * relevant checked Exceptions are returned. + */ +/** + * The CatalogResolver will throw CatalogException when there is no match and + * the resolve property is strict. The Exception should be caught with the existing + * mechanisms so that the checked Exception corresponding to the process can be + * returned. + * + * @author huizhe.wang@oracle.com + */ +@Listeners({jaxp.library.FilePolicy.class, jaxp.library.NetAccessPolicy.class}) +public class CatalogSupport5 extends CatalogSupportBase { + + /* + * Initializing fields + */ + @BeforeClass + public void setUpClass() throws Exception { + setUp(); + } + + + /* + Verifies the Catalog support on SAXParser. + */ + @Test(dataProvider = "data_SAXC", expectedExceptions = SAXException.class) + public void testSAXC(boolean setUseCatalog, boolean useCatalog, String catalog, String + xml, MyHandler handler, String expected) throws Exception { + testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected); + } + + /* + Verifies the Catalog support on XMLReader. + */ + @Test(dataProvider = "data_SAXC", expectedExceptions = SAXException.class) + public void testXMLReaderC(boolean setUseCatalog, boolean useCatalog, String catalog, + String xml, MyHandler handler, String expected) throws Exception { + testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected); + } + + /* + Verifies the Catalog support on XInclude. + */ + @Test(dataProvider = "data_XIC", expectedExceptions = SAXException.class) + public void testXIncludeC(boolean setUseCatalog, boolean useCatalog, String catalog, + String xml, MyHandler handler, String expected) throws Exception { + testXInclude(setUseCatalog, useCatalog, catalog, xml, handler, expected); + } + + /* + Verifies the Catalog support on DOM parser. + */ + @Test(dataProvider = "data_DOMC", expectedExceptions = SAXException.class) + public void testDOMC(boolean setUseCatalog, boolean useCatalog, String catalog, + String xml, MyHandler handler, String expected) throws Exception { + testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected); + } + + /* + Verifies the Catalog support on resolving DTD, xsd import and include in + Schema files. + */ + @Test(dataProvider = "data_SchemaC", expectedExceptions = SAXException.class) + public void testValidationC(boolean setUseCatalog, boolean useCatalog, String catalog, + String xsd, LSResourceResolver resolver) + throws Exception { + testValidation(setUseCatalog, useCatalog, catalog, xsd, resolver) ; + } + + @Test(dataProvider = "data_ValidatorC", expectedExceptions = SAXException.class) + public void testValidatorC(boolean setUseCatalog1, boolean setUseCatalog2, boolean useCatalog, + Source source, LSResourceResolver resolver1, LSResourceResolver resolver2, + String catalog1, String catalog2) + throws Exception { + testValidator(setUseCatalog1, setUseCatalog2, useCatalog, source, + resolver1, resolver2, catalog1, catalog2); + } + + /* + Verifies the Catalog support on resolving DTD, xsl import and include in + XSL files. + */ + @Test(dataProvider = "data_XSLC", expectedExceptions = TransformerException.class) + public void testXSLImportC(boolean setUseCatalog, boolean useCatalog, String catalog, + SAXSource xsl, StreamSource xml, URIResolver resolver, String expected) throws Exception { + + testXSLImport(setUseCatalog, useCatalog, catalog, xsl, xml, resolver, expected); + } + + /* + @bug 8158084 8162442 + Verifies the Catalog support on resolving DTD, xsl import and include in + XSL files. + */ + @Test(dataProvider = "data_XSLC", expectedExceptions = TransformerException.class) + public void testXSLImportWTemplatesC(boolean setUseCatalog, boolean useCatalog, String catalog, + SAXSource xsl, StreamSource xml, URIResolver resolver, String expected) throws Exception { + testXSLImportWTemplates(setUseCatalog, useCatalog, catalog, xsl, xml, resolver, expected); + } + + /* + DataProvider: for testing the SAX parser + Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string + */ + @DataProvider(name = "data_SAXC") + public Object[][] getDataSAXC() { + return new Object[][]{ + {false, true, xml_bogus_catalog, xml_system, new MyHandler(elementInSystem), expectedWCatalog} + + }; + } + + /* + DataProvider: for testing XInclude + Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string + */ + @DataProvider(name = "data_XIC") + public Object[][] getDataXIC() { + return new Object[][]{ + {false, true, xml_bogus_catalog, xml_xInclude, new MyHandler(elementInXISimple), contentInUIutf8Catalog}, + }; + } + + /* + DataProvider: for testing DOM parser + Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string + */ + @DataProvider(name = "data_DOMC") + public Object[][] getDataDOMC() { + return new Object[][]{ + {false, true, xml_bogus_catalog, xml_system, new MyHandler(elementInSystem), expectedWCatalog} + }; + } + + /* + DataProvider: for testing Schema validation + Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver + */ + @DataProvider(name = "data_SchemaC") + public Object[][] getDataSchemaC() { + + return new Object[][]{ + // for resolving DTD in xsd + {false, true, xml_bogus_catalog, xsd_xmlSchema, null}, + // for resolving xsd import + {false, true, xml_bogus_catalog, xsd_xmlSchema_import, null}, + // for resolving xsd include + {false, true, xml_bogus_catalog, xsd_include_company, null} + }; + } + + /* + DataProvider: for testing Schema Validator + Data: setUseCatalog1, setUseCatalog2, useCatalog, source, resolver1, resolver2, + catalog1, catalog2 + */ + @DataProvider(name = "data_ValidatorC") + public Object[][] getDataValidator() { + DOMSource ds = getDOMSource(xml_val_test, xml_val_test_id, true, true, xml_catalog); + + SAXSource ss = new SAXSource(new InputSource(xml_val_test)); + ss.setSystemId(xml_val_test_id); + + StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id); + StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id); + + StreamSource source = new StreamSource(new File(xml_val_test)); + + return new Object[][]{ + // use catalog + {false, false, true, ds, null, null, xml_bogus_catalog, null}, + {false, false, true, ds, null, null, null, xml_bogus_catalog}, + {false, false, true, ss, null, null, xml_bogus_catalog, null}, + {false, false, true, ss, null, null, null, xml_bogus_catalog}, + {false, false, true, stax, null, null, xml_bogus_catalog, null}, + {false, false, true, stax1, null, null, null, xml_bogus_catalog}, + {false, false, true, source, null, null, xml_bogus_catalog, null}, + {false, false, true, source, null, null, null, xml_bogus_catalog}, + }; + } + + /* + DataProvider: for testing XSL import and include + Data: set use_catalog, use_catalog, catalog file, xsl file, xml file, a URIResolver, expected + */ + @DataProvider(name = "data_XSLC") + public Object[][] getDataXSLC() { + SAXSource xslSourceDTD = new SAXSource(new InputSource(new StringReader(xsl_includeDTD))); + StreamSource xmlSourceDTD = new StreamSource(new StringReader(xml_xslDTD)); + + SAXSource xslDocSource = new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString())); + StreamSource xmlDocSource = new StreamSource(new File(xml_doc)); + return new Object[][]{ + // for resolving DTD, import and include in xsl + {false, true, xml_bogus_catalog, xslSourceDTD, xmlSourceDTD, null, ""}, + // for resolving reference by the document function + {false, true, xml_bogus_catalog, xslDocSource, xmlDocSource, null, "Resolved by a catalog"}, + }; + } +} diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java index 83a1520c45d..87735104855 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java @@ -35,9 +35,9 @@ import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; - import javax.xml.XMLConstants; import javax.xml.catalog.CatalogFeatures; +import javax.xml.catalog.CatalogResolver; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -61,7 +61,6 @@ import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; - import org.testng.Assert; import org.w3c.dom.Document; import org.w3c.dom.Node; @@ -677,6 +676,29 @@ public class CatalogSupportBase { } + + /** + * Extends MyHandler and overrides resolveEntity with a CatalogResolver + */ + class MyCatalogHandler extends MyHandler { + CatalogResolver cr; + + public MyCatalogHandler(CatalogResolver cr, String elementName) { + super(elementName); + this.cr = cr; + } + + @Override + public InputSource resolveEntity(String publicId, String systemId) { + return cr.resolveEntity(publicId, systemId); + } + @Override + public InputSource resolveEntity(String name, String publicId, + String baseURI, String systemId) { + return cr.resolveEntity(publicId, systemId); + } + } + /** * Extends MyHandler and overrides resolveEntity */ @@ -935,4 +957,3 @@ public class CatalogSupportBase { } } } - diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport_uri.xml b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport_uri.xml new file mode 100644 index 00000000000..8a4b0dbf290 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport_uri.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java index 4c00ef686c8..6f622f9ab25 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java @@ -26,23 +26,37 @@ import static jaxp.library.JAXPTestUtilities.clearSystemProperty; import static jaxp.library.JAXPTestUtilities.getSystemProperty; import static jaxp.library.JAXPTestUtilities.setSystemProperty; +import java.io.File; +import java.io.FileInputStream; import java.io.FilePermission; import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.io.StringWriter; import java.nio.file.Paths; import java.util.PropertyPermission; - +import javax.xml.XMLConstants; import javax.xml.catalog.Catalog; import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures.Feature; import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogResolver; -import javax.xml.catalog.CatalogUriResolver; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; import javax.xml.transform.Source; - +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; import jaxp.library.JAXPTestUtilities; import org.testng.Assert; @@ -59,29 +73,235 @@ import org.xml.sax.ext.DefaultHandler2; /* * @test - * @bug 8081248 8144966 8146606 8146237 8151154 8150969 8151162 8152527 8154220 + * @bug 8081248 8144966 8146606 8146237 8151154 8150969 8151162 8152527 8154220 8163232 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @run testng/othervm -DrunSecMngr=true catalog.CatalogTest * @run testng/othervm catalog.CatalogTest * @summary Tests basic Catalog functions. */ @Listeners({jaxp.library.FilePolicy.class}) -public class CatalogTest { +public class CatalogTest extends CatalogSupportBase { static final String KEY_FILES = "javax.xml.catalog.files"; - public String filepath; /* * Initializing fields */ @BeforeClass public void setUpClass() throws Exception { - String file1 = getClass().getResource("first_cat.xml").getFile(); - if (getSystemProperty("os.name").contains("Windows")) { - filepath = file1.substring(1, file1.lastIndexOf("/") + 1); - } else { - filepath = file1.substring(0, file1.lastIndexOf("/") + 1); + super.setUp(); + } + + + /* + * @bug 8163232 + * Verifies that the CatalogResolver supports the following XML Resolvers: + javax.xml.stream.XMLResolver + javax.xml.transform.URIResolver + org.w3c.dom.ls.LSResourceResolver + org.xml.sax.EntityResolver + * + * Plus, system and uri entries can equally be used. + */ + + /* + * Verifies the support for org.xml.sax.EntityResolver. + * Expected: the parser returns the expected string. + */ + @Test(dataProvider = "supportXMLResolver") + public void supportEntityResolver(String catalogFile, String xml, String expected) throws Exception { + String xmlSource = getClass().getResource(xml).getFile(); + + CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); + MyCatalogHandler handler = new MyCatalogHandler(cr, elementInSystem); + SAXParser parser = getSAXParser(false, true, null); + parser.parse(xmlSource, handler); + + Assert.assertEquals(handler.getResult().trim(), expected); + } + + /* + * Verifies the support for javax.xml.stream.XMLResolver. + * Expected: the parser returns the expected string. + */ + @Test(dataProvider = "supportXMLResolver") + public void supportXMLResolver(String catalogFile, String xml, String expected) throws Exception { + String xmlSource = getClass().getResource(xml).getFile(); + + CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); + + XMLInputFactory xifactory = XMLInputFactory.newInstance(); + xifactory.setProperty(XMLInputFactory.IS_COALESCING, true); + xifactory.setProperty(XMLInputFactory.RESOLVER, cr); + File file = new File(xmlSource); + String systemId = file.toURI().toString(); + InputStream entityxml = new FileInputStream(file); + XMLStreamReader streamReader = xifactory.createXMLStreamReader(systemId, entityxml); + String result = null; + while (streamReader.hasNext()) { + int eventType = streamReader.next(); + if (eventType == XMLStreamConstants.START_ELEMENT) { + eventType = streamReader.next(); + if (eventType == XMLStreamConstants.CHARACTERS) { + result = streamReader.getText(); + } + } } + System.out.println(": expected [" + expected + "] <> actual [" + result.trim() + "]"); + + Assert.assertEquals(result.trim(), expected); + } + + /* + * Verifies the support for org.w3c.dom.ls.LSResourceResolver by ShemaFactory. + * Success: parsing goes through with no error + * Fail: throws Exception if references are not resolved (by the CatalogResolver) + */ + @Test(dataProvider = "supportLSResourceResolver") + public void supportLSResourceResolver(String catalogFile, Source schemaSource) throws SAXException { + + CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); + + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + factory.setResourceResolver(cr); + Schema schema = factory.newSchema(schemaSource); + + } + + /* + * Verifies the support for org.w3c.dom.ls.LSResourceResolver by Validator. + * Success: parsing goes through with no error + * Fail: throws Exception if references are not resolved (by the CatalogResolver) + */ + @Test(dataProvider = "supportLSResourceResolver1") + public void supportLSResourceResolver1(String catalogFile, Source source) throws Exception { + + CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); + + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Validator validator = factory.newSchema().newValidator(); + validator.setResourceResolver(cr); + validator.validate(source); + } + + /* + * Verifies the support for javax.xml.transform.URIResolver. + * Success: parsing goes through with no error + * Fail: throws Exception if references are not resolved (by the CatalogResolver) + */ + @Test(dataProvider = "supportURIResolver") + public void supportURIResolver(String catalogFile, Source xsl, Source xml, String expected) throws Exception { + + CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); + + TransformerFactory factory = TransformerFactory.newInstance(); + factory.setURIResolver(cr); + Transformer transformer = factory.newTransformer(xsl); + StringWriter out = new StringWriter(); + transformer.transform(xml, new StreamResult(out)); + if (expected != null) { + Assert.assertTrue(out.toString().contains(expected), "supportURIResolver"); + } + } + + /* + DataProvider: used to verify the support of XML Resolvers. + Data columns: + catalog filepath, xml source file, expected result + */ + @DataProvider(name = "supportXMLResolver") + public Object[][] supportXMLResolver() { + String catalogFile = getClass().getResource("catalog.xml").getFile(); + String catalogFileUri = getClass().getResource("catalog_uri.xml").getFile(); + + return new Object[][]{ + {catalogFile, "system.xml", "Test system entry"}, + {catalogFile, "rewritesystem.xml", "Test rewritesystem entry"}, + {catalogFile, "rewritesystem1.xml", "Test rewritesystem entry"}, + {catalogFile, "systemsuffix.xml", "Test systemsuffix entry"}, + {catalogFile, "delegatesystem.xml", "Test delegatesystem entry"}, + {catalogFile, "public.xml", "Test public entry"}, + {catalogFile, "delegatepublic.xml", "Test delegatepublic entry"}, + // using uri entries + {catalogFileUri, "system.xml", "Test system entry"}, + {catalogFileUri, "rewritesystem.xml", "Test rewritesystem entry"}, + {catalogFileUri, "rewritesystem1.xml", "Test rewritesystem entry"}, + {catalogFileUri, "systemsuffix.xml", "Test systemsuffix entry"}, + {catalogFileUri, "delegateuri.xml", "Test delegateuri entry"}, + {catalogFileUri, "public.xml", "Test public entry"}, + }; + } + + /* + DataProvider: used to verify the support of LSResourceResolver by SchemaFactory. + Data columns: + catalog filepath, schema source file + */ + @DataProvider(name = "supportLSResourceResolver") + public Object[][] supportLSResourceResolver() { + String catalogFile = getClass().getResource("CatalogSupport.xml").getFile(); + String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile(); + + /* + * XMLSchema.xsd has a reference to XMLSchema.dtd which in turn refers to + * datatypes.dtd + */ + return new Object[][]{ + {catalogFile, new StreamSource(new StringReader(xsd_xmlSchema))}, + {catalogFile, new StreamSource(new StringReader(xsd_xmlSchema_import))}, + {catalogFile, new StreamSource(new StringReader(xsd_include_company))}, + {catalogFileUri, new StreamSource(new StringReader(xsd_xmlSchema))}, + {catalogFileUri, new StreamSource(new StringReader(xsd_xmlSchema_import))}, + {catalogFileUri, new StreamSource(new StringReader(xsd_include_company))}, + }; + } + + /* + DataProvider: used to verify the support of LSResourceResolver by Validator. + Data columns: + catalog filepath, source file + */ + @DataProvider(name = "supportLSResourceResolver1") + public Object[][] supportLSResourceResolver1() { + String catalogFile = getClass().getResource("CatalogSupport.xml").getFile(); + String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile(); + + /* + * val_test.xml has a reference to system.dtd and val_test.xsd + */ + SAXSource ss = new SAXSource(new InputSource(xml_val_test)); + ss.setSystemId(xml_val_test_id); + + return new Object[][]{ + {catalogFile, ss}, + {catalogFileUri, ss}, + }; + } + + + /* + DataProvider: used to verify the support of LSResourceResolver by Validator. + Data columns: + catalog filepath, xsl source, xml source file + */ + @DataProvider(name = "supportURIResolver") + public Object[][] supportURIResolver() { + String catalogFile = getClass().getResource("CatalogSupport.xml").getFile(); + String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile(); + SAXSource xslSource = new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString())); + + /* + * val_test.xml has a reference to system.dtd and val_test.xsd + */ + SAXSource ss = new SAXSource(new InputSource(xml_val_test)); + ss.setSystemId(xml_val_test_id); + + return new Object[][]{ + {catalogFile, new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString())), + new StreamSource(new File(xml_doc)), "Resolved by a catalog"}, + {catalogFileUri, new SAXSource(new InputSource(new StringReader(xsl_include))), + new StreamSource(new StringReader(xml_xsl)), null}, + }; } /* @@ -110,7 +330,7 @@ public class CatalogTest { @Test(dataProvider = "resolveUri") public void testMatch1(String cFile, String href, String expectedFile, String expectedUri, String msg) { String catalogFile = getClass().getResource(cFile).getFile(); - CatalogUriResolver cur = CatalogManager.catalogUriResolver(CatalogFeatures.defaults(), catalogFile); + CatalogResolver cur = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile); Source source = cur.resolve(href, null); Assert.assertNotNull(source, "Source returned is null"); Assert.assertEquals(expectedUri, source.getSystemId(), msg); @@ -275,7 +495,7 @@ public class CatalogTest { try { - CatalogUriResolver resolver = CatalogManager.catalogUriResolver(CatalogFeatures.defaults(), catalog); + CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog); String actualSystemId = resolver.resolve("http://remote.com/import/import.xsl", null).getSystemId(); Assert.assertTrue(!actualSystemId.contains("//"), "result contains duplicate slashes"); } catch (Exception e) { @@ -383,7 +603,7 @@ public class CatalogTest { /* - DataProvider: used to verify CatalogUriResolver's resolve function. + DataProvider: used to verify CatalogResolver's resolve function. Data columns: catalog, uri or publicId, expectedFile, expectedUri, msg @@ -571,4 +791,3 @@ public class CatalogTest { } } } - diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/catalog.xml b/jaxp/test/javax/xml/jaxp/unittest/catalog/catalog.xml index f7340d77859..0c25770bf3b 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/catalog.xml +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/catalog.xml @@ -26,4 +26,4 @@ - \ No newline at end of file + diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/catalog_uri.xml b/jaxp/test/javax/xml/jaxp/unittest/catalog/catalog_uri.xml new file mode 100644 index 00000000000..26adf0f3f01 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/catalog_uri.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/delegateuri.xml b/jaxp/test/javax/xml/jaxp/unittest/catalog/delegateuri.xml new file mode 100644 index 00000000000..88b802cfe44 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/delegateuri.xml @@ -0,0 +1,5 @@ + + + +Test &delegateuri; entry diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegatecatalog.xml b/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegatecatalog.xml index 1344c78101a..b398f5ba30d 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegatecatalog.xml +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegatecatalog.xml @@ -22,4 +22,4 @@ - \ No newline at end of file + diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegatecatalog_uri.xml b/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegatecatalog_uri.xml new file mode 100644 index 00000000000..a9f6b86be0c --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegatecatalog_uri.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegateuri.dtd b/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegateuri.dtd new file mode 100644 index 00000000000..a8e56d26fb3 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/files/delegateuri.dtd @@ -0,0 +1,2 @@ + + diff --git a/jaxp/test/javax/xml/jaxp/unittest/catalog/system.xml b/jaxp/test/javax/xml/jaxp/unittest/catalog/system.xml index a96c4d896f7..0ceb2c633d0 100644 --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/system.xml +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/system.xml @@ -1,5 +1,5 @@ - -Test &system; entry \ No newline at end of file +Test &system; entry diff --git a/jaxp/test/javax/xml/jaxp/unittest/parsers/HandleError.java b/jaxp/test/javax/xml/jaxp/unittest/parsers/HandleError.java new file mode 100644 index 00000000000..0a3e35c5dd3 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/parsers/HandleError.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package parsers; + +import java.io.StringReader; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +/* + * @test + * @bug 8157797 + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @run testng/othervm -DrunSecMngr=true parsers.HandleError + * @run testng/othervm parsers.HandleError + * @summary Tests that the parser handles errors properly. + */ +@Listeners({jaxp.library.BasePolicy.class}) +public class HandleError { + + /* + * Verifies that the parser returns with no unexpected "java.lang.InternalError" + * when continue-after-fatal-error is requested. + */ + @Test + public void test() throws Exception { + String invalidXml = ""; + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true); + SAXParser parser = saxParserFactory.newSAXParser(); + parser.parse(new InputSource(new StringReader(invalidXml)), new DefaultHandler() { + @Override + public void fatalError(SAXParseException e) throws SAXException { + System.err.printf("%s%n", e.getMessage()); + } + }); + } + + + /* + * Verifies that the parser throws SAXParseException when parsing error is + * encountered when: + * continue-after-fatal-error is not set, the default it false + * continue-after-fatal-error is explicitly set to false + */ + @Test(dataProvider = "setFeature", expectedExceptions = SAXParseException.class) + public void test1(boolean setFeature, boolean value) throws Exception { + String invalidXml = ""; + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + if (setFeature) { + saxParserFactory.setFeature("http://apache.org/xml/features/continue-after-fatal-error", value); + } + SAXParser parser = saxParserFactory.newSAXParser(); + parser.parse(new InputSource(new StringReader(invalidXml)), new DefaultHandler()); + } + + /* + DataProvider: used to set feature "continue-after-fatal-error" + Data columns: + flag to indicate the feature is to be set, the value of the feature + */ + @DataProvider(name = "setFeature") + public Object[][] getFeatureSetting() { + + return new Object[][]{ + {false, false}, + {true, false}, + }; + } +} diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 36eb74d3bb0..136f72fe00d 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -378,3 +378,4 @@ fe4e11bd2423635dc0f5f5cb9a64eb2f2cce7f4c jdk-9+128 39c6293131d91aec7f2f5120395e070a937b8858 jdk-9+130 783e7e2c587f2c7e1b9998a46d90ec196ab2a195 jdk-9+131 9fff2477a4cadf2a9618a76f1f4fe0f20bb5ff3b jdk-9+132 +05e99eefda2b58d1ed176e411302d9d6b35dca16 jdk-9+133 diff --git a/jdk/.hgtags b/jdk/.hgtags index d0c1a581878..4639f93e55b 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -375,3 +375,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123 6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130 8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131 d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132 +3cdae27c90b5e41afe75eab904fda19fac076330 jdk-9+133 diff --git a/jdk/make/gendata/Gendata-java.base.gmk b/jdk/make/gendata/Gendata-java.base.gmk index 8547f205011..88acb5b983b 100644 --- a/jdk/make/gendata/Gendata-java.base.gmk +++ b/jdk/make/gendata/Gendata-java.base.gmk @@ -34,7 +34,7 @@ include GendataTZDB.gmk include GendataBlacklistedCerts.gmk -include GendataPolicyJars.gmk +include GendataCryptoPolicy.gmk ################################################################################ @@ -64,13 +64,19 @@ TARGETS += $(GENDATA_CURDATA) GENDATA_JAVA_SECURITY_SRC := $(JDK_TOPDIR)/src/java.base/share/conf/security/java.security GENDATA_JAVA_SECURITY := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/java.security +ifeq ($(UNLIMITED_CRYPTO), true) + CRYPTO.POLICY := unlimited +else + CRYPTO.POLICY := limited +endif + # RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile $(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC) $(call LogInfo, Generating java.security) $(call MakeDir, $(@D)) $(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \ - $(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC) + $(OPENJDK_TARGET_CPU_ARCH) $(CRYPTO.POLICY) $(RESTRICTED_PKGS_SRC) TARGETS += $(GENDATA_JAVA_SECURITY) diff --git a/jdk/make/gendata/GendataCryptoPolicy.gmk b/jdk/make/gendata/GendataCryptoPolicy.gmk new file mode 100644 index 00000000000..dff51230b44 --- /dev/null +++ b/jdk/make/gendata/GendataCryptoPolicy.gmk @@ -0,0 +1,72 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# In pre-JDK9 releases, Oracle JDK has had a separately downloadable set +# of policy files which has been a nightmare for deployment. +# +# We now create 2 complete initial sets of policy files and package into +# 2 different directories. The crypto.policy Security property will select +# the active policy. +# +# It will be up to the user/deployer to make an informed choice +# as to whether they are legally entitled to use the unlimited policy +# file in their environment. The $(UNLIMITED_CRYPTO) make variable +# determines the default directory/policy. +# + +default: all + +include $(SPEC) +include MakeBase.gmk + + +################################################################################ +POLICY_DIR := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/policy +LIMITED_POLICY_DIR := $(POLICY_DIR)/limited +UNLIMITED_POLICY_DIR := $(POLICY_DIR)/unlimited + +POLICY_SRC_DIR := $(JDK_TOPDIR)/src/java.base/share/conf/security/policy +LIMITED_POLICY_SRC_DIR := $(POLICY_SRC_DIR)/limited +UNLIMITED_POLICY_SRC_DIR := $(POLICY_SRC_DIR)/unlimited + +$(POLICY_DIR)/README.txt: $(POLICY_SRC_DIR)/README.txt + $(install-file) + +$(LIMITED_POLICY_DIR)/%: $(LIMITED_POLICY_SRC_DIR)/% + $(install-file) + +$(UNLIMITED_POLICY_DIR)/%: $(UNLIMITED_POLICY_SRC_DIR)/% + $(install-file) + +TARGETS += \ + $(POLICY_DIR)/README.txt \ + $(LIMITED_POLICY_DIR)/default_US_export.policy \ + $(LIMITED_POLICY_DIR)/default_local.policy \ + $(LIMITED_POLICY_DIR)/exempt_local.policy \ + $(UNLIMITED_POLICY_DIR)/default_US_export.policy \ + $(UNLIMITED_POLICY_DIR)/default_local.policy \ + +################################################################################ diff --git a/jdk/make/gendata/GendataPolicyJars.gmk b/jdk/make/gendata/GendataPolicyJars.gmk deleted file mode 100644 index 57f80abe9f2..00000000000 --- a/jdk/make/gendata/GendataPolicyJars.gmk +++ /dev/null @@ -1,150 +0,0 @@ -# -# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -default: all - -include $(SPEC) -include MakeBase.gmk -include JarArchive.gmk - - -################################################################################ - -US_EXPORT_POLICY_JAR_DST := \ - $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/US_export_policy.jar - -US_EXPORT_POLICY_JAR_LIMITED := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/limited/US_export_policy.jar -US_EXPORT_POLICY_JAR_UNLIMITED := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy.jar - -# -# TODO fix so that SetupJarArchive does not write files into SRCS -# then we don't need this extra copying -# -# NOTE: We currently do not place restrictions on our limited export -# policy. This was not a typo. This means we are shipping the same file -# for both limited and unlimited US_export_policy.jar. Only the local -# policy file currently has restrictions. -# -US_EXPORT_POLICY_JAR_SRC_DIR := \ - $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited -US_EXPORT_POLICY_JAR_TMP := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy_jar.tmp - -$(US_EXPORT_POLICY_JAR_TMP)/%: $(US_EXPORT_POLICY_JAR_SRC_DIR)/% - $(install-file) - -US_EXPORT_POLICY_JAR_DEPS := \ - $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy - -$(eval $(call SetupJarArchive, BUILD_US_EXPORT_POLICY_JAR, \ - DEPENDENCIES := $(US_EXPORT_POLICY_JAR_DEPS), \ - SRCS := $(US_EXPORT_POLICY_JAR_TMP), \ - SUFFIXES := .policy, \ - JAR := $(US_EXPORT_POLICY_JAR_UNLIMITED), \ - EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \ - SKIP_METAINF := true, \ -)) - -$(US_EXPORT_POLICY_JAR_LIMITED): \ - $(US_EXPORT_POLICY_JAR_UNLIMITED) - $(call LogInfo, Copying unlimited $(patsubst $(OUTPUT_ROOT)/%,%,$@)) - $(install-file) - -TARGETS += $(US_EXPORT_POLICY_JAR_LIMITED) $(US_EXPORT_POLICY_JAR_UNLIMITED) - -ifeq ($(UNLIMITED_CRYPTO), true) - $(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_UNLIMITED) - $(install-file) -else - $(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_LIMITED) - $(install-file) -endif - -POLICY_JARS += $(US_EXPORT_POLICY_JAR_DST) - -################################################################################ - -LOCAL_POLICY_JAR_DST := \ - $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/local_policy.jar - -LOCAL_POLICY_JAR_LIMITED := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy.jar -LOCAL_POLICY_JAR_UNLIMITED := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy.jar - -# -# TODO fix so that SetupJarArchive does not write files into SRCS -# then we don't need this extra copying -# -LOCAL_POLICY_JAR_LIMITED_TMP := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy_jar.tmp -LOCAL_POLICY_JAR_UNLIMITED_TMP := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy_jar.tmp - -$(LOCAL_POLICY_JAR_LIMITED_TMP)/%: \ - $(JDK_TOPDIR)/make/data/cryptopolicy/limited/% - $(install-file) - -$(LOCAL_POLICY_JAR_UNLIMITED_TMP)/%: \ - $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited/% - $(install-file) - -$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_LIMITED, \ - DEPENDENCIES := $(LOCAL_POLICY_JAR_LIMITED_TMP)/exempt_local.policy \ - $(LOCAL_POLICY_JAR_LIMITED_TMP)/default_local.policy, \ - SRCS := $(LOCAL_POLICY_JAR_LIMITED_TMP), \ - SUFFIXES := .policy, \ - JAR := $(LOCAL_POLICY_JAR_LIMITED), \ - EXTRA_MANIFEST_ATTR := Crypto-Strength: limited, \ - SKIP_METAINF := true, \ -)) - -$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_UNLIMITED, \ - DEPENDENCIES := $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/default_local.policy, \ - SRCS := $(LOCAL_POLICY_JAR_UNLIMITED_TMP), \ - SUFFIXES := .policy, \ - JAR := $(LOCAL_POLICY_JAR_UNLIMITED), \ - EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \ - SKIP_METAINF := true, \ -)) - -TARGETS += $(LOCAL_POLICY_JAR_LIMITED) $(LOCAL_POLICY_JAR_UNLIMITED) - -ifeq ($(UNLIMITED_CRYPTO), true) - $(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_UNLIMITED) - $(install-file) -else - $(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_LIMITED) - $(install-file) -endif - -POLICY_JARS += $(LOCAL_POLICY_JAR_DST) -TARGETS += $(POLICY_JARS) - -################################################################################ - -$(eval $(call IncludeCustomExtension, jdk, gendata/GendataPolicyJars.gmk)) diff --git a/jdk/make/launcher/Launcher-jdk.jdeps.gmk b/jdk/make/launcher/Launcher-jdk.jdeps.gmk index 6cbcaf47163..4a69deede07 100644 --- a/jdk/make/launcher/Launcher-jdk.jdeps.gmk +++ b/jdk/make/launcher/Launcher-jdk.jdeps.gmk @@ -36,3 +36,9 @@ $(eval $(call SetupBuildLauncher, jdeps, \ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ )) + +$(eval $(call SetupBuildLauncher, jdeprscan, \ + MAIN_CLASS := com.sun.tools.jdeprscan.Main, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ + -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ +)) diff --git a/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk b/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk index c74f77960bb..82618b11fb5 100644 --- a/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk +++ b/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \ CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \ $(LIBJAVA_HEADER_FLAGS) \ -I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.pkcs11, \ - DISABLED_WARNINGS_solstudio := E_DECLARATION_IN_CODE, \ - DISABLED_WARNINGS_microsoft := 4013 4267, \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ diff --git a/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java b/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java index 0e3ca50bc26..963db0b593e 100644 --- a/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java +++ b/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,8 @@ import java.util.*; * * 1. Adds additional packages to the package.access and * package.definition security properties. - * 2. Filter out platform-unrelated parts + * 2. Filter out platform-unrelated parts. + * 3. Set the JCE jurisdiction policy directory. * * In order to easily maintain platform-related entries, every item * (including the last line) in package.access and package.definition @@ -50,12 +51,13 @@ public class MakeJavaSecurity { public static void main(String[] args) throws Exception { - if (args.length < 4) { + if (args.length < 5) { System.err.println("Usage: java MakeJavaSecurity " + "[input java.security file name] " + "[output java.security file name] " + "[openjdk target os] " + "[openjdk target cpu architecture]" + + "[JCE jurisdiction policy directory]" + "[more restricted packages file name?]"); System.exit(1); @@ -63,8 +65,8 @@ public class MakeJavaSecurity { // more restricted packages List extraLines; - if (args.length == 5) { - extraLines = Files.readAllLines(Paths.get(args[4])); + if (args.length == 6) { + extraLines = Files.readAllLines(Paths.get(args[5])); } else { extraLines = Collections.emptyList(); } @@ -135,6 +137,16 @@ public class MakeJavaSecurity { } } + // Set the JCE policy value + for (int i = 0; i < lines.size(); i++) { + String line = lines.get(i); + int index = line.indexOf("crypto.policydir-tbd"); + if (index >= 0) { + String prefix = line.substring(0, index); + lines.set(i, prefix + args[4]); + } + } + // Clean up the last line of PKG_ACC and PKG_DEF blocks. // Not really necessary since a blank line follows. boolean inBlock = false; diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java index 592ec411407..106ee91392c 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java @@ -986,8 +986,9 @@ final class CipherCore { if (padding != null) { int padStart = padding.unpad(outWithPadding, 0, outLen); if (padStart < 0) { - throw new BadPaddingException("Given final block not " - + "properly padded"); + throw new BadPaddingException("Given final block not " + + "properly padded. Such issues can arise if a bad key " + + "is used during decryption."); } outLen = padStart; } diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java index 25d4a3b5b9f..8c9957274d6 100644 --- a/jdk/src/java.base/share/classes/java/lang/Class.java +++ b/jdk/src/java.base/share/classes/java/lang/Class.java @@ -331,12 +331,6 @@ public final class Class implements java.io.Serializable, * Note that this method does not check whether the requested class * is accessible to its caller. * - *

If the {@code loader} is {@code null}, and a security - * manager is present, and the caller's class loader is not null, then this - * method calls the security manager's {@code checkPermission} method - * with a {@code RuntimePermission("getClassLoader")} permission to - * ensure it's ok to access the bootstrap class loader. - * * @param name fully qualified name of the desired class * @param initialize if {@code true} the class will be initialized. * See Section 12.4 of The Java Language Specification. @@ -348,6 +342,11 @@ public final class Class implements java.io.Serializable, * by this method fails * @exception ClassNotFoundException if the class cannot be located by * the specified class loader + * @exception SecurityException + * if a security manager is present, and the {@code loader} is + * {@code null}, and the caller's class loader is not + * {@code null}, and the caller does not have the + * {@link RuntimePermission}{@code ("getClassLoader")} * * @see java.lang.Class#forName(String) * @see java.lang.ClassLoader @@ -782,22 +781,17 @@ public final class Class implements java.io.Serializable, * null in such implementations if this class was loaded by the bootstrap * class loader. * - *

If a security manager is present, and the caller's class loader is - * not null and the caller's class loader is not the same as or an ancestor of - * the class loader for the class whose class loader is requested, then - * this method calls the security manager's {@code checkPermission} - * method with a {@code RuntimePermission("getClassLoader")} - * permission to ensure it's ok to access the class loader for the class. - * *

If this object * represents a primitive type or void, null is returned. * * @return the class loader that loaded the class or interface * represented by this object. - * @throws SecurityException - * if a security manager exists and its - * {@code checkPermission} method denies - * access to the class loader for the class. + * @throws SecurityException + * if a security manager is present, and the caller's class loader + * is not {@code null} and is not the same as or an ancestor of the + * class loader for the class whose class loader is requested, + * and the caller does not have the + * {@link RuntimePermission}{@code ("getClassLoader")} * @see java.lang.ClassLoader * @see SecurityManager#checkPermission * @see java.lang.RuntimePermission diff --git a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java index 013912384d8..d8b2dee337d 100644 --- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java @@ -1537,22 +1537,13 @@ public abstract class ClassLoader { * will return null in such implementations if this class loader's * parent is the bootstrap class loader. * - *

If a security manager is present, and the invoker's class loader is - * not null and is not an ancestor of this class loader, then this - * method invokes the security manager's {@link - * SecurityManager#checkPermission(java.security.Permission) - * checkPermission} method with a {@link - * RuntimePermission#RuntimePermission(String) - * RuntimePermission("getClassLoader")} permission to verify - * access to the parent class loader is permitted. If not, a - * SecurityException will be thrown.

- * * @return The parent ClassLoader * * @throws SecurityException - * If a security manager exists and its checkPermission - * method doesn't allow access to this class loader's parent class - * loader. + * If a security manager is present, and the caller's class loader + * is not {@code null} and is not an ancestor of this class loader, + * and the caller does not have the + * {@link RuntimePermission}{@code ("getClassLoader")} * * @since 1.2 */ @@ -1590,12 +1581,11 @@ public abstract class ClassLoader { * @return The platform {@code ClassLoader}. * * @throws SecurityException - * If a security manager exists and the caller's class loader is - * not {@code null} and the caller's class loader is not the same + * If a security manager is present, and the caller's class loader is + * not {@code null}, and the caller's class loader is not the same * as or an ancestor of the platform class loader, - * and the {@link SecurityManager#checkPermission(java.security.Permission) - * checkPermission} method denies {@code RuntimePermission("getClassLoader")} - * to access the platform class loader. + * and the caller does not have the + * {@link RuntimePermission}{@code ("getClassLoader")} * * @since 9 */ @@ -1636,17 +1626,6 @@ public abstract class ClassLoader { * If circular initialization of the system class loader is detected then * an unspecified error or exception is thrown. * - *

If a security manager is present, and the invoker's class loader is - * not null and the invoker's class loader is not the same as or - * an ancestor of the system class loader, then this method invokes the - * security manager's {@link - * SecurityManager#checkPermission(java.security.Permission) - * checkPermission} method with a {@link - * RuntimePermission#RuntimePermission(String) - * RuntimePermission("getClassLoader")} permission to verify - * access to the system class loader. If not, a - * SecurityException will be thrown.

- * * @implNote The system property to override the system class loader is not * examined until the VM is almost fully initialized. Code that executes * this method during startup should take care not to cache the return @@ -1656,8 +1635,10 @@ public abstract class ClassLoader { * null if none * * @throws SecurityException - * If a security manager exists and its checkPermission - * method doesn't allow access to the system class loader. + * If a security manager is present, and the caller's class loader + * is not {@code null} and is not the same as or an ancestor of the + * system class loader, and the caller does not have the + * {@link RuntimePermission}{@code ("getClassLoader")} * * @throws IllegalStateException * If invoked recursively during the construction of the class diff --git a/jdk/src/java.base/share/classes/java/lang/Math.java b/jdk/src/java.base/share/classes/java/lang/Math.java index 4261bd2c3f1..37a9d8573c5 100644 --- a/jdk/src/java.base/share/classes/java/lang/Math.java +++ b/jdk/src/java.base/share/classes/java/lang/Math.java @@ -1370,8 +1370,13 @@ public final class Math { * result is positive zero. *
  • If the argument is infinite, the result is positive infinity. *
  • If the argument is NaN, the result is NaN. - * In other words, the result is the same as the value of the expression: - *

    {@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))} + * + * @apiNote As implied by the above, one valid implementation of + * this method is given by the expression below which computes a + * {@code float} with the same exponent and significand as the + * argument but with a guaranteed zero sign bit indicating a + * positive value:
    + * {@code Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a))} * * @param a the argument whose absolute value is to be determined * @return the absolute value of the argument. @@ -1389,8 +1394,13 @@ public final class Math { * is positive zero. *

  • If the argument is infinite, the result is positive infinity. *
  • If the argument is NaN, the result is NaN. - * In other words, the result is the same as the value of the expression: - *

    {@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)} + * + * @apiNote As implied by the above, one valid implementation of + * this method is given by the expression below which computes a + * {@code double} with the same exponent and significand as the + * argument but with a guaranteed zero sign bit indicating a + * positive value:
    + * {@code Double.longBitsToDouble((Double.doubleToRawLongBits(a)<<1)>>>1)} * * @param a the argument whose absolute value is to be determined * @return the absolute value of the argument. diff --git a/jdk/src/java.base/share/classes/java/lang/StrictMath.java b/jdk/src/java.base/share/classes/java/lang/StrictMath.java index 3ef67145d0c..1491a8478bc 100644 --- a/jdk/src/java.base/share/classes/java/lang/StrictMath.java +++ b/jdk/src/java.base/share/classes/java/lang/StrictMath.java @@ -1070,8 +1070,13 @@ public final class StrictMath { * result is positive zero. *

  • If the argument is infinite, the result is positive infinity. *
  • If the argument is NaN, the result is NaN. - * In other words, the result is the same as the value of the expression: - *

    {@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))} + * + * @apiNote As implied by the above, one valid implementation of + * this method is given by the expression below which computes a + * {@code float} with the same exponent and significand as the + * argument but with a guaranteed zero sign bit indicating a + * positive value:
    + * {@code Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a))} * * @param a the argument whose absolute value is to be determined * @return the absolute value of the argument. @@ -1089,8 +1094,13 @@ public final class StrictMath { * is positive zero. *

  • If the argument is infinite, the result is positive infinity. *
  • If the argument is NaN, the result is NaN. - * In other words, the result is the same as the value of the expression: - *

    {@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)} + * + * @apiNote As implied by the above, one valid implementation of + * this method is given by the expression below which computes a + * {@code double} with the same exponent and significand as the + * argument but with a guaranteed zero sign bit indicating a + * positive value:
    + * {@code Double.longBitsToDouble((Double.doubleToRawLongBits(a)<<1)>>>1)} * * @param a the argument whose absolute value is to be determined * @return the absolute value of the argument. diff --git a/jdk/src/java.base/share/classes/java/lang/Thread.java b/jdk/src/java.base/share/classes/java/lang/Thread.java index 310ada1b470..4fac9eddf07 100644 --- a/jdk/src/java.base/share/classes/java/lang/Thread.java +++ b/jdk/src/java.base/share/classes/java/lang/Thread.java @@ -1507,28 +1507,25 @@ class Thread implements Runnable { } /** - * Returns the context ClassLoader for this Thread. The context - * ClassLoader is provided by the creator of the thread for use + * Returns the context {@code ClassLoader} for this thread. The context + * {@code ClassLoader} is provided by the creator of the thread for use * by code running in this thread when loading classes and resources. * If not {@linkplain #setContextClassLoader set}, the default is the - * ClassLoader context of the parent Thread. The context ClassLoader of the + * {@code ClassLoader} context of the parent thread. The context + * {@code ClassLoader} of the * primordial thread is typically set to the class loader used to load the * application. * - *

    If a security manager is present, and the invoker's class loader is not - * {@code null} and is not the same as or an ancestor of the context class - * loader, then this method invokes the security manager's {@link - * SecurityManager#checkPermission(java.security.Permission) checkPermission} - * method with a {@link RuntimePermission RuntimePermission}{@code - * ("getClassLoader")} permission to verify that retrieval of the context - * class loader is permitted. * - * @return the context ClassLoader for this Thread, or {@code null} + * @return the context {@code ClassLoader} for this thread, or {@code null} * indicating the system class loader (or, failing that, the * bootstrap class loader) * * @throws SecurityException - * if the current thread cannot get the context ClassLoader + * if a security manager is present, and the caller's class loader + * is not {@code null} and is not the same as or an ancestor of the + * context class loader, and the caller does not have the + * {@link RuntimePermission}{@code ("getClassLoader")} * * @since 1.2 */ diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java index 91071a2b3b4..461dd3967cb 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java @@ -497,6 +497,10 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*; String shortTypes = LambdaForm.shortenSignature(types); String className = SPECIES_CLASS_PREFIX + shortTypes; Class c = BootLoader.loadClassOrNull(className); + if (TRACE_RESOLVE) { + System.out.println("[BMH_RESOLVE] " + shortTypes + + (c != null ? " (success)" : " (fail)") ); + } if (c != null) { return c.asSubclass(BoundMethodHandle.class); } else { diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java index 174e914f805..ce1f938583f 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -492,7 +492,7 @@ class DirectMethodHandle extends MethodHandle { } // Caching machinery for field accessors: - private static final byte + static final byte AF_GETFIELD = 0, AF_PUTFIELD = 1, AF_GETSTATIC = 2, @@ -502,7 +502,7 @@ class DirectMethodHandle extends MethodHandle { AF_LIMIT = 6; // Enumerate the different field kinds using Wrapper, // with an extra case added for checked references. - private static final int + static final int FT_LAST_WRAPPER = Wrapper.COUNT-1, FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(), FT_CHECKED_REF = FT_LAST_WRAPPER+1, @@ -515,7 +515,7 @@ class DirectMethodHandle extends MethodHandle { @Stable private static final LambdaForm[] ACCESSOR_FORMS = new LambdaForm[afIndex(AF_LIMIT, false, 0)]; - private static int ftypeKind(Class ftype) { + static int ftypeKind(Class ftype) { if (ftype.isPrimitive()) return Wrapper.forPrimitiveType(ftype).ordinal(); else if (VerifyType.isNullReferenceConversion(Object.class, ftype)) @@ -566,7 +566,64 @@ class DirectMethodHandle extends MethodHandle { private static final Wrapper[] ALL_WRAPPERS = Wrapper.values(); - private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) { + private static Kind getFieldKind(boolean isGetter, boolean isVolatile, Wrapper wrapper) { + if (isGetter) { + if (isVolatile) { + switch (wrapper) { + case BOOLEAN: return GET_BOOLEAN_VOLATILE; + case BYTE: return GET_BYTE_VOLATILE; + case SHORT: return GET_SHORT_VOLATILE; + case CHAR: return GET_CHAR_VOLATILE; + case INT: return GET_INT_VOLATILE; + case LONG: return GET_LONG_VOLATILE; + case FLOAT: return GET_FLOAT_VOLATILE; + case DOUBLE: return GET_DOUBLE_VOLATILE; + case OBJECT: return GET_OBJECT_VOLATILE; + } + } else { + switch (wrapper) { + case BOOLEAN: return GET_BOOLEAN; + case BYTE: return GET_BYTE; + case SHORT: return GET_SHORT; + case CHAR: return GET_CHAR; + case INT: return GET_INT; + case LONG: return GET_LONG; + case FLOAT: return GET_FLOAT; + case DOUBLE: return GET_DOUBLE; + case OBJECT: return GET_OBJECT; + } + } + } else { + if (isVolatile) { + switch (wrapper) { + case BOOLEAN: return PUT_BOOLEAN_VOLATILE; + case BYTE: return PUT_BYTE_VOLATILE; + case SHORT: return PUT_SHORT_VOLATILE; + case CHAR: return PUT_CHAR_VOLATILE; + case INT: return PUT_INT_VOLATILE; + case LONG: return PUT_LONG_VOLATILE; + case FLOAT: return PUT_FLOAT_VOLATILE; + case DOUBLE: return PUT_DOUBLE_VOLATILE; + case OBJECT: return PUT_OBJECT_VOLATILE; + } + } else { + switch (wrapper) { + case BOOLEAN: return PUT_BOOLEAN; + case BYTE: return PUT_BYTE; + case SHORT: return PUT_SHORT; + case CHAR: return PUT_CHAR; + case INT: return PUT_INT; + case LONG: return PUT_LONG; + case FLOAT: return PUT_FLOAT; + case DOUBLE: return PUT_DOUBLE; + case OBJECT: return PUT_OBJECT; + } + } + } + throw new AssertionError("Invalid arguments"); + } + + static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) { boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1); boolean isStatic = (formOp >= AF_GETSTATIC); boolean needsInit = (formOp >= AF_GETSTATIC_INIT); @@ -576,24 +633,14 @@ class DirectMethodHandle extends MethodHandle { assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind); // getObject, putIntVolatile, etc. - StringBuilder nameBuilder = new StringBuilder(); - if (isGetter) { - nameBuilder.append("get"); - } else { - nameBuilder.append("put"); - } - nameBuilder.append(fw.primitiveSimpleName()); - nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3))); - if (isVolatile) { - nameBuilder.append("Volatile"); - } + Kind kind = getFieldKind(isGetter, isVolatile, fw); MethodType linkerType; if (isGetter) linkerType = MethodType.methodType(ft, Object.class, long.class); else linkerType = MethodType.methodType(void.class, Object.class, long.class, ft); - MemberName linker = new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual); + MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual); try { linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class); } catch (ReflectiveOperationException ex) { @@ -620,6 +667,7 @@ class DirectMethodHandle extends MethodHandle { final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any final int F_OFFSET = nameCursor++; // Either static offset or field offset. final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1); + final int U_HOLDER = nameCursor++; // UNSAFE holder final int INIT_BAR = (needsInit ? nameCursor++ : -1); final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1); final int LINKER_CALL = nameCursor++; @@ -632,7 +680,7 @@ class DirectMethodHandle extends MethodHandle { names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]); Object[] outArgs = new Object[1 + linkerType.parameterCount()]; assert(outArgs.length == (isGetter ? 3 : 4)); - outArgs[0] = UNSAFE; + outArgs[0] = names[U_HOLDER] = new Name(NF_UNSAFE); if (isStatic) { outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]); outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]); @@ -650,6 +698,7 @@ class DirectMethodHandle extends MethodHandle { for (Name n : names) assert(n != null); // add some detail to the lambdaForm debugname, // significant only for debugging + StringBuilder nameBuilder = new StringBuilder(kind.methodName); if (isStatic) { nameBuilder.append("Static"); } else { @@ -657,7 +706,12 @@ class DirectMethodHandle extends MethodHandle { } if (needsCast) nameBuilder.append("Cast"); if (needsInit) nameBuilder.append("Init"); - return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT); + if (needsCast || needsInit) { + // can't use the pre-generated form when casting and/or initializing + return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT); + } else { + return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT, kind); + } } /** @@ -674,7 +728,8 @@ class DirectMethodHandle extends MethodHandle { NF_staticOffset, NF_checkCast, NF_allocateInstance, - NF_constructorMethod; + NF_constructorMethod, + NF_UNSAFE; static { try { NamedFunction nfs[] = { @@ -697,7 +752,9 @@ class DirectMethodHandle extends MethodHandle { NF_allocateInstance = new NamedFunction(DirectMethodHandle.class .getDeclaredMethod("allocateInstance", Object.class)), NF_constructorMethod = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("constructorMethod", Object.class)) + .getDeclaredMethod("constructorMethod", Object.class)), + NF_UNSAFE = new NamedFunction(new MemberName(MethodHandleStatics.class + .getDeclaredField("UNSAFE"))) }; // Each nf must be statically invocable or we get tied up in our bootstraps. assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs)); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java b/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java index 714e6268d25..d8e6dcd5ed0 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java @@ -28,9 +28,11 @@ package java.lang.invoke; import java.util.Map; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Opcodes; - import java.util.ArrayList; import java.util.HashSet; +import sun.invoke.util.Wrapper; + +import static java.lang.invoke.MethodHandleNatives.Constants.*; /** * Helper class to assist the GenerateJLIClassesPlugin to get access to @@ -66,14 +68,38 @@ class GenerateJLIClassesHelper { static byte[] generateDirectMethodHandleHolderClassBytes(String className, MethodType[] methodTypes, int[] types) { - LambdaForm[] forms = new LambdaForm[methodTypes.length]; - String[] names = new String[methodTypes.length]; - for (int i = 0; i < forms.length; i++) { - forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i], - types[i]); - names[i] = forms[i].kind.defaultLambdaName; + ArrayList forms = new ArrayList<>(); + ArrayList names = new ArrayList<>(); + for (int i = 0; i < methodTypes.length; i++) { + LambdaForm form = DirectMethodHandle + .makePreparedLambdaForm(methodTypes[i], types[i]); + forms.add(form); + names.add(form.kind.defaultLambdaName); } - return generateCodeBytesForLFs(className, names, forms); + for (Wrapper wrapper : Wrapper.values()) { + if (wrapper == Wrapper.VOID) { + continue; + } + for (byte b = DirectMethodHandle.AF_GETFIELD; b < DirectMethodHandle.AF_LIMIT; b++) { + int ftype = DirectMethodHandle.ftypeKind(wrapper.primitiveType()); + LambdaForm form = DirectMethodHandle + .makePreparedFieldLambdaForm(b, /*isVolatile*/false, ftype); + if (form.kind != LambdaForm.Kind.GENERIC) { + forms.add(form); + names.add(form.kind.defaultLambdaName); + } + // volatile + form = DirectMethodHandle + .makePreparedFieldLambdaForm(b, /*isVolatile*/true, ftype); + if (form.kind != LambdaForm.Kind.GENERIC) { + forms.add(form); + names.add(form.kind.defaultLambdaName); + } + } + } + return generateCodeBytesForLFs(className, + names.toArray(new String[0]), + forms.toArray(new LambdaForm[0])); } static byte[] generateDelegatingMethodHandleHolderClassBytes(String className, @@ -107,6 +133,34 @@ class GenerateJLIClassesHelper { forms.toArray(new LambdaForm[0])); } + static byte[] generateInvokersHolderClassBytes(String className, + MethodType[] methodTypes) { + + HashSet dedupSet = new HashSet<>(); + ArrayList forms = new ArrayList<>(); + ArrayList names = new ArrayList<>(); + int[] types = { + MethodTypeForm.LF_EX_LINKER, + MethodTypeForm.LF_EX_INVOKER, + MethodTypeForm.LF_GEN_LINKER, + MethodTypeForm.LF_GEN_INVOKER + }; + for (int i = 0; i < methodTypes.length; i++) { + // generate methods representing invokers of the specified type + if (dedupSet.add(methodTypes[i])) { + for (int type : types) { + LambdaForm invokerForm = Invokers.invokeHandleForm(methodTypes[i], + /*customized*/false, type); + forms.add(invokerForm); + names.add(invokerForm.kind.defaultLambdaName); + } + } + } + return generateCodeBytesForLFs(className, + names.toArray(new String[0]), + forms.toArray(new LambdaForm[0])); + } + /* * Generate customized code for a set of LambdaForms of specified types into * a class with a specified name. @@ -166,4 +220,5 @@ class GenerateJLIClassesHelper { BoundMethodHandle.Factory.generateConcreteBMHClassBytes( shortTypes, types, className)); } + } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 6b9a2703be2..afb04b6efa4 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -607,7 +607,10 @@ class InvokerBytecodeGenerator { private static MemberName resolveFrom(String name, MethodType type, Class holder) { MemberName member = new MemberName(holder, name, type, REF_invokeStatic); MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder); - + if (TRACE_RESOLVE) { + System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " + + shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") ); + } return resolvedMember; } @@ -629,6 +632,28 @@ class InvokerBytecodeGenerator { name = name + "_" + form.returnType().basicTypeChar(); return resolveFrom(name, invokerType, LambdaForm.Holder.class); } + case EXACT_INVOKER: // fall-through + case EXACT_LINKER: // fall-through + case GENERIC_INVOKER: // fall-through + case GENERIC_LINKER: return resolveFrom(name, invokerType.basicType(), Invokers.Holder.class); + case GET_OBJECT: // fall-through + case GET_BOOLEAN: // fall-through + case GET_BYTE: // fall-through + case GET_CHAR: // fall-through + case GET_SHORT: // fall-through + case GET_INT: // fall-through + case GET_LONG: // fall-through + case GET_FLOAT: // fall-through + case GET_DOUBLE: // fall-through + case PUT_OBJECT: // fall-through + case PUT_BOOLEAN: // fall-through + case PUT_BYTE: // fall-through + case PUT_CHAR: // fall-through + case PUT_SHORT: // fall-through + case PUT_INT: // fall-through + case PUT_LONG: // fall-through + case PUT_FLOAT: // fall-through + case PUT_DOUBLE: // fall-through case DIRECT_INVOKE_INTERFACE: // fall-through case DIRECT_INVOKE_SPECIAL: // fall-through case DIRECT_INVOKE_STATIC: // fall-through diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java index 1aca86298fe..0a97622fe84 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java @@ -36,6 +36,7 @@ import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.Kind.*; /** * Construction and caching of often-used invokers. @@ -254,7 +255,7 @@ class Invokers { * @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker"); * 0x02 whether it is for invokeExact or generic invoke */ - private static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) { + static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) { boolean isCached; if (!customized) { mtype = mtype.basicType(); // normalize Z to I, String to Object, etc. @@ -263,12 +264,12 @@ class Invokers { isCached = false; // maybe cache if mtype == mtype.basicType() } boolean isLinker, isGeneric; - String debugName; + Kind kind; switch (which) { - case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; debugName = "invokeExact_MT"; break; - case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; debugName = "exactInvoker"; break; - case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; debugName = "invoke_MT"; break; - case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; debugName = "invoker"; break; + case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; kind = EXACT_LINKER; break; + case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; kind = EXACT_INVOKER; break; + case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; kind = GENERIC_LINKER; break; + case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; kind = GENERIC_INVOKER; break; default: throw new InternalError(); } LambdaForm lform; @@ -323,7 +324,11 @@ class Invokers { names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]); } names[LINKER_CALL] = new Name(outCallType, outArgs); - lform = new LambdaForm(debugName, INARG_LIMIT, names); + if (customized) { + lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names); + } else { + lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names, kind); + } if (isLinker) lform.compileToBytecode(); // JVM needs a real methodOop if (isCached) @@ -614,4 +619,15 @@ class Invokers { } } } + + static { + // The Holder class will contain pre-generated Invokers resolved + // speculatively using MemberName.getFactory().resolveOrNull. However, that + // doesn't initialize the class, which subtly breaks inlining etc. By forcing + // initialization of the Holder class we avoid these issues. + UNSAFE.ensureClassInitialized(Holder.class); + } + + /* Placeholder class for Invokers generated ahead of time */ + final class Holder {} } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java index a7c84c823ea..6fdf21e2c91 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java @@ -275,12 +275,52 @@ class LambdaForm { BOUND_REINVOKER("BMH.reinvoke"), REINVOKER("MH.reinvoke"), DELEGATE("MH.delegate"), + EXACT_LINKER("MH.invokeExact_MT"), + EXACT_INVOKER("MH.exactInvoker"), + GENERIC_LINKER("MH.invoke_MT"), + GENERIC_INVOKER("MH.invoker"), DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"), DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"), DIRECT_INVOKE_STATIC("DMH.invokeStatic"), DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"), DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"), - DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"); + DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"), + GET_OBJECT("getObject"), + PUT_OBJECT("putObject"), + GET_OBJECT_VOLATILE("getObjectVolatile"), + PUT_OBJECT_VOLATILE("putObjectVolatile"), + GET_INT("getInt"), + PUT_INT("putInt"), + GET_INT_VOLATILE("getIntVolatile"), + PUT_INT_VOLATILE("putIntVolatile"), + GET_BOOLEAN("getBoolean"), + PUT_BOOLEAN("putBoolean"), + GET_BOOLEAN_VOLATILE("getBooleanVolatile"), + PUT_BOOLEAN_VOLATILE("putBooleanVolatile"), + GET_BYTE("getByte"), + PUT_BYTE("putByte"), + GET_BYTE_VOLATILE("getByteVolatile"), + PUT_BYTE_VOLATILE("putByteVolatile"), + GET_CHAR("getChar"), + PUT_CHAR("putChar"), + GET_CHAR_VOLATILE("getCharVolatile"), + PUT_CHAR_VOLATILE("putCharVolatile"), + GET_SHORT("getShort"), + PUT_SHORT("putShort"), + GET_SHORT_VOLATILE("getShortVolatile"), + PUT_SHORT_VOLATILE("putShortVolatile"), + GET_LONG("getLong"), + PUT_LONG("putLong"), + GET_LONG_VOLATILE("getLongVolatile"), + PUT_LONG_VOLATILE("putLongVolatile"), + GET_FLOAT("getFloat"), + PUT_FLOAT("putFloat"), + GET_FLOAT_VOLATILE("getFloatVolatile"), + PUT_FLOAT_VOLATILE("putFloatVolatile"), + GET_DOUBLE("getDouble"), + PUT_DOUBLE("putDouble"), + GET_DOUBLE_VOLATILE("getDoubleVolatile"), + PUT_DOUBLE_VOLATILE("putDoubleVolatile"); final String defaultLambdaName; final String methodName; @@ -329,6 +369,10 @@ class LambdaForm { int arity, Name[] names) { this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); } + LambdaForm(String debugName, + int arity, Name[] names, Kind kind) { + this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, kind); + } LambdaForm(String debugName, int arity, Name[] names, boolean forceInline) { this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC); @@ -817,54 +861,6 @@ class LambdaForm { } } - private static void computeInitialPreparedForms() { - // Find all predefined invokers and associate them with canonical empty lambda forms. - for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) { - if (!m.isStatic() || !m.isPackage()) continue; - MethodType mt = m.getMethodType(); - if (mt.parameterCount() > 0 && - mt.parameterType(0) == MethodHandle.class && - m.getName().startsWith("interpret_")) { - String sig = null; - assert((sig = basicTypeSignature(mt)) != null && - m.getName().equals("interpret" + sig.substring(sig.indexOf('_')))); - LambdaForm form = new LambdaForm(mt); - form.vmentry = m; - form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form); - } - } - } - - // Set this false to disable use of the interpret_L methods defined in this file. - private static final boolean USE_PREDEFINED_INTERPRET_METHODS = true; - - // The following are predefined exact invokers. The system must build - // a separate invoker for each distinct signature. - static Object interpret_L(MethodHandle mh) throws Throwable { - Object[] av = {mh}; - String sig = null; - assert(argumentTypesMatch(sig = "L_L", av)); - Object res = mh.form.interpretWithArguments(av); - assert(returnTypesMatch(sig, av, res)); - return res; - } - static Object interpret_L(MethodHandle mh, Object x1) throws Throwable { - Object[] av = {mh, x1}; - String sig = null; - assert(argumentTypesMatch(sig = "LL_L", av)); - Object res = mh.form.interpretWithArguments(av); - assert(returnTypesMatch(sig, av, res)); - return res; - } - static Object interpret_L(MethodHandle mh, Object x1, Object x2) throws Throwable { - Object[] av = {mh, x1, x2}; - String sig = null; - assert(argumentTypesMatch(sig = "LLL_L", av)); - Object res = mh.form.interpretWithArguments(av); - assert(returnTypesMatch(sig, av, res)); - return res; - } - // The next few routines are called only from assert expressions // They verify that the built-in invokers process the correct raw data types. private static boolean argumentTypesMatch(String sig, Object[] av) { @@ -1151,113 +1147,6 @@ class LambdaForm { return super.hashCode(); } - // Put the predefined NamedFunction invokers into the table. - static void initializeInvokers() { - for (MemberName m : MemberName.getFactory().getMethods(NamedFunction.class, false, null, null, null)) { - if (!m.isStatic() || !m.isPackage()) continue; - MethodType type = m.getMethodType(); - if (type.equals(INVOKER_METHOD_TYPE) && - m.getName().startsWith("invoke_")) { - String sig = m.getName().substring("invoke_".length()); - int arity = LambdaForm.signatureArity(sig); - MethodType srcType = MethodType.genericMethodType(arity); - if (LambdaForm.signatureReturn(sig) == V_TYPE) - srcType = srcType.changeReturnType(void.class); - MethodTypeForm typeForm = srcType.form(); - typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, DirectMethodHandle.make(m)); - } - } - } - - // The following are predefined NamedFunction invokers. The system must build - // a separate invoker for each distinct signature. - /** void return type invokers. */ - @Hidden - static Object invoke__V(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(0, void.class, mh, a)); - mh.invokeBasic(); - return null; - } - @Hidden - static Object invoke_L_V(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(1, void.class, mh, a)); - mh.invokeBasic(a[0]); - return null; - } - @Hidden - static Object invoke_LL_V(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(2, void.class, mh, a)); - mh.invokeBasic(a[0], a[1]); - return null; - } - @Hidden - static Object invoke_LLL_V(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(3, void.class, mh, a)); - mh.invokeBasic(a[0], a[1], a[2]); - return null; - } - @Hidden - static Object invoke_LLLL_V(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(4, void.class, mh, a)); - mh.invokeBasic(a[0], a[1], a[2], a[3]); - return null; - } - @Hidden - static Object invoke_LLLLL_V(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(5, void.class, mh, a)); - mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]); - return null; - } - /** Object return type invokers. */ - @Hidden - static Object invoke__L(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(0, mh, a)); - return mh.invokeBasic(); - } - @Hidden - static Object invoke_L_L(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(1, mh, a)); - return mh.invokeBasic(a[0]); - } - @Hidden - static Object invoke_LL_L(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(2, mh, a)); - return mh.invokeBasic(a[0], a[1]); - } - @Hidden - static Object invoke_LLL_L(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(3, mh, a)); - return mh.invokeBasic(a[0], a[1], a[2]); - } - @Hidden - static Object invoke_LLLL_L(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(4, mh, a)); - return mh.invokeBasic(a[0], a[1], a[2], a[3]); - } - @Hidden - static Object invoke_LLLLL_L(MethodHandle mh, Object[] a) throws Throwable { - assert(arityCheck(5, mh, a)); - return mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]); - } - private static boolean arityCheck(int arity, MethodHandle mh, Object[] a) { - return arityCheck(arity, Object.class, mh, a); - } - private static boolean arityCheck(int arity, Class rtype, MethodHandle mh, Object[] a) { - assert(a.length == arity) - : Arrays.asList(a.length, arity); - assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype)) - : Arrays.asList(mh, rtype, arity); - MemberName member = mh.internalMemberName(); - if (isInvokeBasic(member)) { - assert(arity > 0); - assert(a[0] instanceof MethodHandle); - MethodHandle mh2 = (MethodHandle) a[0]; - assert(mh2.type().basicType() == MethodType.genericMethodType(arity-1).changeReturnType(rtype)) - : Arrays.asList(member, mh2, rtype, arity); - } - return true; - } - static final MethodType INVOKER_METHOD_TYPE = MethodType.methodType(Object.class, MethodHandle.class, Object[].class); @@ -1920,12 +1809,7 @@ class LambdaForm { DEBUG_NAME_COUNTERS = null; } - // Put this last, so that previous static inits can run before. static { - if (USE_PREDEFINED_INTERPRET_METHODS) - computeInitialPreparedForms(); - NamedFunction.initializeInvokers(); - // The Holder class will contain pre-generated forms resolved // using MemberName.getFactory(). However, that doesn't initialize the // class, which subtly breaks inlining etc. By forcing diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index 4d0c2890fdf..4fe4bb524a7 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -1745,6 +1745,13 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*; return GenerateJLIClassesHelper .generateBasicFormsClassBytes(className); } + + @Override + public byte[] generateInvokersHolderClassBytes(final String className, + MethodType[] methodTypes) { + return GenerateJLIClassesHelper + .generateInvokersHolderClassBytes(className, methodTypes); + } }); } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java index 4f5f1f4dc0d..22408f1b55a 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java @@ -46,6 +46,7 @@ import java.util.Properties; static final boolean DUMP_CLASS_FILES; static final boolean TRACE_INTERPRETER; static final boolean TRACE_METHOD_LINKAGE; + static final boolean TRACE_RESOLVE; static final int COMPILE_THRESHOLD; static final boolean LOG_LF_COMPILATION_FAILURE; static final int DONT_INLINE_THRESHOLD; @@ -65,6 +66,8 @@ import java.util.Properties; props.getProperty("java.lang.invoke.MethodHandle.TRACE_INTERPRETER")); TRACE_METHOD_LINKAGE = Boolean.parseBoolean( props.getProperty("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE")); + TRACE_RESOLVE = Boolean.parseBoolean( + props.getProperty("java.lang.invoke.MethodHandle.TRACE_RESOLVE")); COMPILE_THRESHOLD = Integer.parseInt( props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0")); LOG_LF_COMPILATION_FAILURE = Boolean.parseBoolean( diff --git a/jdk/src/java.base/share/classes/java/net/HttpCookie.java b/jdk/src/java.base/share/classes/java/net/HttpCookie.java index c8d127837ca..7cc7d6e8ebc 100644 --- a/jdk/src/java.base/share/classes/java/net/HttpCookie.java +++ b/jdk/src/java.base/share/classes/java/net/HttpCookie.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -233,7 +233,7 @@ public final class HttpCookie implements Cloneable { // if not specify max-age, this cookie should be // discarded when user agent is to be closed, but // it is not expired. - if (maxAge == MAX_AGE_UNSPECIFIED) return false; + if (maxAge < 0) return false; long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000; if (deltaSecond > maxAge) @@ -952,7 +952,8 @@ public final class HttpCookie implements Cloneable { String attrName, String attrValue) { if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED) { - cookie.setMaxAge(cookie.expiryDate2DeltaSeconds(attrValue)); + long delta = cookie.expiryDate2DeltaSeconds(attrValue); + cookie.setMaxAge(delta > 0 ? delta : 0); } } }); diff --git a/jdk/src/java.base/share/classes/java/time/Duration.java b/jdk/src/java.base/share/classes/java/time/Duration.java index 13e8eff9783..e2c55a971ea 100644 --- a/jdk/src/java.base/share/classes/java/time/Duration.java +++ b/jdk/src/java.base/share/classes/java/time/Duration.java @@ -150,10 +150,12 @@ public final class Duration /** * The pattern for parsing. */ - private static final Pattern PATTERN = + private static class Lazy { + static final Pattern PATTERN = Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" + "(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?", Pattern.CASE_INSENSITIVE); + } /** * The number of seconds in the duration. @@ -387,7 +389,7 @@ public final class Duration */ public static Duration parse(CharSequence text) { Objects.requireNonNull(text, "text"); - Matcher matcher = PATTERN.matcher(text); + Matcher matcher = Lazy.PATTERN.matcher(text); if (matcher.matches()) { // check for letter T but no time sections if (!charMatch(text, matcher.start(3), matcher.end(3), 'T')) { diff --git a/jdk/src/java.base/share/classes/java/time/ZoneOffset.java b/jdk/src/java.base/share/classes/java/time/ZoneOffset.java index c5d15ef8ccc..9f2e9c2d356 100644 --- a/jdk/src/java.base/share/classes/java/time/ZoneOffset.java +++ b/jdk/src/java.base/share/classes/java/time/ZoneOffset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -375,15 +375,15 @@ public final class ZoneOffset } else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) { throw new DateTimeException("Zone offset minutes and seconds must have the same sign"); } - if (Math.abs(minutes) > 59) { - throw new DateTimeException("Zone offset minutes not in valid range: abs(value) " + - Math.abs(minutes) + " is not in the range 0 to 59"); + if (minutes < -59 || minutes > 59) { + throw new DateTimeException("Zone offset minutes not in valid range: value " + + minutes + " is not in the range -59 to 59"); } - if (Math.abs(seconds) > 59) { - throw new DateTimeException("Zone offset seconds not in valid range: abs(value) " + - Math.abs(seconds) + " is not in the range 0 to 59"); + if (seconds < -59 || seconds > 59) { + throw new DateTimeException("Zone offset seconds not in valid range: value " + + seconds + " is not in the range -59 to 59"); } - if (Math.abs(hours) == 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) { + if (Math.abs(hours) == 18 && (minutes | seconds) != 0) { throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00"); } } @@ -411,7 +411,7 @@ public final class ZoneOffset * @throws DateTimeException if the offset is not in the required range */ public static ZoneOffset ofTotalSeconds(int totalSeconds) { - if (Math.abs(totalSeconds) > MAX_SECONDS) { + if (totalSeconds < -MAX_SECONDS || totalSeconds > MAX_SECONDS) { throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00"); } if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) { @@ -696,11 +696,12 @@ public final class ZoneOffset * The comparison is "consistent with equals", as defined by {@link Comparable}. * * @param other the other date to compare to, not null - * @return the comparator value, negative if less, postive if greater + * @return the comparator value, negative if less, positive if greater * @throws NullPointerException if {@code other} is null */ @Override public int compareTo(ZoneOffset other) { + // abs(totalSeconds) <= MAX_SECONDS, so no overflow can happen here return other.totalSeconds - totalSeconds; } diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index aadf3ca32a9..1d80077b58c 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -4566,7 +4566,10 @@ public class ConcurrentHashMap extends AbstractMap boolean modified = false; // Use (c instanceof Set) as a hint that lookup in c is as // efficient as this view - if (c instanceof Set && c.size() > map.table.length) { + Node[] t; + if ((t = map.table) == null) { + return false; + } else if (c instanceof Set && c.size() > t.length) { for (Iterator it = iterator(); it.hasNext(); ) { if (c.contains(it.next())) { it.remove(); diff --git a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java index 82a96607b90..2c4500d169b 100644 --- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java +++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java @@ -353,7 +353,7 @@ class JarFile extends ZipFile { if (isMultiRelease) { return true; } - if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) { + if (MULTI_RELEASE_ENABLED) { try { checkForSpecialAttributes(); } catch (IOException io) { @@ -644,7 +644,7 @@ class JarFile extends ZipFile { return signers == null ? null : signers.clone(); } JarFileEntry realEntry() { - if (isMultiRelease()) { + if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) { String entryName = super.getName(); return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this); } @@ -960,7 +960,7 @@ class JarFile extends ZipFile { hasClassPathAttribute = match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC) != -1; // is this a multi-release jar file - if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) { + if (MULTI_RELEASE_ENABLED) { int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC); if (i != -1) { i += MULTIRELEASE_CHARS.length; diff --git a/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java b/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java index d4fffacf38f..cc32f835696 100644 --- a/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java +++ b/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java @@ -29,6 +29,7 @@ import java.util.*; import java.util.jar.*; import java.io.*; import java.net.URL; +import java.nio.file.*; import java.security.*; import java.security.Provider.Service; @@ -206,7 +207,7 @@ final class JceSecurity { static { try { - NULL_URL = new URL("http://null.sun.com/"); + NULL_URL = new URL("http://null.oracle.com/"); } catch (Exception e) { throw new RuntimeException(e); } @@ -243,83 +244,94 @@ final class JceSecurity { } } + // This is called from within an doPrivileged block. private static void setupJurisdictionPolicies() throws Exception { - String javaHomeDir = System.getProperty("java.home"); - String sep = File.separator; - String pathToPolicyJar = javaHomeDir + sep + "lib" + sep + - "security" + sep; - File exportJar = new File(pathToPolicyJar, "US_export_policy.jar"); - File importJar = new File(pathToPolicyJar, "local_policy.jar"); + // Sanity check the crypto.policy Security property. Single + // directory entry, no pseudo-directories (".", "..", leading/trailing + // path separators). normalize()/getParent() will help later. + String cryptoPolicyProperty = Security.getProperty("crypto.policy"); + Path cpPath = Paths.get(cryptoPolicyProperty); - if (!exportJar.exists() || !importJar.exists()) { - throw new SecurityException - ("Cannot locate policy or framework files!"); + if ((cryptoPolicyProperty == null) || + (cpPath.getNameCount() != 1) || + (cpPath.compareTo(cpPath.getFileName()) != 0)) { + throw new SecurityException( + "Invalid policy directory name format: " + + cryptoPolicyProperty); } - // Read jurisdiction policies. - CryptoPermissions defaultExport = new CryptoPermissions(); - CryptoPermissions exemptExport = new CryptoPermissions(); - loadPolicies(exportJar, defaultExport, exemptExport); + // Prepend java.home to get the full path. normalize() in + // case an extra "." or ".." snuck in somehow. + String javaHomeProperty = System.getProperty("java.home"); + Path javaHomePolicyPath = Paths.get(javaHomeProperty, "conf", + "security", "policy").normalize(); + Path cryptoPolicyPath = Paths.get(javaHomeProperty, "conf", "security", + "policy", cryptoPolicyProperty).normalize(); - CryptoPermissions defaultImport = new CryptoPermissions(); - CryptoPermissions exemptImport = new CryptoPermissions(); - loadPolicies(importJar, defaultImport, exemptImport); - - // Merge the export and import policies for default applications. - if (defaultExport.isEmpty() || defaultImport.isEmpty()) { - throw new SecurityException("Missing mandatory jurisdiction " + - "policy files"); + if (cryptoPolicyPath.getParent().compareTo(javaHomePolicyPath) != 0) { + throw new SecurityException( + "Invalid cryptographic jurisdiction policy directory path: " + + cryptoPolicyProperty); } - defaultPolicy = defaultExport.getMinimum(defaultImport); - // Merge the export and import policies for exempt applications. - if (exemptExport.isEmpty()) { - exemptPolicy = exemptImport.isEmpty() ? null : exemptImport; - } else { - exemptPolicy = exemptExport.getMinimum(exemptImport); + if (!Files.isDirectory(cryptoPolicyPath) + || !Files.isReadable(cryptoPolicyPath)) { + throw new SecurityException( + "Can't read cryptographic policy directory: " + + cryptoPolicyProperty); } - } - /** - * Load the policies from the specified file. Also checks that the - * policies are correctly signed. - */ - private static void loadPolicies(File jarPathName, - CryptoPermissions defaultPolicy, - CryptoPermissions exemptPolicy) - throws Exception { + try (DirectoryStream stream = Files.newDirectoryStream( + cryptoPolicyPath, "{default,exempt}_*.policy")) { + for (Path entry : stream) { + try (InputStream is = new BufferedInputStream( + Files.newInputStream(entry))) { + String filename = entry.getFileName().toString(); - JarFile jf = new JarFile(jarPathName); + CryptoPermissions tmpPerms = new CryptoPermissions(); + tmpPerms.load(is); - Enumeration entries = jf.entries(); - while (entries.hasMoreElements()) { - JarEntry je = entries.nextElement(); - InputStream is = null; - try { - if (je.getName().startsWith("default_")) { - is = jf.getInputStream(je); - defaultPolicy.load(is); - } else if (je.getName().startsWith("exempt_")) { - is = jf.getInputStream(je); - exemptPolicy.load(is); - } else { - continue; - } - } finally { - if (is != null) { - is.close(); + if (filename.startsWith("default_")) { + // Did we find a default perms? + defaultPolicy = ((defaultPolicy == null) ? tmpPerms : + defaultPolicy.getMinimum(tmpPerms)); + } else if (filename.startsWith("exempt_")) { + // Did we find a exempt perms? + exemptPolicy = ((exemptPolicy == null) ? tmpPerms : + exemptPolicy.getMinimum(tmpPerms)); + } else { + // This should never happen. newDirectoryStream + // should only throw return "{default,exempt}_*.policy" + throw new SecurityException( + "Unexpected jurisdiction policy files in : " + + cryptoPolicyProperty); + } + } catch (Exception e) { + throw new SecurityException( + "Couldn't parse jurisdiction policy files in: " + + cryptoPolicyProperty); } } - - // Enforce the signer restraint, i.e. signer of JCE framework - // jar should also be the signer of the two jurisdiction policy - // jar files. - ProviderVerifier.verifyPolicySigned(je.getCertificates()); + } catch (DirectoryIteratorException ex) { + // I/O error encountered during the iteration, + // the cause is an IOException + throw new SecurityException( + "Couldn't iterate through the jurisdiction policy files: " + + cryptoPolicyProperty); + } + + // Must have a default policy + if ((defaultPolicy == null) || defaultPolicy.isEmpty()) { + throw new SecurityException( + "Missing mandatory jurisdiction policy files: " + + cryptoPolicyProperty); + } + + // If there was an empty exempt policy file, ignore it. + if ((exemptPolicy != null) && exemptPolicy.isEmpty()) { + exemptPolicy = null; } - // Close and nullify the JarFile reference to help GC. - jf.close(); - jf = null; } static CryptoPermissions getDefaultPolicy() { diff --git a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtDirectoryStream.java b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtDirectoryStream.java index eced854d9d8..f2f2aa684c3 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtDirectoryStream.java +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtDirectoryStream.java @@ -47,8 +47,8 @@ final class JrtDirectoryStream implements DirectoryStream { private final JrtPath dir; private final DirectoryStream.Filter filter; - private volatile boolean isClosed; - private volatile Iterator itr; + private boolean isClosed; + private Iterator itr; JrtDirectoryStream(JrtPath dir, DirectoryStream.Filter filter) @@ -73,24 +73,22 @@ final class JrtDirectoryStream implements DirectoryStream { throw new IllegalStateException(e); } return new Iterator() { - private Path next; @Override - public synchronized boolean hasNext() { - if (isClosed) - return false; - return itr.hasNext(); + public boolean hasNext() { + synchronized (JrtDirectoryStream.this) { + if (isClosed) + return false; + return itr.hasNext(); + } } @Override - public synchronized Path next() { - if (isClosed) - throw new NoSuchElementException(); - return itr.next(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); + public Path next() { + synchronized (JrtDirectoryStream.this) { + if (isClosed) + throw new NoSuchElementException(); + return itr.next(); + } } }; } diff --git a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java index 5f0433b9d3b..cb6c85d11e3 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java @@ -119,9 +119,7 @@ class JrtFileSystem extends FileSystem { @Override public Iterable getRootDirectories() { - ArrayList dirs = new ArrayList<>(); - dirs.add(getRootPath()); - return dirs; + return Collections.singleton(getRootPath()); } @Override @@ -159,9 +157,7 @@ class JrtFileSystem extends FileSystem { @Override public final Iterable getFileStores() { - ArrayList list = new ArrayList<>(1); - list.add(getFileStore(getRootPath())); - return list; + return Collections.singleton(getFileStore(getRootPath())); } private static final Set supportedFileAttributeViews diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java index 867853f22e8..c710c6543ef 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java @@ -46,7 +46,7 @@ public interface JavaLangInvokeAccess { boolean isNative(Object mname); /** - * Returns a {@code byte[]} containing the bytecode for a class implementing + * Returns a {@code byte[]} representation of a class implementing * DirectMethodHandle of each pairwise combination of {@code MethodType} and * an {@code int} representing method type. Used by * GenerateJLIClassesPlugin to generate such a class during the jlink phase. @@ -55,7 +55,7 @@ public interface JavaLangInvokeAccess { MethodType[] methodTypes, int[] types); /** - * Returns a {@code byte[]} containing the bytecode for a class implementing + * Returns a {@code byte[]} representation of a class implementing * DelegatingMethodHandles of each {@code MethodType} kind in the * {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to * generate such a class during the jlink phase. @@ -64,7 +64,7 @@ public interface JavaLangInvokeAccess { MethodType[] methodTypes); /** - * Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle + * Returns a {@code byte[]} representation of {@code BoundMethodHandle} * species class implementing the signature defined by {@code types}. Used * by GenerateBMHClassesPlugin to enable generation of such classes during * the jlink phase. Should do some added validation since this string may be @@ -74,8 +74,15 @@ public interface JavaLangInvokeAccess { final String types); /** - * Returns a {@code byte[]} containing the bytecode for a class implementing + * Returns a {@code byte[]} representation of a class implementing * the zero and identity forms of all {@code LambdaForm.BasicType}s. */ byte[] generateBasicFormsClassBytes(final String className); + + /** + * Returns a {@code byte[]} representation of a class implementing + * the invoker forms for the set of supplied {@code methodTypes}. + */ + byte[] generateInvokersHolderClassBytes(String className, + MethodType[] methodTypes); } diff --git a/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java b/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java index d236c346d87..d757a192b81 100644 --- a/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java +++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java @@ -253,7 +253,8 @@ public final class RSAPadding { public byte[] pad(byte[] data) throws BadPaddingException { if (data.length > maxDataSize) { throw new BadPaddingException("Data must be shorter than " - + (maxDataSize + 1) + " bytes"); + + (maxDataSize + 1) + " bytes but received " + + data.length + " bytes."); } switch (type) { case PAD_NONE: @@ -281,7 +282,9 @@ public final class RSAPadding { */ public byte[] unpad(byte[] padded) throws BadPaddingException { if (padded.length != paddedSize) { - throw new BadPaddingException("Decryption error"); + throw new BadPaddingException("Decryption error." + + "The padded array length (" + padded.length + + ") is not the specified padded size (" + paddedSize + ")"); } switch (type) { case PAD_NONE: diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java index 57a3e1e8aa6..2056d2fe7a2 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java @@ -493,7 +493,9 @@ final class CipherBox { if (protocolVersion.useTLS11PlusSpec()) { if (newLen < blockSize) { - throw new BadPaddingException("invalid explicit IV"); + throw new BadPaddingException("The length after " + + "padding removal (" + newLen + ") should be larger " + + "than <" + blockSize + "> since explicit IV used"); } } } @@ -504,7 +506,6 @@ final class CipherBox { } } - /* * Decrypts a block of data, returning the size of the * resulting block if padding was required. position and limit @@ -575,7 +576,9 @@ final class CipherBox { // check the explicit IV of TLS v1.1 or later if (protocolVersion.useTLS11PlusSpec()) { if (newLen < blockSize) { - throw new BadPaddingException("invalid explicit IV"); + throw new BadPaddingException("The length after " + + "padding removal (" + newLen + ") should be larger " + + "than <" + blockSize + "> since explicit IV used"); } // reset the position to the end of the decrypted data @@ -756,7 +759,9 @@ final class CipherBox { // so accept that as well // v3 does not require any particular value for the other bytes if (padLen > blockSize) { - throw new BadPaddingException("Invalid SSLv3 padding"); + throw new BadPaddingException("Padding length (" + + padLen + ") of SSLv3 message should not be bigger " + + "than the block size (" + blockSize + ")"); } } return newLen; @@ -802,7 +807,9 @@ final class CipherBox { // so accept that as well // v3 does not require any particular value for the other bytes if (padLen > blockSize) { - throw new BadPaddingException("Invalid SSLv3 padding"); + throw new BadPaddingException("Padding length (" + + padLen + ") of SSLv3 message should not be bigger " + + "than the block size (" + blockSize + ")"); } } @@ -925,7 +932,10 @@ final class CipherBox { case AEAD_CIPHER: if (bb.remaining() < (recordIvSize + tagSize)) { throw new BadPaddingException( - "invalid AEAD cipher fragment"); + "Insufficient buffer remaining for AEAD cipher " + + "fragment (" + bb.remaining() + "). Needs to be " + + "more than or equal to IV size (" + recordIvSize + + ") + tag size (" + tagSize + ")"); } // initialize the AEAD cipher for the unique IV diff --git a/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfo.java b/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfo.java index 98c9442be36..f3929ee389f 100644 --- a/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfo.java +++ b/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfo.java @@ -27,15 +27,8 @@ package sun.util.calendar; import java.io.IOException; import java.io.ObjectInputStream; -import java.lang.ref.SoftReference; -import java.security.AccessController; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; -import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Set; import java.util.SimpleTimeZone; import java.util.TimeZone; @@ -80,8 +73,6 @@ public class ZoneInfo extends TimeZone { private static final long ABBR_MASK = 0xf00L; private static final int TRANSITION_NSHIFT = 12; - private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar(); - /** * The raw GMT offset in milliseconds between this zone and GMT. * Negative offsets are to the west of Greenwich. To obtain local @@ -379,6 +370,7 @@ public class ZoneInfo extends TimeZone { throw new IllegalArgumentException(); } + Gregorian gcal = CalendarSystem.getGregorianCalendar(); CalendarDate date = gcal.newCalendarDate(null); date.setDate(year, month + 1, day); if (gcal.validate(date) == false) { diff --git a/jdk/src/java.base/share/conf/security/java.security b/jdk/src/java.base/share/conf/security/java.security index 2bba767dd05..34e5ac92b47 100644 --- a/jdk/src/java.base/share/conf/security/java.security +++ b/jdk/src/java.base/share/conf/security/java.security @@ -490,7 +490,7 @@ networkaddress.cache.negative.ttl=10 # property is set then those two properties are ignored. # # Example, -# ocsp.responderCertSubjectName="CN=OCSP Responder, O=XYZ Corp" +# ocsp.responderCertSubjectName=CN=OCSP Responder, O=XYZ Corp # # Issuer name of the OCSP responder's certificate @@ -505,7 +505,7 @@ networkaddress.cache.negative.ttl=10 # property is ignored. # # Example, -# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp" +# ocsp.responderCertIssuerName=CN=Enterprise CA, O=XYZ Corp # # Serial number of the OCSP responder's certificate @@ -803,3 +803,94 @@ jdk.tls.legacyAlgorithms= \ # E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ # EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ # FFFFFFFF FFFFFFFF, 2} + +# Cryptographic Jurisdiction Policy defaults +# +# Due to the import control restrictions of some countries, the default +# JCE policy files allow for strong but "limited" cryptographic key +# lengths to be used. If your country's cryptographic regulations allow, +# the "unlimited" strength policy files can be used instead, which contain +# no restrictions on cryptographic strengths. +# +# If your country has restrictions that don't fit either "limited" or +# "unlimited", an appropriate set of policy files should be created and +# configured before using this distribution. The jurisdiction policy file +# configuration must reflect the cryptographic restrictions appropriate +# for your country. +# +# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY +# TO DETERMINE THE EXACT REQUIREMENTS. +# +# The policy files are flat text files organized into subdirectories of +# /conf/security/policy. Each directory contains a complete +# set of policy files. +# +# The "crypto.policy" Security property controls the directory selection, +# and thus the effective cryptographic policy. +# +# The default set of directories is: +# +# limited | unlimited +# +# however other directories can be created and configured. +# +# Within a directory, the effective policy is the combined minimum +# permissions of the grant statements in the file(s) with the filename +# pattern "default_*.policy". At least one grant is required. For +# example: +# +# limited = Export (all) + Import (limited) = Limited +# unlimited = Export (all) + Import (all) = Unlimited +# +# The effective exemption policy is the combined minimum permissions +# of the grant statements in the file(s) with the filename pattern +# "exempt_*.policy". Exemption grants are optional. +# +# limited = grants exemption permissions, by which the +# effective policy can be circumvented. +# e.g. KeyRecovery/Escrow/Weakening. +# +# Please see the JCA documentation for additional information on these +# files and formats. +crypto.policy=crypto.policydir-tbd + +# +# The policy for the XML Signature secure validation mode. The mode is +# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to +# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method, +# or by running the code with a SecurityManager. +# +# Policy: +# Constraint {"," Constraint } +# Constraint: +# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | +# ReferenceUriSchemeConstraint | OtherConstraint +# AlgConstraint +# "disallowAlg" Uri +# MaxTransformsConstraint: +# "maxTransforms" Integer +# MaxReferencesConstraint: +# "maxReferences" Integer +# ReferenceUriSchemeConstraint: +# "disallowReferenceUriSchemes" String { String } +# OtherConstraint: +# "noDuplicateIds" | "noRetrievalMethodLoops" +# +# For AlgConstraint, Uri is the algorithm URI String that is not allowed. +# See the XML Signature Recommendation for more information on algorithm +# URI Identifiers. If the MaxTransformsConstraint or MaxReferencesConstraint is +# specified more than once, only the last entry is enforced. +# +# Note: This property is currently used by the JDK Reference implementation. It +# is not guaranteed to be examined and used by other implementations. +# +jdk.xml.dsig.secureValidationPolicy=\ + disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\ + disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\ + maxTransforms 5,\ + maxReferences 30,\ + disallowReferenceUriSchemes file http https,\ + noDuplicateIds,\ + noRetrievalMethodLoops diff --git a/jdk/src/java.base/share/conf/security/policy/README.txt b/jdk/src/java.base/share/conf/security/policy/README.txt new file mode 100644 index 00000000000..84e33c972b7 --- /dev/null +++ b/jdk/src/java.base/share/conf/security/policy/README.txt @@ -0,0 +1,35 @@ + + Java(TM) Cryptography Extension Policy Files + for the Java(TM) Platform, Standard Edition Runtime Environment + + README +------------------------------------------------------------------------ + + +The JCE architecture allows flexible cryptographic strength to be +configured via the jurisdiction policy files contained within these +directories. + +Due to import control restrictions of some countries, the default +JCE policy files bundled in this Java Runtime Environment allow +for strong but "limited" cryptographic strengths. For convenience, +this build also contains the "unlimited strength" policy files which +contain no restrictions on cryptographic strengths, but they must be +specifically activated by updating the "crypto.policy" Security property +(e.g. /conf/security/java.security) to point to the appropriate +directory. + +Each subdirectory contains a complete policy configuration, and additional +subdirectories can be added/removed to reflect local regulations. + +JCE for Java SE has been through the U.S. export review process. The JCE +framework, along with the various JCE providers that come standard with it +(SunJCE, SunEC, SunPKCS11, SunMSCAPI, etc), is exportable from the +United States. + +You are advised to consult your export/import control counsel or attorney +to determine the exact requirements of your location, and what policy +settings should be used. + +Please see The Java(TM) Cryptography Architecture (JCA) Reference +Guide and the java.security file for more information. diff --git a/jdk/make/data/cryptopolicy/unlimited/default_US_export.policy b/jdk/src/java.base/share/conf/security/policy/limited/default_US_export.policy similarity index 76% rename from jdk/make/data/cryptopolicy/unlimited/default_US_export.policy rename to jdk/src/java.base/share/conf/security/policy/limited/default_US_export.policy index 67d0acc47a3..1f389340585 100644 --- a/jdk/make/data/cryptopolicy/unlimited/default_US_export.policy +++ b/jdk/src/java.base/share/conf/security/policy/limited/default_US_export.policy @@ -1,4 +1,5 @@ -// Manufacturing policy file. +// Default US Export policy file. + grant { // There is no restriction to any algorithms. permission javax.crypto.CryptoAllPermission; diff --git a/jdk/make/data/cryptopolicy/limited/default_local.policy b/jdk/src/java.base/share/conf/security/policy/limited/default_local.policy similarity index 100% rename from jdk/make/data/cryptopolicy/limited/default_local.policy rename to jdk/src/java.base/share/conf/security/policy/limited/default_local.policy diff --git a/jdk/make/data/cryptopolicy/limited/exempt_local.policy b/jdk/src/java.base/share/conf/security/policy/limited/exempt_local.policy similarity index 76% rename from jdk/make/data/cryptopolicy/limited/exempt_local.policy rename to jdk/src/java.base/share/conf/security/policy/limited/exempt_local.policy index f3255a2d970..9dd5b91b06d 100644 --- a/jdk/make/data/cryptopolicy/limited/exempt_local.policy +++ b/jdk/src/java.base/share/conf/security/policy/limited/exempt_local.policy @@ -1,5 +1,5 @@ -// Some countries have import limits on crypto strength. So this file -// will be useful. +// Some countries have import limits on crypto strength, but may allow for +// these exemptions if the exemption mechanism is used. grant { // There is no restriction to any algorithms if KeyRecovery is enforced. diff --git a/jdk/src/java.base/share/conf/security/policy/unlimited/default_US_export.policy b/jdk/src/java.base/share/conf/security/policy/unlimited/default_US_export.policy new file mode 100644 index 00000000000..1f389340585 --- /dev/null +++ b/jdk/src/java.base/share/conf/security/policy/unlimited/default_US_export.policy @@ -0,0 +1,6 @@ +// Default US Export policy file. + +grant { + // There is no restriction to any algorithms. + permission javax.crypto.CryptoAllPermission; +}; diff --git a/jdk/make/data/cryptopolicy/unlimited/default_local.policy b/jdk/src/java.base/share/conf/security/policy/unlimited/default_local.policy similarity index 99% rename from jdk/make/data/cryptopolicy/unlimited/default_local.policy rename to jdk/src/java.base/share/conf/security/policy/unlimited/default_local.policy index 8dc9702e9da..2b907e25895 100644 --- a/jdk/make/data/cryptopolicy/unlimited/default_local.policy +++ b/jdk/src/java.base/share/conf/security/policy/unlimited/default_local.policy @@ -1,4 +1,5 @@ // Country-specific policy file for countries with no limits on crypto strength. + grant { // There is no restriction to any algorithms. permission javax.crypto.CryptoAllPermission; diff --git a/jdk/src/java.base/share/lib/security/default.policy b/jdk/src/java.base/share/lib/security/default.policy index 318bd8bb2ab..f57e67fb482 100644 --- a/jdk/src/java.base/share/lib/security/default.policy +++ b/jdk/src/java.base/share/lib/security/default.policy @@ -72,6 +72,8 @@ grant codeBase "jrt:/java.xml.crypto" { "removeProviderProperty.XMLDSig"; permission java.security.SecurityPermission "com.sun.org.apache.xml.internal.security.register"; + permission java.security.SecurityPermission + "getProperty.jdk.xml.dsig.secureValidationPolicy"; }; grant codeBase "jrt:/java.xml.ws" { diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java index 8382c8cdfe8..1bcee895514 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java @@ -252,6 +252,21 @@ class UnixPath implements Path { return new UnixPath(getFileSystem(), new byte[0]); } + + // return true if this path has "." or ".." + private boolean hasDotOrDotDot() { + int n = getNameCount(); + for (int i=0; i cn) ? cn : bn; + int n = Math.min(baseCount, childCount); int i = 0; while (i < n) { - if (!this.getName(i).equals(other.getName(i))) + if (!base.getName(i).equals(child.getName(i))) break; i++; } - int dotdots = bn - i; - if (i < cn) { - // remaining name components in other - UnixPath remainder = other.subpath(i, cn); - if (dotdots == 0) - return remainder; - - // other is the empty path - boolean isOtherEmpty = other.isEmpty(); - - // result is a "../" for each remaining name in base - // followed by the remaining names in other. If the remainder is - // the empty path then we don't add the final trailing slash. - int len = dotdots*3 + remainder.path.length; - if (isOtherEmpty) { - assert remainder.isEmpty(); - len--; - } - byte[] result = new byte[len]; - int pos = 0; - while (dotdots > 0) { - result[pos++] = (byte)'.'; - result[pos++] = (byte)'.'; - if (isOtherEmpty) { - if (dotdots > 1) result[pos++] = (byte)'/'; - } else { - result[pos++] = (byte)'/'; - } - dotdots--; - } - System.arraycopy(remainder.path, 0, result, pos, remainder.path.length); - return new UnixPath(getFileSystem(), result); + // remaining elements in child + UnixPath childRemaining; + boolean isChildEmpty; + if (i == childCount) { + childRemaining = emptyPath(); + isChildEmpty = true; } else { - // no remaining names in other so result is simply a sequence of ".." - byte[] result = new byte[dotdots*3 - 1]; - int pos = 0; - while (dotdots > 0) { - result[pos++] = (byte)'.'; - result[pos++] = (byte)'.'; - // no tailing slash at the end - if (dotdots > 1) - result[pos++] = (byte)'/'; - dotdots--; - } - return new UnixPath(getFileSystem(), result); + childRemaining = child.subpath(i, childCount); + isChildEmpty = childRemaining.isEmpty(); } + + // matched all of base + if (i == baseCount) { + return childRemaining; + } + + // the remainder of base cannot contain ".." + UnixPath baseRemaining = base.subpath(i, baseCount); + if (baseRemaining.hasDotOrDotDot()) { + throw new IllegalArgumentException("Unable to compute relative " + + " path from " + this + " to " + obj); + } + if (baseRemaining.isEmpty()) + return childRemaining; + + // number of ".." needed + int dotdots = baseRemaining.getNameCount(); + if (dotdots == 0) { + return childRemaining; + } + + // result is a "../" for each remaining name in base followed by the + // remaining names in child. If the remainder is the empty path + // then we don't add the final trailing slash. + int len = dotdots*3 + childRemaining.path.length; + if (isChildEmpty) { + assert childRemaining.isEmpty(); + len--; + } + byte[] result = new byte[len]; + int pos = 0; + while (dotdots > 0) { + result[pos++] = (byte)'.'; + result[pos++] = (byte)'.'; + if (isChildEmpty) { + if (dotdots > 1) result[pos++] = (byte)'/'; + } else { + result[pos++] = (byte)'/'; + } + dotdots--; + } + System.arraycopy(childRemaining.path,0, result, pos, + childRemaining.path.length); + return new UnixPath(getFileSystem(), result); } @Override - public Path normalize() { + public UnixPath normalize() { final int count = getNameCount(); if (count == 0 || isEmpty()) return this; diff --git a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java index b27f663de35..f4d70f94ad5 100644 --- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java +++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java @@ -375,57 +375,108 @@ class WindowsPath implements Path { return (WindowsPath)path; } + // return true if this path has "." or ".." + private boolean hasDotOrDotDot() { + int n = getNameCount(); + for (int i=0; i cn) ? cn : bn; + int n = Math.min(baseCount, childCount); int i = 0; while (i < n) { - if (!this.getName(i).equals(other.getName(i))) + if (!base.getName(i).equals(child.getName(i))) break; i++; } - // append ..\ for remaining names in the base + // remaining elements in child + WindowsPath childRemaining; + boolean isChildEmpty; + if (i == childCount) { + childRemaining = emptyPath(); + isChildEmpty = true; + } else { + childRemaining = child.subpath(i, childCount); + isChildEmpty = childRemaining.isEmpty(); + } + + // matched all of base + if (i == baseCount) { + return childRemaining; + } + + // the remainder of base cannot contain ".." + WindowsPath baseRemaining = base.subpath(i, baseCount); + if (baseRemaining.hasDotOrDotDot()) { + throw new IllegalArgumentException("Unable to compute relative " + + " path from " + this + " to " + obj); + } + if (baseRemaining.isEmpty()) + return childRemaining; + + // number of ".." needed + int dotdots = baseRemaining.getNameCount(); + if (dotdots == 0) { + return childRemaining; + } + StringBuilder result = new StringBuilder(); - for (int j=i; j>> KDCCommunication: kdc=" + kdc + if (DEBUG) { + System.out.println(">>> KDCCommunication: kdc=" + kdc + " " + proto + ":" + port + ", timeout=" + timeout + ",Attempt =" + i + ", #bytes=" + obuf.length); + } + try (NetClient kdcClient = NetClient.getInstance( + proto, kdc, port, timeout)) { + kdcClient.send(obuf); + ibuf = kdcClient.receive(); + break; + } catch (SocketTimeoutException se) { + if (DEBUG) { + System.out.println ("SocketTimeOutException with " + + "attempt: " + i); } - try { - /* - * Send the data to the kdc. - */ - kdcClient.send(obuf); - /* - * And get a response. - */ - ibuf = kdcClient.receive(); - break; - } catch (SocketTimeoutException se) { - if (DEBUG) { - System.out.println ("SocketTimeOutException with " + - "attempt: " + i); - } - if (i == retries) { - ibuf = null; - throw se; - } + if (i == retries) { + ibuf = null; + throw se; } } } diff --git a/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java b/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java index 1f938621a31..b86e5be0fb7 100644 --- a/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java +++ b/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3204,7 +3204,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * this method is called on a closed CallableStatement * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method - * @since 1.4 */ public void setNull(String parameterName, int sqlType) throws SQLException { throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3240,7 +3239,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * this method is called on a closed CallableStatement * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method - * @since 1.4 */ public void setNull (String parameterName, int sqlType, String typeName) throws SQLException{ @@ -3259,7 +3257,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setBoolean(String parameterName, boolean x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3277,7 +3274,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setByte(String parameterName, byte x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3295,7 +3291,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setShort(String parameterName, short x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3313,7 +3308,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setInt(String parameterName, int x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3332,7 +3326,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setLong(String parameterName, long x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3350,7 +3343,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setFloat(String parameterName, float x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3368,7 +3360,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setDouble(String parameterName, double x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3387,7 +3378,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3408,7 +3398,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setString(String parameterName, String x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3428,7 +3417,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setBytes(String parameterName, byte x[]) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -3447,7 +3435,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setTimestamp(String parameterName, java.sql.Timestamp x) throws SQLException{ @@ -3474,7 +3461,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * this method is called on a closed CallableStatement * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method - * @since 1.4 */ public void setAsciiStream(String parameterName, java.io.InputStream x, int length) throws SQLException{ @@ -3500,7 +3486,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * this method is called on a closed CallableStatement * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method - * @since 1.4 */ public void setBinaryStream(String parameterName, java.io.InputStream x, int length) throws SQLException{ @@ -3528,7 +3513,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * this method is called on a closed CallableStatement * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method - * @since 1.4 */ public void setCharacterStream(String parameterName, java.io.Reader reader, @@ -3684,7 +3668,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * this data type * @see Types * @see #getParams - * @since 1.4 */ public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException{ @@ -3710,7 +3693,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * or STRUCT data type and the JDBC driver does not support * this data type * @see #getParams - * @since 1.4 */ public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException{ @@ -3751,7 +3733,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setObject(String parameterName, Object x) throws SQLException{ throw new SQLFeatureNotSupportedException("Feature not supported"); @@ -4024,7 +4005,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setDate(String parameterName, java.sql.Date x) throws SQLException { @@ -4050,7 +4030,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setDate(String parameterName, java.sql.Date x, Calendar cal) throws SQLException { @@ -4069,7 +4048,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setTime(String parameterName, java.sql.Time x) throws SQLException { @@ -4095,7 +4073,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setTime(String parameterName, java.sql.Time x, Calendar cal) throws SQLException { @@ -4121,7 +4098,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @see #getParams - * @since 1.4 */ public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal) throws SQLException { @@ -4459,7 +4435,6 @@ public abstract class BaseRowSet implements Serializable, Cloneable { * @exception SQLException if a database access error occurs or * this method is called on a closed PreparedStatement * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method - * @since 1.4 */ public void setURL(int parameterIndex, java.net.URL x) throws SQLException { throw new SQLFeatureNotSupportedException("Feature not supported"); diff --git a/jdk/src/java.sql/share/classes/javax/sql/CommonDataSource.java b/jdk/src/java.sql/share/classes/javax/sql/CommonDataSource.java index 006560cbe38..160c432474d 100644 --- a/jdk/src/java.sql/share/classes/javax/sql/CommonDataSource.java +++ b/jdk/src/java.sql/share/classes/javax/sql/CommonDataSource.java @@ -57,7 +57,6 @@ public interface CommonDataSource { * logging is disabled * @exception java.sql.SQLException if a database access error occurs * @see #setLogWriter - * @since 1.4 */ java.io.PrintWriter getLogWriter() throws SQLException; @@ -79,7 +78,6 @@ public interface CommonDataSource { * @param out the new log writer; to disable logging, set to null * @exception SQLException if a database access error occurs * @see #getLogWriter - * @since 1.4 */ void setLogWriter(java.io.PrintWriter out) throws SQLException; @@ -94,7 +92,6 @@ public interface CommonDataSource { * @param seconds the data source login time limit * @exception SQLException if a database access error occurs. * @see #getLoginTimeout - * @since 1.4 */ void setLoginTimeout(int seconds) throws SQLException; @@ -109,7 +106,6 @@ public interface CommonDataSource { * @return the data source login time limit * @exception SQLException if a database access error occurs. * @see #setLoginTimeout - * @since 1.4 */ int getLoginTimeout() throws SQLException; diff --git a/jdk/src/java.sql/share/classes/javax/sql/ConnectionPoolDataSource.java b/jdk/src/java.sql/share/classes/javax/sql/ConnectionPoolDataSource.java index 08ae5611a31..54a97b184c9 100644 --- a/jdk/src/java.sql/share/classes/javax/sql/ConnectionPoolDataSource.java +++ b/jdk/src/java.sql/share/classes/javax/sql/ConnectionPoolDataSource.java @@ -72,6 +72,34 @@ public interface ConnectionPoolDataSource extends CommonDataSource { PooledConnection getPooledConnection(String user, String password) throws SQLException; + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + java.io.PrintWriter getLogWriter() throws SQLException; + + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + void setLogWriter(java.io.PrintWriter out) throws SQLException; + + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + void setLoginTimeout(int seconds) throws SQLException; + + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + int getLoginTimeout() throws SQLException; + //------------------------- JDBC 4.3 ----------------------------------- /** diff --git a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java index 4c3274d22d9..276a6051fe8 100644 --- a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java +++ b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java @@ -109,6 +109,34 @@ public interface DataSource extends CommonDataSource, Wrapper { Connection getConnection(String username, String password) throws SQLException; + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + java.io.PrintWriter getLogWriter() throws SQLException; + + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + void setLogWriter(java.io.PrintWriter out) throws SQLException; + + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + void setLoginTimeout(int seconds) throws SQLException; + + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + int getLoginTimeout() throws SQLException; + // JDBC 4.3 /** diff --git a/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java b/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java index 83656b205c8..0882a7de9e3 100644 --- a/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java +++ b/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java @@ -81,7 +81,35 @@ public interface XADataSource extends CommonDataSource { XAConnection getXAConnection(String user, String password) throws SQLException; - // JDBC 4.3 + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + java.io.PrintWriter getLogWriter() throws SQLException; + + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + void setLogWriter(java.io.PrintWriter out) throws SQLException; + + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + void setLoginTimeout(int seconds) throws SQLException; + + /** + * {@inheritDoc} + * @since 1.4 + */ + @Override + int getLoginTimeout() throws SQLException; + + // JDBC 4.3 /** * Creates a new {@code XAConnectionBuilder} instance diff --git a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java index 8935e389728..94eae3b772e 100644 --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java @@ -150,7 +150,7 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { this.macAlgorithm.init(secretKey); } catch (InvalidKeyException ex) { // reinstantiate Mac object to work around bug in JDK - // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 + // see: http://bugs.java.com/view_bug.do?bug_id=4953555 Mac mac = this.macAlgorithm; try { this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm()); diff --git a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java index 7460f66ffd6..f7d169572e2 100644 --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java @@ -112,7 +112,7 @@ public abstract class SignatureBaseRSA extends SignatureAlgorithmSpi { this.signatureAlgorithm.initVerify((PublicKey) publicKey); } catch (InvalidKeyException ex) { // reinstantiate Signature object to work around bug in JDK - // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 + // see: http://bugs.java.com/view_bug.do?bug_id=4953555 Signature sig = this.signatureAlgorithm; try { this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm()); diff --git a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java index 7a771d71beb..6638e9293e4 100644 --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java @@ -139,7 +139,7 @@ public class SignatureDSA extends SignatureAlgorithmSpi { this.signatureAlgorithm.initVerify((PublicKey) publicKey); } catch (InvalidKeyException ex) { // reinstantiate Signature object to work around bug in JDK - // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 + // see: http://bugs.java.com/view_bug.do?bug_id=4953555 Signature sig = this.signatureAlgorithm; try { this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm()); diff --git a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java index 8da7a8c6e67..7ba65724fb0 100644 --- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java +++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java @@ -252,7 +252,7 @@ public abstract class SignatureECDSA extends SignatureAlgorithmSpi { this.signatureAlgorithm.initVerify((PublicKey) publicKey); } catch (InvalidKeyException ex) { // reinstantiate Signature object to work around bug in JDK - // see: http://bugs.sun.com/view_bug.do?bug_id=4953555 + // see: http://bugs.java.com/view_bug.do?bug_id=4953555 Signature sig = this.signatureAlgorithm; try { this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm()); diff --git a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java index 3cad0fd6f0c..c053df02a7f 100644 --- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java +++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. */ /* * $Id: ApacheTransform.java 1333869 2012-05-04 10:42:44Z coheigea $ @@ -38,7 +38,6 @@ import org.w3c.dom.Node; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.transforms.Transform; -import com.sun.org.apache.xml.internal.security.transforms.Transforms; import javax.xml.crypto.*; import javax.xml.crypto.dom.DOMCryptoContext; @@ -150,7 +149,7 @@ public abstract class ApacheTransform extends TransformService { if (Utils.secureValidation(xc)) { String algorithm = getAlgorithm(); - if (Transforms.TRANSFORM_XSLT.equals(algorithm)) { + if (Policy.restrictAlg(algorithm)) { throw new TransformException( "Transform " + algorithm + " is forbidden when secure validation is enabled" ); diff --git a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java index 2c86d8f65ee..69a2a3371c8 100644 --- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java +++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. */ /* * $Id: DOMManifest.java 1333415 2012-05-03 12:03:51Z coheigea $ @@ -110,9 +110,10 @@ public final class DOMManifest extends DOMStructure implements Manifest { localName + ", expected Reference"); } refs.add(new DOMReference(refElem, context, provider)); - if (secVal && (refs.size() > DOMSignedInfo.MAXIMUM_REFERENCE_COUNT)) { - String error = "A maxiumum of " + DOMSignedInfo.MAXIMUM_REFERENCE_COUNT + " " - + "references per Manifest are allowed with secure validation"; + if (secVal && Policy.restrictNumReferences(refs.size())) { + String error = "A maximum of " + Policy.maxReferences() + + " references per Manifest are allowed when" + + " secure validation is enabled"; throw new MarshalException(error); } refElem = DOMUtils.getNextSiblingElement(refElem); diff --git a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java index 91f9054657a..7e2f33129db 100644 --- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java +++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. */ /* * =========================================================================== @@ -51,7 +51,6 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; import org.jcp.xml.dsig.internal.DigesterOutputStream; -import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm; import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.utils.Base64; @@ -66,11 +65,6 @@ import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream public final class DOMReference extends DOMStructure implements Reference, DOMURIReference { - /** - * The maximum number of transforms per reference, if secure validation is enabled. - */ - public static final int MAXIMUM_TRANSFORM_COUNT = 5; - /** * Look up useC14N11 system property. If true, an explicit C14N11 transform * will be added if necessary when generating the signature. See section @@ -208,9 +202,10 @@ public final class DOMReference extends DOMStructure } transforms.add (new DOMTransform(transformElem, context, provider)); - if (secVal && (transforms.size() > MAXIMUM_TRANSFORM_COUNT)) { - String error = "A maxiumum of " + MAXIMUM_TRANSFORM_COUNT + " " - + "transforms per Reference are allowed with secure validation"; + if (secVal && Policy.restrictNumTransforms(transforms.size())) { + String error = "A maximum of " + Policy.maxTransforms() + + " transforms per Reference are allowed when" + + " secure validation is enabled"; throw new MarshalException(error); } transformElem = DOMUtils.getNextSiblingElement(transformElem); @@ -227,10 +222,10 @@ public final class DOMReference extends DOMStructure Element dmElem = nextSibling; this.digestMethod = DOMDigestMethod.unmarshal(dmElem); String digestMethodAlgorithm = this.digestMethod.getAlgorithm(); - if (secVal - && MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5.equals(digestMethodAlgorithm)) { + if (secVal && Policy.restrictAlg(digestMethodAlgorithm)) { throw new MarshalException( - "It is forbidden to use algorithm " + digestMethod + " when secure validation is enabled" + "It is forbidden to use algorithm " + digestMethodAlgorithm + + " when secure validation is enabled" ); } diff --git a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java index eed6fffe5a5..d5ac8c16dbc 100644 --- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java +++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. */ /* * =========================================================================== @@ -149,9 +149,10 @@ public final class DOMRetrievalMethod extends DOMStructure } transforms.add (new DOMTransform(transformElem, context, provider)); - if (secVal && (transforms.size() > DOMReference.MAXIMUM_TRANSFORM_COUNT)) { - String error = "A maxiumum of " + DOMReference.MAXIMUM_TRANSFORM_COUNT + " " - + "transforms per Reference are allowed with secure validation"; + if (secVal && Policy.restrictNumTransforms(transforms.size())) { + String error = "A maximum of " + Policy.maxTransforms() + + " transforms per Reference are allowed when" + + " secure validation is enabled"; throw new MarshalException(error); } transformElem = DOMUtils.getNextSiblingElement(transformElem); @@ -238,7 +239,8 @@ public final class DOMRetrievalMethod extends DOMStructure } // guard against RetrievalMethod loops - if ((data instanceof NodeSetData) && Utils.secureValidation(context)) { + if ((data instanceof NodeSetData) && Utils.secureValidation(context) + && Policy.restrictRetrievalMethodLoops()) { NodeSetData nsd = (NodeSetData)data; Iterator i = nsd.iterator(); if (i.hasNext()) { diff --git a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java index c18a462fba7..17043b4c165 100644 --- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java +++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. */ /* * $Id: DOMSignedInfo.java 1333415 2012-05-03 12:03:51Z coheigea $ @@ -45,7 +45,6 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; import com.sun.org.apache.xml.internal.security.utils.Base64; -import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream; /** @@ -55,22 +54,9 @@ import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream */ public final class DOMSignedInfo extends DOMStructure implements SignedInfo { - /** - * The maximum number of references per Manifest, if secure validation is enabled. - */ - public static final int MAXIMUM_REFERENCE_COUNT = 30; - private static java.util.logging.Logger log = java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom"); - /** Signature - NOT Recommended RSAwithMD5 */ - private static final String ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5 = - Constants.MoreAlgorithmsSpecNS + "rsa-md5"; - - /** HMAC - NOT Recommended HMAC-MD5 */ - private static final String ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5 = - Constants.MoreAlgorithmsSpecNS + "hmac-md5"; - private List references; private CanonicalizationMethod canonicalizationMethod; private SignatureMethod signatureMethod; @@ -158,10 +144,10 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo { boolean secVal = Utils.secureValidation(context); String signatureMethodAlgorithm = signatureMethod.getAlgorithm(); - if (secVal && ((ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5.equals(signatureMethodAlgorithm) - || ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5.equals(signatureMethodAlgorithm)))) { + if (secVal && Policy.restrictAlg(signatureMethodAlgorithm)) { throw new MarshalException( - "It is forbidden to use algorithm " + signatureMethod + " when secure validation is enabled" + "It is forbidden to use algorithm " + signatureMethodAlgorithm + + " when secure validation is enabled" ); } @@ -179,9 +165,10 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo { } refList.add(new DOMReference(refElem, context, provider)); - if (secVal && (refList.size() > MAXIMUM_REFERENCE_COUNT)) { - String error = "A maxiumum of " + MAXIMUM_REFERENCE_COUNT + " " - + "references per Manifest are allowed with secure validation"; + if (secVal && Policy.restrictNumReferences(refList.size())) { + String error = "A maximum of " + Policy.maxReferences() + + " references per Manifest are allowed when" + + " secure validation is enabled"; throw new MarshalException(error); } refElem = DOMUtils.getNextSiblingElement(refElem); diff --git a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java index d2beb4e50a6..72791df3a2a 100644 --- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java +++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. */ /* * $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $ @@ -73,6 +73,11 @@ public class DOMURIDereferencer implements URIDereferencer { boolean secVal = Utils.secureValidation(context); + if (secVal && Policy.restrictReferenceUriScheme(uri)) { + throw new URIReferenceException( + "Uri " + uri + " is forbidden when secure validation is enabled"); + } + // Check if same-document URI and already registered on the context if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') { String id = uri.substring(1); @@ -83,12 +88,19 @@ public class DOMURIDereferencer implements URIDereferencer { id = id.substring(i1+1, i2); } - Node referencedElem = dcc.getElementById(id); + // check if element is registered by Id + Node referencedElem = uriAttr.getOwnerDocument().getElementById(id); + if (referencedElem == null) { + // see if element is registered in DOMCryptoContext + referencedElem = dcc.getElementById(id); + } if (referencedElem != null) { - if (secVal) { + if (secVal && Policy.restrictDuplicateIds()) { Element start = referencedElem.getOwnerDocument().getDocumentElement(); if (!XMLUtils.protectAgainstWrappingAttack(start, (Element)referencedElem, id)) { - String error = "Multiple Elements with the same ID " + id + " were detected"; + String error = "Multiple Elements with the same ID " + + id + " detected when secure validation" + + " is enabled"; throw new URIReferenceException(error); } } @@ -110,9 +122,9 @@ public class DOMURIDereferencer implements URIDereferencer { try { ResourceResolver apacheResolver = - ResourceResolver.getInstance(uriAttr, baseURI, secVal); + ResourceResolver.getInstance(uriAttr, baseURI, false); XMLSignatureInput in = apacheResolver.resolve(uriAttr, - baseURI, secVal); + baseURI, false); if (in.isOctetStream()) { return new ApacheOctetStreamData(in); } else { diff --git a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java new file mode 100644 index 00000000000..af9bea40876 --- /dev/null +++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.jcp.xml.dsig.internal.dom; + +import java.net.URI; +import java.net.URISyntaxException; +import java.security.AccessController; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.Security; +import java.util.Collections; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +/** + * The secure validation policy as specified by the + * jdk.xml.dsig.secureValidationPolicy security property. + */ +public final class Policy { + + // all restrictions are initialized to be unconstrained + private static Set disallowedAlgs = new HashSet<>(); + private static int maxTrans = Integer.MAX_VALUE; + private static int maxRefs = Integer.MAX_VALUE; + private static Set disallowedRefUriSchemes = new HashSet<>(); + private static boolean noDuplicateIds = false; + private static boolean noRMLoops = false; + + static { + try { + initialize(); + } catch (Exception e) { + throw new SecurityException( + "Cannot initialize the secure validation policy", e); + } + } + + private Policy() {} + + private static void initialize() { + String prop = + AccessController.doPrivileged((PrivilegedAction) () -> + Security.getProperty("jdk.xml.dsig.secureValidationPolicy")); + if (prop == null || prop.isEmpty()) { + // no policy specified, so don't enforce any restrictions + return; + } + String[] entries = prop.split(","); + for (String entry : entries) { + String[] tokens = entry.split("\\s"); + String type = tokens[0]; + switch(type) { + case "disallowAlg": + if (tokens.length != 2) { + error(entry); + } + disallowedAlgs.add(URI.create(tokens[1])); + break; + case "maxTransforms": + if (tokens.length != 2) { + error(entry); + } + maxTrans = Integer.parseUnsignedInt(tokens[1]); + break; + case "maxReferences": + if (tokens.length != 2) { + error(entry); + } + maxRefs = Integer.parseUnsignedInt(tokens[1]); + break; + case "disallowReferenceUriSchemes": + if (tokens.length == 1) { + error(entry); + } + for (int i = 1; i < tokens.length; i++) { + String scheme = tokens[i]; + disallowedRefUriSchemes.add( + scheme.toLowerCase(Locale.ROOT)); + } + break; + case "noDuplicateIds": + if (tokens.length != 1) { + error(entry); + } + noDuplicateIds = true; + break; + case "noRetrievalMethodLoops": + if (tokens.length != 1) { + error(entry); + } + noRMLoops = true; + break; + default: + error(entry); + } + } + } + + public static boolean restrictAlg(String alg) { + try { + URI uri = new URI(alg); + return disallowedAlgs.contains(uri); + } catch (URISyntaxException use) { + return false; + } + } + + public static boolean restrictNumTransforms(int numTrans) { + return (numTrans > maxTrans); + } + + public static boolean restrictNumReferences(int numRefs) { + return (numRefs > maxRefs); + } + + public static boolean restrictReferenceUriScheme(String uri) { + if (uri != null) { + String scheme = java.net.URI.create(uri).getScheme(); + if (scheme != null) { + return disallowedRefUriSchemes.contains( + scheme.toLowerCase(Locale.ROOT)); + } + } + return false; + } + + public static boolean restrictDuplicateIds() { + return noDuplicateIds; + } + + public static boolean restrictRetrievalMethodLoops() { + return noRMLoops; + } + + public static Set disabledAlgs() { + return Collections.unmodifiableSet(disallowedAlgs); + } + + public static int maxTransforms() { + return maxTrans; + } + + public static int maxReferences() { + return maxRefs; + } + + public static Set disabledReferenceUriSchemes() { + return Collections.unmodifiableSet(disallowedRefUriSchemes); + } + + private static void error(String entry) { + throw new IllegalArgumentException( + "Invalid jdk.xml.dsig.secureValidationPolicy entry: " + entry); + } +} diff --git a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11RSACipher.java b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11RSACipher.java index 58a4e2f545d..164ae0c6c02 100644 --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11RSACipher.java +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11RSACipher.java @@ -358,7 +358,9 @@ final class P11RSACipher extends CipherSpi { System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs); tmpBuffer = p11.C_Sign(session.id(), tmpBuffer); if (tmpBuffer.length > outLen) { - throw new BadPaddingException("Output buffer too small"); + throw new BadPaddingException( + "Output buffer (" + outLen + ") is too small to " + + "hold the produced data (" + tmpBuffer.length + ")"); } System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length); n = tmpBuffer.length; diff --git a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c index f102baa64bf..87d34543731 100644 --- a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c +++ b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c @@ -558,7 +558,7 @@ void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy); if (pCharArray == NULL) { return; } - *ckpLength = strlen(pCharArray); + *ckpLength = (CK_ULONG) strlen(pCharArray); *ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR)); if (*ckpArray == NULL) { (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray); diff --git a/jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c b/jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c index 225263247db..d5154eff606 100644 --- a/jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c +++ b/jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,7 @@ void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) { JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle (JNIEnv *env, jclass thisClass, jstring jLibName) { + void *hModule; const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL); if (libName == NULL) { return 0L; @@ -56,9 +57,9 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle // look up existing handle only, do not load #if defined(AIX) - void *hModule = dlopen(libName, RTLD_LAZY); + hModule = dlopen(libName, RTLD_LAZY); #else - void *hModule = dlopen(libName, RTLD_NOLOAD); + hModule = dlopen(libName, RTLD_NOLOAD); #endif dprintf2("-handle for %s: %u\n", libName, hModule); (*env)->ReleaseStringUTFChars(env, jLibName, libName); diff --git a/jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.c b/jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.c index 33b11bfd07e..6e983ce158f 100644 --- a/jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.c +++ b/jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.c @@ -31,6 +31,9 @@ #include "j2secmod.h" +extern void throwNullPointerException(JNIEnv *env, const char *message); +extern void throwIOException(JNIEnv *env, const char *message); + void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) { HINSTANCE hModule = (HINSTANCE)jHandle; void *fAddress = GetProcAddress(hModule, functionName); diff --git a/jdk/src/jdk.internal.opt/share/classes/module-info.java b/jdk/src/jdk.internal.opt/share/classes/module-info.java index 9c8f889adf2..dc5d39b6453 100644 --- a/jdk/src/jdk.internal.opt/share/classes/module-info.java +++ b/jdk/src/jdk.internal.opt/share/classes/module-info.java @@ -24,5 +24,5 @@ */ module jdk.internal.opt { - exports jdk.internal.joptsimple to jdk.jlink; + exports jdk.internal.joptsimple to jdk.jlink, jdk.jshell; } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java index 1b37140ed55..aaccb4269a0 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java @@ -78,28 +78,21 @@ public final class DefaultImageBuilder implements ImageBuilder { private final List args; private final Set modules; - public DefaultExecutableImage(Path home, Set modules) { - this(home, modules, createArgs(home)); - } - - private DefaultExecutableImage(Path home, Set modules, - List args) { + DefaultExecutableImage(Path home, Set modules) { Objects.requireNonNull(home); - Objects.requireNonNull(args); if (!Files.exists(home)) { throw new IllegalArgumentException("Invalid image home"); } this.home = home; this.modules = Collections.unmodifiableSet(modules); - this.args = Collections.unmodifiableList(args); + this.args = createArgs(home); } private static List createArgs(Path home) { Objects.requireNonNull(home); - List javaArgs = new ArrayList<>(); - javaArgs.add(home.resolve("bin"). - resolve(getJavaProcessName()).toString()); - return javaArgs; + Path binDir = home.resolve("bin"); + String java = Files.exists(binDir.resolve("java"))? "java" : "java.exe"; + return List.of(binDir.resolve(java).toString()); } @Override @@ -130,6 +123,7 @@ public final class DefaultImageBuilder implements ImageBuilder { private final Path root; private final Path mdir; private final Set modules = new HashSet<>(); + private String targetOsName; /** * Default image builder constructor. @@ -171,6 +165,11 @@ public final class DefaultImageBuilder implements ImageBuilder { @Override public void storeFiles(ResourcePool files) { try { + // populate release properties up-front. targetOsName + // field is assigned from there and used elsewhere. + Properties release = releaseProperties(files); + Path bin = root.resolve("bin"); + files.entries().forEach(f -> { if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) { try { @@ -186,11 +185,11 @@ public final class DefaultImageBuilder implements ImageBuilder { modules.add(m.name()); } }); - storeFiles(modules, releaseProperties(files)); + + storeFiles(modules, release); if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) { // launchers in the bin directory need execute permission - Path bin = root.resolve("bin"); if (Files.isDirectory(bin)) { Files.list(bin) .filter(f -> !f.toString().endsWith(".diz")) @@ -208,7 +207,11 @@ public final class DefaultImageBuilder implements ImageBuilder { } } - prepareApplicationFiles(files, modules); + // If native files are stripped completely, /bin dir won't exist! + // So, don't bother generating launcher scripts. + if (Files.isDirectory(bin)) { + prepareApplicationFiles(files, modules); + } } catch (IOException ex) { throw new PluginException(ex); } @@ -226,6 +229,11 @@ public final class DefaultImageBuilder implements ImageBuilder { props.setProperty("JAVA_VERSION", System.getProperty("java.version")); }); + this.targetOsName = props.getProperty("OS_NAME"); + if (this.targetOsName == null) { + throw new PluginException("TargetPlatform attribute is missing for java.base module"); + } + Optional release = pool.findEntry("/java.base/release"); if (release.isPresent()) { try (InputStream is = release.get().content()) { @@ -373,7 +381,7 @@ public final class DefaultImageBuilder implements ImageBuilder { Files.createLink(dstFile, target); } - private static String nativeDir(String filename) { + private String nativeDir(String filename) { if (isWindows()) { if (filename.endsWith(".dll") || filename.endsWith(".diz") || filename.endsWith(".pdb") || filename.endsWith(".map")) { @@ -386,8 +394,8 @@ public final class DefaultImageBuilder implements ImageBuilder { } } - private static boolean isWindows() { - return System.getProperty("os.name").startsWith("Windows"); + private boolean isWindows() { + return targetOsName.startsWith("Windows"); } /** @@ -452,12 +460,10 @@ public final class DefaultImageBuilder implements ImageBuilder { } } - private static String getJavaProcessName() { - return isWindows() ? "java.exe" : "java"; - } - public static ExecutableImage getExecutableImage(Path root) { - if (Files.exists(root.resolve("bin").resolve(getJavaProcessName()))) { + Path binDir = root.resolve("bin"); + if (Files.exists(binDir.resolve("java")) || + Files.exists(binDir.resolve("java.exe"))) { return new DefaultExecutableImage(root, retrieveModules(root)); } return null; diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java index a0b91d33473..5ec8f67948f 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java @@ -172,7 +172,7 @@ public final class ImagePluginStack { private final Plugin lastSorter; private final List plugins = new ArrayList<>(); private final List resourcePrevisitors = new ArrayList<>(); - + private final boolean validate; public ImagePluginStack() { this(null, Collections.emptyList(), null); @@ -181,6 +181,13 @@ public final class ImagePluginStack { public ImagePluginStack(ImageBuilder imageBuilder, List plugins, Plugin lastSorter) { + this(imageBuilder, plugins, lastSorter, true); + } + + public ImagePluginStack(ImageBuilder imageBuilder, + List plugins, + Plugin lastSorter, + boolean validate) { this.imageBuilder = Objects.requireNonNull(imageBuilder); this.lastSorter = lastSorter; this.plugins.addAll(Objects.requireNonNull(plugins)); @@ -190,6 +197,7 @@ public final class ImagePluginStack { resourcePrevisitors.add((ResourcePrevisitor) p); } }); + this.validate = validate; } public void operate(ImageProvider provider) throws Exception { @@ -268,6 +276,7 @@ public final class ImagePluginStack { frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList(); } } + return resPool; } @@ -458,7 +467,11 @@ public final class ImagePluginStack { throws Exception { Objects.requireNonNull(original); Objects.requireNonNull(transformed); - imageBuilder.storeFiles(new LastPoolManager(transformed).resourcePool()); + ResourcePool lastPool = new LastPoolManager(transformed).resourcePool(); + if (validate) { + ResourcePoolConfiguration.validate(lastPool); + } + imageBuilder.storeFiles(lastPool); } public ExecutableImage getExecutableImage() throws IOException { diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PathResourcePoolEntry.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PathResourcePoolEntry.java index 7b7cba3575e..e7c0c87a5ff 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PathResourcePoolEntry.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PathResourcePoolEntry.java @@ -5,7 +5,7 @@ * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classfile" exception as provided + * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java new file mode 100644 index 00000000000..11af53af6c1 --- /dev/null +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.tools.jlink.internal; + +import java.lang.module.Configuration; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleFinder; +import java.lang.module.ModuleReference; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import jdk.tools.jlink.plugin.PluginException; +import jdk.tools.jlink.plugin.ResourcePool; +import jdk.tools.jlink.plugin.ResourcePoolEntry; +import jdk.tools.jlink.plugin.ResourcePoolModule; + +final class ResourcePoolConfiguration { + private ResourcePoolConfiguration() {} + + private static ModuleDescriptor descriptorOf(ResourcePoolModule mod) { + ModuleDescriptor md = mod.descriptor(); + + // drop hashes + ModuleDescriptor.Builder builder = new ModuleDescriptor.Builder(md.name()); + md.requires().stream() + .forEach(builder::requires); + md.exports().stream() + .forEach(builder::exports); + md.uses().stream() + .forEach(builder::uses); + md.provides().values().stream() + .forEach(builder::provides); + + // build the proper concealed packages + Set exps = md.exports().stream() + .map(ModuleDescriptor.Exports::source) + .collect(Collectors.toSet()); + + mod.packages().stream() + .filter(pn -> !exps.contains(pn)) + .forEach(builder::conceals); + + md.version().ifPresent(builder::version); + md.mainClass().ifPresent(builder::mainClass); + md.osName().ifPresent(builder::osName); + md.osArch().ifPresent(builder::osArch); + md.osVersion().ifPresent(builder::osVersion); + + return builder.build(); + } + + private static ModuleReference moduleReference(ModuleDescriptor desc) { + return new ModuleReference(desc, null, () -> { + IOException ioe = new IOException(""); + throw new UncheckedIOException(ioe); + }); + } + + private static Map allModRefs(ResourcePool pool) { + return pool.moduleView().modules(). + collect(Collectors.toMap(ResourcePoolModule::name, + m -> moduleReference(descriptorOf(m)))); + } + + private static void checkPackages(ResourcePool pool) { + // check that each resource pool module's packages() + // returns a set that is consistent with the module + // descriptor of that module. + + pool.moduleView().modules().forEach(m -> { + ModuleDescriptor desc = m.descriptor(); + if (!desc.packages().equals(m.packages())) { + throw new RuntimeException("Module " + m.name() + + "'s descriptor returns inconsistent package set"); + } + }); + } + + static Configuration validate(ResourcePool pool) { + checkPackages(pool); + final Map nameToModRef = allModRefs(pool); + final Set allRefs = new HashSet<>(nameToModRef.values()); + + final ModuleFinder finder = new ModuleFinder() { + @Override + public Optional find(String name) { + return Optional.ofNullable(nameToModRef.get(name)); + } + + @Override + public Set findAll() { + return allRefs; + } + }; + + return Configuration.empty().resolveRequires( + finder, ModuleFinder.of(), nameToModRef.keySet()); + } +} diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java index d59bc8a2341..a60a1e934b5 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java @@ -24,7 +24,11 @@ */ package jdk.tools.jlink.internal.plugins; +import java.io.File; +import java.io.IOException; import java.lang.invoke.MethodType; +import java.nio.file.Files; +import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; @@ -32,6 +36,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; import jdk.internal.misc.SharedSecrets; import jdk.internal.misc.JavaLangInvokeAccess; import jdk.tools.jlink.plugin.ResourcePoolEntry; @@ -47,15 +52,9 @@ public final class GenerateJLIClassesPlugin implements Plugin { private static final String NAME = "generate-jli-classes"; - private static final String BMH_PARAM = "bmh"; - - private static final String BMH_SPECIES_PARAM = "bmh-species"; - - private static final String DMH_PARAM = "dmh"; - private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME); - private static final String DIRECT_METHOD_HANDLE = "java/lang/invoke/DirectMethodHandle$Holder"; + private static final String DIRECT_HOLDER = "java/lang/invoke/DirectMethodHandle$Holder"; private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual"; private static final String DMH_INVOKE_STATIC = "invokeStatic"; private static final String DMH_INVOKE_SPECIAL = "invokeSpecial"; @@ -63,15 +62,17 @@ public final class GenerateJLIClassesPlugin implements Plugin { private static final String DMH_INVOKE_INTERFACE = "invokeInterface"; private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit"; - private static final String DELEGATING_METHOD_HANDLE = "java/lang/invoke/DelegatingMethodHandle$Holder"; - - private static final String BASIC_FORMS_HANDLE = "java/lang/invoke/LambdaForm$Holder"; + private static final String DELEGATING_HOLDER = "java/lang/invoke/DelegatingMethodHandle$Holder"; + private static final String BASIC_FORMS_HOLDER = "java/lang/invoke/LambdaForm$Holder"; + private static final String INVOKERS_HOLDER = "java/lang/invoke/Invokers$Holder"; private static final JavaLangInvokeAccess JLIA = SharedSecrets.getJavaLangInvokeAccess(); List speciesTypes; + List invokerTypes; + Map> dmhMethods; public GenerateJLIClassesPlugin() { @@ -116,22 +117,30 @@ public final class GenerateJLIClassesPlugin implements Plugin { "LILL", "I", "LLILL"); } + /** + * @return the default invoker forms to generate. + */ + private static List defaultInvokers() { + return List.of("LL_L", "LL_I", "LILL_I", "L6_L"); + } + /** * @return the list of default DirectMethodHandle methods to generate. */ - public static Map> defaultDMHMethods() { + private static Map> defaultDMHMethods() { return Map.of( - DMH_INVOKE_VIRTUAL, List.of("_L", "L_L", "LI_I", "LL_V"), - DMH_INVOKE_SPECIAL, List.of("L_I", "L_L", "LF_L", "LD_L", "LL_L", - "L3_L", "L4_L", "L5_L", "L6_L", "L7_L", "LI_I", "LI_L", "LIL_I", - "LII_I", "LII_L", "LLI_L", "LLI_I", "LILI_I", "LIIL_L", - "LIILL_L", "LIILL_I", "LIIL_I", "LILIL_I", "LILILL_I", - "LILII_I", "LI3_I", "LI3L_I", "LI3LL_I", "LI3_L", "LI4_I"), - DMH_INVOKE_STATIC, List.of("II_I", "IL_I", "ILIL_I", "ILII_I", - "_I", "_L", "_V", "D_L", "F_L", "I_I", "II_L", "LI_L", - "L_V", "L_L", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L", - "L7_L", "L8_L", "L9_L", "L9I_L", "L9II_L", "L9IIL_L", - "L10_L", "L11_L", "L12_L", "L13_L", "L13I_L", "L13II_L") + DMH_INVOKE_VIRTUAL, List.of("L_L", "LL_L", "LLI_I", "L3_V"), + DMH_INVOKE_SPECIAL, List.of("LL_I", "LL_L", "LLF_L", "LLD_L", "L3_L", + "L4_L", "L5_L", "L6_L", "L7_L", "L8_L", "LLI_I", "LLI_L", + "LLIL_I", "LLII_I", "LLII_L", "L3I_L", "L3I_I", "LLILI_I", + "LLIIL_L", "LLIILL_L", "LLIILL_I", "LLIIL_I", "LLILIL_I", + "LLILILL_I", "LLILII_I", "LLI3_I", "LLI3L_I", "LLI3LL_I", + "LLI3_L", "LLI4_I"), + DMH_INVOKE_STATIC, List.of("LII_I", "LIL_I", "LILIL_I", "LILII_I", + "L_I", "L_L", "L_V", "LD_L", "LF_L", "LI_I", "LII_L", "LLI_L", + "LL_V", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L", "L7_L", + "L8_L", "L9_L", "L10_L", "L10I_L", "L10II_L", "L10IIL_L", + "L11_L", "L12_L", "L13_L", "L14_L", "L14I_L", "L14II_L") ); } @@ -150,72 +159,91 @@ public final class GenerateJLIClassesPlugin implements Plugin { public void configure(Map config) { String mainArgument = config.get(NAME); - // Enable by default - boolean bmhEnabled = true; - boolean dmhEnabled = true; - if (mainArgument != null) { - List args = Arrays.asList(mainArgument.split(",")); - if (!args.contains(BMH_PARAM)) { - bmhEnabled = false; - } - if (!args.contains(DMH_PARAM)) { - dmhEnabled = false; - } - } + if (mainArgument != null && mainArgument.startsWith("@")) { + File file = new File(mainArgument.substring(1)); + if (file.exists()) { + speciesTypes = new ArrayList<>(); + invokerTypes = new ArrayList<>(); + dmhMethods = new HashMap<>(); + Stream lines = fileLines(file); - if (!bmhEnabled) { - speciesTypes = List.of(); + lines.map(line -> line.split(" ")) + .forEach(parts -> { + switch (parts[0]) { + case "[BMH_RESOLVE]": + speciesTypes.add(expandSignature(parts[1])); + break; + case "[LF_RESOLVE]": + String methodType = parts[3]; + validateMethodType(methodType); + if (parts[1].contains("Invokers")) { + invokerTypes.add(methodType); + } else if (parts[1].contains("DirectMethodHandle")) { + String dmh = parts[2]; + // ignore getObject etc for now (generated + // by default) + if (DMH_METHOD_TYPE_MAP.containsKey(dmh)) { + addDMHMethodType(dmh, methodType); + } + } + break; + default: break; // ignore + } + }); + } } else { - String args = config.get(BMH_SPECIES_PARAM); - List bmhSpecies; - if (args != null && !args.isEmpty()) { - bmhSpecies = Arrays.stream(args.split(",")) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toList()); - } else { - bmhSpecies = defaultSpecies(); - } - + List bmhSpecies = defaultSpecies(); // Expand BMH species signatures speciesTypes = bmhSpecies.stream() .map(type -> expandSignature(type)) .collect(Collectors.toList()); - } - // DirectMethodHandles - if (!dmhEnabled) { - dmhMethods = Map.of(); - } else { - dmhMethods = new HashMap<>(); - for (String dmhParam : DMH_METHOD_TYPE_MAP.keySet()) { - String args = config.get(dmhParam); - if (args != null && !args.isEmpty()) { - List dmhMethodTypes = Arrays.stream(args.split(",")) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toList()); - dmhMethods.put(dmhParam, dmhMethodTypes); - // Validation check - for (String type : dmhMethodTypes) { - String[] typeParts = type.split("_"); - // check return type (second part) - if (typeParts.length != 2 || typeParts[1].length() != 1 - || "LJIFDV".indexOf(typeParts[1].charAt(0)) == -1) { - throw new PluginException( - "Method type signature must be of form [LJIFD]*_[LJIFDV]"); - } - // expand and check arguments (first part) - expandSignature(typeParts[0]); - } - } - } - if (dmhMethods.isEmpty()) { - dmhMethods = defaultDMHMethods(); + invokerTypes = defaultInvokers(); + validateMethodTypes(invokerTypes); + + dmhMethods = defaultDMHMethods(); + for (List dmhMethodTypes : dmhMethods.values()) { + validateMethodTypes(dmhMethodTypes); } } } + private void addDMHMethodType(String dmh, String methodType) { + validateMethodType(methodType); + List methodTypes = dmhMethods.get(dmh); + if (methodTypes == null) { + methodTypes = new ArrayList<>(); + dmhMethods.put(dmh, methodTypes); + } + methodTypes.add(methodType); + } + + private Stream fileLines(File file) { + try { + return Files.lines(file.toPath()); + } catch (IOException io) { + throw new PluginException("Couldn't read file"); + } + } + + private void validateMethodTypes(List dmhMethodTypes) { + for (String type : dmhMethodTypes) { + validateMethodType(type); + } + } + + private void validateMethodType(String type) { + String[] typeParts = type.split("_"); + // check return type (second part) + if (typeParts.length != 2 || typeParts[1].length() != 1 + || "LJIFDV".indexOf(typeParts[1].charAt(0)) == -1) { + throw new PluginException( + "Method type signature must be of form [LJIFD]*_[LJIFDV]"); + } + // expand and check arguments (first part) + expandSignature(typeParts[0]); + } + private static void requireBasicType(char c) { if ("LIJFD".indexOf(c) < 0) { throw new PluginException( @@ -228,9 +256,10 @@ public final class GenerateJLIClassesPlugin implements Plugin { // Copy all but DMH_ENTRY to out in.transformAndCopy(entry -> { // filter out placeholder entries - if (entry.path().equals(DIRECT_METHOD_HANDLE_ENTRY) || - entry.path().equals(DELEGATING_METHOD_HANDLE_ENTRY) || - entry.path().equals(BASIC_FORMS_HANDLE_ENTRY)) { + if (entry.path().equals(DIRECT_METHOD_HOLDER_ENTRY) || + entry.path().equals(DELEGATING_METHOD_HOLDER_ENTRY) || + entry.path().equals(INVOKERS_HOLDER_ENTRY) || + entry.path().equals(BASIC_FORMS_HOLDER_ENTRY)) { return null; } else { return entry; @@ -265,42 +294,72 @@ public final class GenerateJLIClassesPlugin implements Plugin { for (List entry : dmhMethods.values()) { count += entry.size(); } - MethodType[] methodTypes = new MethodType[count]; + MethodType[] directMethodTypes = new MethodType[count]; int[] dmhTypes = new int[count]; int index = 0; for (Map.Entry> entry : dmhMethods.entrySet()) { String dmhType = entry.getKey(); for (String type : entry.getValue()) { - methodTypes[index] = asMethodType(type); + // The DMH type to actually ask for is retrieved by removing + // the first argument, which needs to be of Object.class + MethodType mt = asMethodType(type); + if (mt.parameterCount() < 1 || + mt.parameterType(0) != Object.class) { + throw new PluginException( + "DMH type parameter must start with L"); + } + directMethodTypes[index] = mt.dropParameterTypes(0, 1); dmhTypes[index] = DMH_METHOD_TYPE_MAP.get(dmhType); index++; } } + MethodType[] invokerMethodTypes = new MethodType[this.invokerTypes.size()]; + for (int i = 0; i < invokerTypes.size(); i++) { + // The invoker type to ask for is retrieved by removing the first + // and the last argument, which needs to be of Object.class + MethodType mt = asMethodType(invokerTypes.get(i)); + final int lastParam = mt.parameterCount() - 1; + if (mt.parameterCount() < 2 || + mt.parameterType(0) != Object.class || + mt.parameterType(lastParam) != Object.class) { + throw new PluginException( + "Invoker type parameter must start and end with L"); + } + mt = mt.dropParameterTypes(lastParam, lastParam + 1); + invokerMethodTypes[i] = mt.dropParameterTypes(0, 1); + } try { byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes( - DIRECT_METHOD_HANDLE, methodTypes, dmhTypes); + DIRECT_HOLDER, directMethodTypes, dmhTypes); ResourcePoolEntry ndata = ResourcePoolEntry - .create(DIRECT_METHOD_HANDLE_ENTRY, bytes); + .create(DIRECT_METHOD_HOLDER_ENTRY, bytes); out.add(ndata); bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes( - DELEGATING_METHOD_HANDLE, methodTypes); - ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HANDLE_ENTRY, bytes); + DELEGATING_HOLDER, directMethodTypes); + ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HOLDER_ENTRY, bytes); out.add(ndata); - bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HANDLE); - ndata = ResourcePoolEntry.create(BASIC_FORMS_HANDLE_ENTRY, bytes); + bytes = JLIA.generateInvokersHolderClassBytes(INVOKERS_HOLDER, + invokerMethodTypes); + ndata = ResourcePoolEntry.create(INVOKERS_HOLDER_ENTRY, bytes); + out.add(ndata); + + bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HOLDER); + ndata = ResourcePoolEntry.create(BASIC_FORMS_HOLDER_ENTRY, bytes); out.add(ndata); } catch (Exception ex) { throw new PluginException(ex); } } - private static final String DIRECT_METHOD_HANDLE_ENTRY = - "/java.base/" + DIRECT_METHOD_HANDLE + ".class"; - private static final String DELEGATING_METHOD_HANDLE_ENTRY = - "/java.base/" + DELEGATING_METHOD_HANDLE + ".class"; - private static final String BASIC_FORMS_HANDLE_ENTRY = - "/java.base/" + BASIC_FORMS_HANDLE + ".class"; + private static final String DIRECT_METHOD_HOLDER_ENTRY = + "/java.base/" + DIRECT_HOLDER + ".class"; + private static final String DELEGATING_METHOD_HOLDER_ENTRY = + "/java.base/" + DELEGATING_HOLDER + ".class"; + private static final String BASIC_FORMS_HOLDER_ENTRY = + "/java.base/" + BASIC_FORMS_HOLDER + ".class"; + private static final String INVOKERS_HOLDER_ENTRY = + "/java.base/" + INVOKERS_HOLDER + ".class"; // Convert LL -> LL, L3 -> LLL private static String expandSignature(String signature) { diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties index 50b958fa85d..67c40903eb9 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties @@ -56,7 +56,7 @@ copy-files.argument== to copy to the image>. copy-files.description=\ If files to copy are not absolute path, JDK home dir is used.\n\ -e.g.: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewehere/conf.txt +e.g.: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewhere/conf.txt exclude-files.argument= of files to exclude @@ -68,10 +68,12 @@ exclude-resources.argument= resources to exclude exclude-resources.description=\ Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/** -generate-jli-classes.argument= +generate-jli-classes.argument=<@filename> generate-jli-classes.description=\ -Concrete java.lang.invoke classes to generate +Takes a file hinting to jlink what java.lang.invoke classes to pre-generate. If\n\ +this flag is not specified a default set of classes will be generated, so to \n\ +disable pre-generation supply the name of an empty or non-existing file installed-modules.description=Fast loading of module descriptors (always enabled) diff --git a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java index 1e05e84e40f..2826f96f4ff 100644 --- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java +++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java @@ -165,8 +165,8 @@ class JarFileSystem extends ZipFileSystem { walk(inode.child, process); } else { process.accept(inode); - walk(inode.sibling, process); } + walk(inode.sibling, process); } /** diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 50eb6e6b321..2165bef4aba 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -124,10 +124,6 @@ java/beans/Introspector/8132566/OverrideUserDefPropertyInfoTest.java 8132565 gen # jdk_lang java/lang/StringCoding/CheckEncodings.sh 7008363 generic-all -java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java 8160690 generic-all -java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java 8160690 generic-all -java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java 8160690 generic-all -java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java 8160690 generic-all ############################################################################ @@ -211,8 +207,6 @@ sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic- java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all -sun/rmi/runtime/Log/6409194/NoConsoleOutput.java 8164124 windows-all - ############################################################################ # jdk_security diff --git a/jdk/test/java/lang/StackWalker/VerifyStackTrace.java b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java index 2c70a6d02dc..704a807bc57 100644 --- a/jdk/test/java/lang/StackWalker/VerifyStackTrace.java +++ b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java @@ -205,12 +205,13 @@ public class VerifyStackTrace { .replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/") .replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run") .replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke") - // DMHs may or may not be pre-generated, making frames differ + // LFs may or may not be pre-generated, making frames differ .replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH") - .replaceAll("DMH\\.invoke", "DMH/xxxxxxxx.invoke") + .replaceAll("Invokers\\$Holder", "LambdaForm\\$MH") + .replaceAll("MH\\.invoke", "MH/xxxxxxxx.invoke") // invoke frames may or may not have basic method type // information encoded for diagnostic purposes - .replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z]+_[A-Z]", "xx.invoke$1") + .replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z_]+", "xx.invoke$1") .replaceAll("\\$[0-9]+", "\\$??"); } else { return produced; diff --git a/jdk/test/java/net/HttpCookie/CookieNegativeMaxAge.java b/jdk/test/java/net/HttpCookie/CookieNegativeMaxAge.java new file mode 100644 index 00000000000..aae65f4f625 --- /dev/null +++ b/jdk/test/java/net/HttpCookie/CookieNegativeMaxAge.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8005068 + * @summary Check that any negative maxAge is treated as "unspecified" and + * if header contains cookie with "expires" attribute in the past then cookie + * is created with maxAge=0 meaning it is specified to be immediately expired. + * @run main CookieNegativeMaxAge + */ + + +import java.net.HttpCookie; +import java.util.List; + +public class CookieNegativeMaxAge { + + public static void main(String... args) { + HttpCookie cookie = new HttpCookie("testCookie", "value"); + cookie.setMaxAge(Integer.MIN_VALUE); + if (cookie.hasExpired()) { + throw new RuntimeException("Cookie has unexpectedly expired"); + } + + List cookies = HttpCookie.parse("Set-Cookie: " + + "expiredCookie=value; expires=Thu, 01 Jan 1970 00:00:00 GMT"); + if (cookies.size() == 1) { + if (cookies.get(0).getMaxAge() != 0) { + throw new RuntimeException("Cookie maxAge expected to be 0"); + } + } else { + throw new RuntimeException("Header was incorrectly parsed"); + } + } +} diff --git a/jdk/test/java/net/MulticastSocket/NoLoopbackPackets.java b/jdk/test/java/net/MulticastSocket/NoLoopbackPackets.java index f01993ab131..7f7fb776df3 100644 --- a/jdk/test/java/net/MulticastSocket/NoLoopbackPackets.java +++ b/jdk/test/java/net/MulticastSocket/NoLoopbackPackets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,6 +68,7 @@ public class NoLoopbackPackets { MulticastSocket msock = null; List failedGroups = new ArrayList(); + Sender sender = null; try { msock = new MulticastSocket(); int port = msock.getLocalPort(); @@ -80,9 +81,8 @@ public class NoLoopbackPackets { groups.add(new InetSocketAddress(InetAddress.getByName("::ffff:224.1.1.2"), port)); groups.add(new InetSocketAddress(InetAddress.getByName("ff02::1:1"), port)); - Thread sender = new Thread(new Sender(groups)); - sender.setDaemon(true); // we want sender to stop when main thread exits - sender.start(); + sender = new Sender(groups); + new Thread(sender).start(); // Now try to receive multicast packets. we should not see any of them // since we disable loopback mode. @@ -107,6 +107,9 @@ public class NoLoopbackPackets { } } finally { if (msock != null) try { msock.close(); } catch (Exception e) {} + if (sender != null) { + sender.stop(); + } } if (failedGroups.size() > 0) { @@ -119,6 +122,7 @@ public class NoLoopbackPackets { static class Sender implements Runnable { private List sendToGroups; + private volatile boolean stop; public Sender(List groups) { sendToGroups = groups; @@ -136,7 +140,7 @@ public class NoLoopbackPackets { MulticastSocket msock = new MulticastSocket(); msock.setLoopbackMode(true); // disable loopback mode - for (;;) { + while (!stop) { for (DatagramPacket packet : packets) { msock.send(packet); } @@ -147,5 +151,9 @@ public class NoLoopbackPackets { throw new RuntimeException(e); } } + + void stop() { + stop = true; + } } } diff --git a/jdk/test/java/net/httpclient/ProxyAuthTest.java b/jdk/test/java/net/httpclient/ProxyAuthTest.java new file mode 100644 index 00000000000..42bc0c709db --- /dev/null +++ b/jdk/test/java/net/httpclient/ProxyAuthTest.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + */ + +/* + * @test + * @bug 8163561 + * @modules java.base/sun.net.www + * @summary Verify that Proxy-Authenticate header is correctly handled + * + * @run main/othervm ProxyAuthTest + */ + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.Authenticator; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.ProxySelector; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpResponse; +import java.util.Base64; + +import sun.net.www.MessageHeader; + +public class ProxyAuthTest { + private static final String AUTH_USER = "user"; + private static final String AUTH_PASSWORD = "password"; + + public static void main(String[] args) throws Exception { + try (ServerSocket ss = new ServerSocket(0)) { + int port = ss.getLocalPort(); + MyProxy proxy = new MyProxy(ss); + (new Thread(proxy)).start(); + System.out.println("Proxy listening port " + port); + + Auth auth = new Auth(); + InetSocketAddress paddr = new InetSocketAddress("localhost", port); + + URI uri = new URI("http://www.google.ie/"); + HttpClient client = HttpClient.create() + .proxy(ProxySelector.of(paddr)) + .authenticator(auth) + .build(); + HttpResponse resp = client.request(uri) + .GET() + .responseAsync() + .get(); + if (resp.statusCode() != 404) { + throw new RuntimeException("Unexpected status code: " + resp.statusCode()); + } + + if (auth.isCalled) { + System.out.println("Authenticator is called"); + } else { + throw new RuntimeException("Authenticator is not called"); + } + + if (!proxy.matched) { + throw new RuntimeException("Proxy authentication failed"); + } + } + } + + static class Auth extends Authenticator { + private volatile boolean isCalled; + + @Override + protected PasswordAuthentication getPasswordAuthentication() { + System.out.println("scheme: " + this.getRequestingScheme()); + isCalled = true; + return new PasswordAuthentication(AUTH_USER, + AUTH_PASSWORD.toCharArray()); + } + } + + static class MyProxy implements Runnable { + final ServerSocket ss; + private volatile boolean matched; + + MyProxy(ServerSocket ss) { + this.ss = ss; + } + + public void run() { + for (int i = 0; i < 2; i++) { + try (Socket s = ss.accept(); + InputStream in = s.getInputStream(); + OutputStream os = s.getOutputStream(); + BufferedWriter writer = new BufferedWriter( + new OutputStreamWriter(os)); + PrintWriter out = new PrintWriter(writer);) { + MessageHeader headers = new MessageHeader(in); + System.out.println("Proxy: received " + headers); + + String authInfo = headers + .findValue("Proxy-Authorization"); + if (authInfo != null) { + authenticate(authInfo); + out.print("HTTP/1.1 404 Not found\r\n"); + out.print("\r\n"); + System.out.println("Proxy: 404"); + out.flush(); + } else { + out.print("HTTP/1.1 407 Proxy Authorization Required\r\n"); + out.print( + "Proxy-Authenticate: Basic realm=\"a fake realm\"\r\n"); + out.print("\r\n"); + System.out.println("Proxy: Authorization required"); + out.flush(); + } + } catch (IOException x) { + System.err.println("Unexpected IOException from proxy."); + x.printStackTrace(); + break; + } + } + } + + private void authenticate(String authInfo) throws IOException { + try { + authInfo.trim(); + int ind = authInfo.indexOf(' '); + String recvdUserPlusPass = authInfo.substring(ind + 1).trim(); + // extract encoded username:passwd + String value = new String( + Base64.getMimeDecoder().decode(recvdUserPlusPass)); + String userPlusPassword = AUTH_USER + ":" + AUTH_PASSWORD; + if (userPlusPassword.equals(value)) { + matched = true; + System.out.println("Proxy: client authentication successful"); + } else { + System.err.println( + "Proxy: client authentication failed, expected [" + + userPlusPassword + "], actual [" + value + + "]"); + } + } catch (Exception e) { + throw new IOException( + "Proxy received invalid Proxy-Authorization value: " + + authInfo); + } + } + } + +} + diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java index 0a62be8fc57..036b28dbf7f 100644 --- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java +++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,19 +119,31 @@ public class Basic { ExecutorService pool = Executors.newCachedThreadPool(); AsynchronousChannelGroup group = AsynchronousChannelGroup .withCachedThreadPool(pool, rand.nextInt(10)); - testShutdownWithChannels(pool, group); + try { + testShutdownWithChannels(pool, group); + } finally { + group.shutdown(); + } } for (int i = 0; i < 100; i++) { int nThreads = 1 + rand.nextInt(8); AsynchronousChannelGroup group = AsynchronousChannelGroup .withFixedThreadPool(nThreads, threadFactory); - testShutdownWithChannels(null, group); + try { + testShutdownWithChannels(null, group); + } finally { + group.shutdown(); + } } for (int i = 0; i < 100; i++) { ExecutorService pool = Executors.newCachedThreadPool(); AsynchronousChannelGroup group = AsynchronousChannelGroup .withThreadPool(pool); - testShutdownWithChannels(pool, group); + try { + testShutdownWithChannels(pool, group); + } finally { + group.shutdown(); + } } } @@ -164,19 +176,31 @@ public class Basic { ExecutorService pool = pool = Executors.newCachedThreadPool(); AsynchronousChannelGroup group = AsynchronousChannelGroup .withCachedThreadPool(pool, rand.nextInt(5)); - testShutdownNow(pool, group); + try { + testShutdownNow(pool, group); + } finally { + group.shutdown(); + } } for (int i = 0; i < 10; i++) { int nThreads = 1 + rand.nextInt(8); AsynchronousChannelGroup group = AsynchronousChannelGroup .withFixedThreadPool(nThreads, threadFactory); - testShutdownNow(null, group); + try { + testShutdownNow(null, group); + } finally { + group.shutdown(); + } } for (int i = 0; i < 10; i++) { ExecutorService pool = Executors.newCachedThreadPool(); AsynchronousChannelGroup group = AsynchronousChannelGroup .withThreadPool(pool); - testShutdownNow(pool, group); + try { + testShutdownNow(pool, group); + } finally { + group.shutdown(); + } } } @@ -186,78 +210,78 @@ public class Basic { AsynchronousChannelGroup group = AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory); - AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group); - AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open(group); + try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group); + AsynchronousServerSocketChannel listener = + AsynchronousServerSocketChannel.open(group)) { - // initiate accept - listener.bind(new InetSocketAddress(0)); - Future result = listener.accept(); + // initiate accept + listener.bind(new InetSocketAddress(0)); + Future result = listener.accept(); - // shutdown group - group.shutdown(); - if (!group.isShutdown()) - throw new RuntimeException("Group should be shutdown"); + // shutdown group + group.shutdown(); + if (!group.isShutdown()) + throw new RuntimeException("Group should be shutdown"); - // attempt to create another channel - try { - AsynchronousSocketChannel.open(group); - throw new RuntimeException("ShutdownChannelGroupException expected"); - } catch (ShutdownChannelGroupException x) { + // attempt to create another channel + try { + AsynchronousSocketChannel.open(group); + throw new RuntimeException("ShutdownChannelGroupException expected"); + } catch (ShutdownChannelGroupException x) { + } + try { + AsynchronousServerSocketChannel.open(group); + throw new RuntimeException("ShutdownChannelGroupException expected"); + } catch (ShutdownChannelGroupException x) { + } + + // attempt to create another channel by connecting. This should cause + // the accept operation to fail. + InetAddress lh = InetAddress.getLocalHost(); + int port = ((InetSocketAddress)listener.getLocalAddress()).getPort(); + InetSocketAddress isa = new InetSocketAddress(lh, port); + ch.connect(isa).get(); + try { + result.get(); + throw new RuntimeException("Connection was accepted"); + } catch (ExecutionException x) { + Throwable cause = x.getCause(); + if (!(cause instanceof IOException)) + throw new RuntimeException("Cause should be IOException"); + cause = cause.getCause(); + if (!(cause instanceof ShutdownChannelGroupException)) + throw new RuntimeException("IOException cause should be ShutdownChannelGroupException"); + } + + // initiate another accept even though channel group is shutdown. + Future res = listener.accept(); + try { + res.get(3, TimeUnit.SECONDS); + throw new RuntimeException("TimeoutException expected"); + } catch (TimeoutException x) { + } + // connect to the listener which should cause the accept to complete + AsynchronousSocketChannel.open().connect(isa); + try { + res.get(); + throw new RuntimeException("Connection was accepted"); + } catch (ExecutionException x) { + Throwable cause = x.getCause(); + if (!(cause instanceof IOException)) + throw new RuntimeException("Cause should be IOException"); + cause = cause.getCause(); + if (!(cause instanceof ShutdownChannelGroupException)) + throw new RuntimeException("IOException cause should be ShutdownChannelGroupException"); + } + + // group should *not* terminate as channels are open + boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS); + if (terminated) { + throw new RuntimeException("Group should not have terminated"); + } + } finally { + group.shutdown(); } - try { - AsynchronousServerSocketChannel.open(group); - throw new RuntimeException("ShutdownChannelGroupException expected"); - } catch (ShutdownChannelGroupException x) { - } - - // attempt to create another channel by connecting. This should cause - // the accept operation to fail. - InetAddress lh = InetAddress.getLocalHost(); - int port = ((InetSocketAddress)listener.getLocalAddress()).getPort(); - InetSocketAddress isa = new InetSocketAddress(lh, port); - ch.connect(isa).get(); - try { - result.get(); - throw new RuntimeException("Connection was accepted"); - } catch (ExecutionException x) { - Throwable cause = x.getCause(); - if (!(cause instanceof IOException)) - throw new RuntimeException("Cause should be IOException"); - cause = cause.getCause(); - if (!(cause instanceof ShutdownChannelGroupException)) - throw new RuntimeException("IOException cause should be ShutdownChannelGroupException"); - } - - // initiate another accept even though channel group is shutdown. - Future res = listener.accept(); - try { - res.get(3, TimeUnit.SECONDS); - throw new RuntimeException("TimeoutException expected"); - } catch (TimeoutException x) { - } - // connect to the listener which should cause the accept to complete - AsynchronousSocketChannel.open().connect(isa); - try { - res.get(); - throw new RuntimeException("Connection was accepted"); - } catch (ExecutionException x) { - Throwable cause = x.getCause(); - if (!(cause instanceof IOException)) - throw new RuntimeException("Cause should be IOException"); - cause = cause.getCause(); - if (!(cause instanceof ShutdownChannelGroupException)) - throw new RuntimeException("IOException cause should be ShutdownChannelGroupException"); - } - - // group should *not* terminate as channels are open - boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS); - if (terminated) - throw new RuntimeException("Group should not have terminated"); - - // close channel; group should terminate quickly - ch.close(); - listener.close(); - awaitTermination(group); } static void miscTests() throws Exception { diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java index ce7d3f63552..9740f953215 100644 --- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java +++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,34 +41,36 @@ import java.io.IOException; public class GroupOfOne { public static void main(String[] args) throws Exception { + final List accepted = new ArrayList<>(); + // create listener to accept connections - final AsynchronousServerSocketChannel listener = - AsynchronousServerSocketChannel.open() - .bind(new InetSocketAddress(0)); - final List accepted = new ArrayList(); - listener.accept((Void)null, new CompletionHandler() { - public void completed(AsynchronousSocketChannel ch, Void att) { - synchronized (accepted) { - accepted.add(ch); + try (final AsynchronousServerSocketChannel listener = + AsynchronousServerSocketChannel.open()) { + + listener.bind(new InetSocketAddress(0)); + listener.accept((Void)null, new CompletionHandler() { + public void completed(AsynchronousSocketChannel ch, Void att) { + synchronized (accepted) { + accepted.add(ch); + } + listener.accept((Void)null, this); } - listener.accept((Void)null, this); - } - public void failed(Throwable exc, Void att) { - } - }); + public void failed(Throwable exc, Void att) { + } + }); - int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); - SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port); + int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); + SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port); - test(sa, true, false); - test(sa, false, true); - test(sa, true, true); - - // clean-up - listener.close(); - synchronized (accepted) { - for (AsynchronousSocketChannel ch: accepted) { - ch.close(); + test(sa, true, false); + test(sa, false, true); + test(sa, true, true); + } finally { + // clean-up + synchronized (accepted) { + for (AsynchronousSocketChannel ch: accepted) { + ch.close(); + } } } } @@ -86,60 +88,60 @@ public class GroupOfOne { return new Thread(r); }}); final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group); + try { + // the latch counts down when: + // 1. The read operation fails (expected) + // 2. the close/shutdown completes + final CountDownLatch latch = new CountDownLatch(2); - // the latch counts down when: - // 1. The read operation fails (expected) - // 2. the close/shutdown completes - final CountDownLatch latch = new CountDownLatch(2); + ch.connect(sa, (Void)null, new CompletionHandler() { + public void completed(Void result, Void att) { + System.out.println("Connected"); - ch.connect(sa, (Void)null, new CompletionHandler() { - public void completed(Void result, Void att) { - System.out.println("Connected"); + // initiate I/O operation that does not complete (successfully) + ByteBuffer buf = ByteBuffer.allocate(100); + ch.read(buf, (Void)null, new CompletionHandler() { + public void completed(Integer bytesRead, Void att) { + throw new RuntimeException(); + } + public void failed(Throwable exc, Void att) { + if (!(exc instanceof AsynchronousCloseException)) + throw new RuntimeException(exc); + System.out.println("Read failed (expected)"); + latch.countDown(); + } + }); - // initiate I/O operation that does not complete (successfully) - ByteBuffer buf = ByteBuffer.allocate(100); - ch.read(buf, (Void)null, new CompletionHandler() { - public void completed(Integer bytesRead, Void att) { + // close channel or shutdown group + try { + if (closeChannel) { + System.out.print("Close channel ..."); + ch.close(); + System.out.println(" done."); + } + if (shutdownGroup) { + System.out.print("Shutdown group ..."); + group.shutdownNow(); + System.out.println(" done."); + } + latch.countDown(); + } catch (IOException e) { throw new RuntimeException(); } - public void failed(Throwable exc, Void att) { - if (!(exc instanceof AsynchronousCloseException)) - throw new RuntimeException(exc); - System.out.println("Read failed (expected)"); - latch.countDown(); - } - }); - - // close channel or shutdown group - try { - if (closeChannel) { - System.out.print("Close channel ..."); - ch.close(); - System.out.println(" done."); - } - if (shutdownGroup) { - System.out.print("Shutdown group ..."); - group.shutdownNow(); - System.out.println(" done."); - } - latch.countDown(); - } catch (IOException e) { - throw new RuntimeException(); } - } - public void failed(Throwable exc, Void att) { - throw new RuntimeException(exc); - } - }); - - latch.await(); - - // clean-up - group.shutdown(); - boolean terminated = group.awaitTermination(20, TimeUnit.SECONDS); - if (!terminated) - throw new RuntimeException("Group did not terminate"); + public void failed(Throwable exc, Void att) { + throw new RuntimeException(exc); + } + }); + latch.await(); + } finally { + // clean-up + group.shutdown(); + boolean terminated = group.awaitTermination(20, TimeUnit.SECONDS); + if (!terminated) + throw new RuntimeException("Group did not terminate"); + } System.out.println("TEST OKAY"); } } diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java index 654d5f92183..ef8c3a0ebf4 100644 --- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java +++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,89 +76,91 @@ public class Identity { } public static void main(String[] args) throws Exception { - // create listener to accept connections - final AsynchronousServerSocketChannel listener = - AsynchronousServerSocketChannel.open() - .bind(new InetSocketAddress(0)); - listener.accept((Void)null, new CompletionHandler() { - public void completed(final AsynchronousSocketChannel ch, Void att) { - listener.accept((Void)null, this); - final ByteBuffer buf = ByteBuffer.allocate(100); - ch.read(buf, ch, new CompletionHandler() { - public void completed(Integer bytesRead, AsynchronousSocketChannel ch) { - if (bytesRead < 0) { - try { ch.close(); } catch (IOException ignore) { } - } else { - buf.clear(); - ch.read(buf, ch, this); - } - } - public void failed(Throwable exc, AsynchronousSocketChannel ch) { - try { ch.close(); } catch (IOException ignore) { } - } - }); - } - public void failed(Throwable exc, Void att) { - } - }); - int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); - SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port); - // create 3-10 channels, each in its own group final int groupCount = 3 + rand.nextInt(8); - AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount]; + final AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount]; final AsynchronousSocketChannel[] channels = new AsynchronousSocketChannel[groupCount]; - for (int i=0; i() { - public void completed(Integer bytesWritten, Integer groupId) { - if (bytesWritten != 1) - fail("Expected 1 byte to be written"); - if (!myGroup.get().equals(groupId)) - fail("Handler invoked by thread with the wrong identity"); - if (writeCount.decrementAndGet() > 0) { - int id = rand.nextInt(groupCount); - channels[id].write(getBuffer(), id, this); - } else { - done.countDown(); + listener.bind(new InetSocketAddress(0)); + listener.accept((Void)null, new CompletionHandler() { + public void completed(final AsynchronousSocketChannel ch, Void att) { + listener.accept((Void)null, this); + final ByteBuffer buf = ByteBuffer.allocate(100); + ch.read(buf, ch, new CompletionHandler() { + public void completed(Integer bytesRead, AsynchronousSocketChannel ch) { + if (bytesRead < 0) { + try { ch.close(); } catch (IOException ignore) { } + } else { + buf.clear(); + ch.read(buf, ch, this); + } + } + public void failed(Throwable exc, AsynchronousSocketChannel ch) { + try { ch.close(); } catch (IOException ignore) { } + } + }); } + public void failed(Throwable exc, Void att) { + } + }); + int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); + SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port); + + for (int i=0; i() { + public void completed(Integer bytesWritten, Integer groupId) { + if (bytesWritten != 1) + fail("Expected 1 byte to be written"); + if (!myGroup.get().equals(groupId)) + fail("Handler invoked by thread with the wrong identity"); + if (writeCount.decrementAndGet() > 0) { + int id = rand.nextInt(groupCount); + channels[id].write(getBuffer(), id, this); + } else { + done.countDown(); + } + } + public void failed(Throwable exc, Integer groupId) { + fail(exc.getMessage()); + } + }); - // clean-up - for (AsynchronousSocketChannel ch: channels) - ch.close(); - for (AsynchronousChannelGroup group: groups) - group.shutdownNow(); - listener.close(); + // wait until done + done.await(); + } finally { + // clean-up + for (AsynchronousSocketChannel ch: channels) + ch.close(); + for (AsynchronousChannelGroup group: groups) + group.shutdownNow(); - if (failed.get()) - throw new RuntimeException("Test failed - see log for details"); + if (failed.get()) + throw new RuntimeException("Test failed - see log for details"); + } } static ByteBuffer getBuffer() { diff --git a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java index 4d364017f0e..2c40bb71da1 100644 --- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java +++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,21 +66,30 @@ public class Restart { // group with fixed thread pool int nThreads = 1 + rand.nextInt(4); AsynchronousChannelGroup group = - AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory); - testRestart(group, 100); - group.shutdown(); + AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory); + try { + testRestart(group, 100); + } finally { + group.shutdown(); + } // group with cached thread pool ExecutorService pool = Executors.newCachedThreadPool(factory); group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5)); - testRestart(group, 100); - group.shutdown(); + try { + testRestart(group, 100); + } finally { + group.shutdown(); + } // group with custom thread pool - group = AsynchronousChannelGroup - .withThreadPool(Executors.newFixedThreadPool(1+rand.nextInt(5), factory)); - testRestart(group, 100); - group.shutdown(); + group = AsynchronousChannelGroup.withThreadPool( + Executors.newFixedThreadPool(1+rand.nextInt(5), factory)); + try { + testRestart(group, 100); + } finally { + group.shutdown(); + } // give time for threads to terminate Thread.sleep(3000); @@ -92,45 +101,43 @@ public class Restart { static void testRestart(AsynchronousChannelGroup group, int count) throws Exception { - AsynchronousServerSocketChannel listener = - AsynchronousServerSocketChannel.open(group) - .bind(new InetSocketAddress(0)); + try (AsynchronousServerSocketChannel listener = + AsynchronousServerSocketChannel.open(group)) { - for (int i=0; i() { - public void completed(AsynchronousSocketChannel ch, Void att) { - try { - ch.close(); - } catch (IOException ignore) { } + listener.accept((Void)null, new CompletionHandler() { + public void completed(AsynchronousSocketChannel ch, Void att) { + try { + ch.close(); + } catch (IOException ignore) { } - latch.countDown(); + latch.countDown(); - // throw error or runtime exception - if (rand.nextBoolean()) { - throw new Error(); - } else { - throw new RuntimeException(); + // throw error or runtime exception + if (rand.nextBoolean()) { + throw new Error(); + } else { + throw new RuntimeException(); + } } - } - public void failed(Throwable exc, Void att) { - } - }); + public void failed(Throwable exc, Void att) { + } + }); - // establish loopback connection which should cause completion - // handler to be invoked. - int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); - AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(); - InetAddress lh = InetAddress.getLocalHost(); - ch.connect(new InetSocketAddress(lh, port)).get(); - ch.close(); + // establish loopback connection which should cause completion + // handler to be invoked. + int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); + try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) { + InetAddress lh = InetAddress.getLocalHost(); + ch.connect(new InetSocketAddress(lh, port)).get(); + } - // wait for handler to be invoked - latch.await(); + // wait for handler to be invoked + latch.await(); + } } - - // clean-up - listener.close(); } } diff --git a/jdk/test/java/nio/channels/FileChannel/Lock.java b/jdk/test/java/nio/channels/FileChannel/Lock.java index 87f470835e7..8dee478ea82 100644 --- a/jdk/test/java/nio/channels/FileChannel/Lock.java +++ b/jdk/test/java/nio/channels/FileChannel/Lock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,8 @@ */ /* @test - * @bug 4429043 4493595 6332756 6709457 - * @summary The FileChannel file locking + * @bug 4429043 4493595 6332756 6709457 7146506 + * @summary Test FileChannel file locking */ import java.io.*; @@ -33,17 +33,14 @@ import static java.nio.file.StandardOpenOption.*; /** * Testing FileChannel's lock method. */ - public class Lock { public static void main(String[] args) throws Exception { - if (args.length > 0) { - if(args[0].equals("1")) { - MadWriter mw = new MadWriter(args[1], false); - } else { - MadWriter mw = new MadWriter(args[1], true); - } + if (args.length == 2) { + attemptLock(args[1], args[0].equals("2")); return; + } else if (args.length != 0) { + throw new RuntimeException("Wrong number of parameters."); } File blah = File.createTempFile("blah", null); blah.deleteOnExit(); @@ -56,120 +53,128 @@ public class Lock { test2(blah, false); test3(blah); test4(blah); - blah.delete(); - } - - private static void test2(File blah, boolean b) throws Exception { - RandomAccessFile raf = new RandomAccessFile(blah, "rw"); - FileChannel channel = raf.getChannel(); - FileLock lock; - if (b) - lock = channel.lock(); - else - lock = channel.tryLock(); - lock.release(); - channel.close(); } + /** + * Test mutual locking with other process + */ static void test1(File blah, String str) throws Exception { + try (RandomAccessFile fis = new RandomAccessFile(blah, "rw")) { + FileChannel fc = fis.getChannel(); + FileLock lock = null; - // Grab the lock - RandomAccessFile fis = new RandomAccessFile(blah, "rw"); - FileChannel fc = fis.getChannel(); - FileLock lock = null; - - if (str.equals("1")) { - lock = fc.lock(0, 10, false); - if (lock == null) - throw new RuntimeException("Lock should not return null"); - try { - FileLock lock2 = fc.lock(5, 10, false); - throw new RuntimeException("Overlapping locks allowed"); - } catch (OverlappingFileLockException e) { - // Correct result + // grab the lock + if (str.equals("1")) { + lock = fc.lock(0, 10, false); + if (lock == null) + throw new RuntimeException("Lock should not return null"); + try { + fc.lock(5, 10, false); + throw new RuntimeException("Overlapping locks allowed"); + } catch (OverlappingFileLockException e) {} // correct result } - } - // Exec the tamperer - String command = System.getProperty("java.home") + - File.separator + "bin" + File.separator + "java"; - String testClasses = System.getProperty("test.classes"); - if (testClasses != null) - command += " -cp " + testClasses; - command += " Lock " + str + " " + blah; - Process p = Runtime.getRuntime().exec(command); + // execute the tamperer + String command = System.getProperty("java.home") + + File.separator + "bin" + File.separator + "java"; + String testClasses = System.getProperty("test.classes"); + if (testClasses != null) + command += " -cp " + testClasses; + command += " Lock " + str + " " + blah; + Process p = Runtime.getRuntime().exec(command); - BufferedReader in = new BufferedReader - (new InputStreamReader(p.getInputStream())); - - String s; - int count = 0; - while ((s = in.readLine()) != null) { - if (!s.equals("good")) { - if (File.separatorChar == '/') { - // Fails on windows over NFS... - throw new RuntimeException("Failed: "+s); + // evaluate System.out of child process + String s; + boolean hasOutput = false; + InputStreamReader isr; + isr = new InputStreamReader(p.getInputStream()); + BufferedReader br = new BufferedReader(isr); + while ((s = br.readLine()) != null) { + // only throw on Unix as windows over NFS fails... + if ((File.separatorChar == '/') && !s.equals("good")) { + throw new RuntimeException("Failed: " + s); } + hasOutput = true; } - count++; - } - if (count == 0) { - in = new BufferedReader(new InputStreamReader(p.getErrorStream())); - while ((s = in.readLine()) != null) { - System.err.println("Error output: " + s); + // evaluate System.err in case of System.out of child process + // was empty + if (!hasOutput) { + isr = new InputStreamReader(p.getErrorStream()); + br = new BufferedReader(isr); + if ((s = br.readLine()) != null) { + System.err.println("Error output:"); + System.err.println(s); + while ((s = br.readLine()) != null) { + System.err.println(s); + } + } + throw new RuntimeException("Failed, no output"); } - throw new RuntimeException("Failed, no output"); - } - // Clean up - if (lock != null) { - /* Check multiple releases */ - lock.release(); - lock.release(); + // clean up, check multiple releases + if (lock != null) { + lock.release(); + lock.release(); + } } - fc.close(); - fis.close(); } - // The overlap check for file locks should be JVM-wide - private static void test3(File blah) throws Exception { - FileChannel fc1 = new RandomAccessFile(blah, "rw").getChannel(); - FileChannel fc2 = new RandomAccessFile(blah, "rw").getChannel(); - - // lock via one channel, and then attempt to lock the same file - // using a second channel - FileLock fl1 = fc1.lock(); - try { - fc2.tryLock(); - throw new RuntimeException("Overlapping locks allowed"); - } catch (OverlappingFileLockException x) { + /** + * Basic test for FileChannel.lock() and FileChannel.tryLock() + */ + static void test2(File blah, boolean b) throws Exception { + try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) { + FileChannel channel = raf.getChannel(); + FileLock lock; + if (b) + lock = channel.lock(); + else + lock = channel.tryLock(); + lock.release(); } - try { + } + + /** + * Test that overlapping file locking is not possible when using different + * FileChannel objects to the same file path + */ + static void test3(File blah) throws Exception { + try (RandomAccessFile raf1 = new RandomAccessFile(blah, "rw"); + RandomAccessFile raf2 = new RandomAccessFile(blah, "rw")) + { + FileChannel fc1 = raf1.getChannel(); + FileChannel fc2 = raf2.getChannel(); + + // lock via one channel, and then attempt to lock the same file + // using a second channel + FileLock fl1 = fc1.lock(); + try { + fc2.tryLock(); + throw new RuntimeException("Overlapping locks allowed"); + } catch (OverlappingFileLockException x) {} + try { + fc2.lock(); + throw new RuntimeException("Overlapping locks allowed"); + } catch (OverlappingFileLockException x) {} + + // release lock and the attempt to lock with the second channel + // should succeed. + fl1.release(); fc2.lock(); - throw new RuntimeException("Overlapping locks allowed"); - } catch (OverlappingFileLockException x) { + try { + fc1.lock(); + throw new RuntimeException("Overlapping locks allowed"); + } catch (OverlappingFileLockException x) {} } - - // release lock and the attempt to lock with the second channel - // should succeed. - fl1.release(); - FileLock fl2 = fc2.lock(); - try { - fc1.lock(); - throw new RuntimeException("Overlapping locks allowed"); - } catch (OverlappingFileLockException x) { - } - - fc1.close(); - fc2.close(); } /** * Test file locking when file is opened for append */ static void test4(File blah) throws Exception { - try (FileChannel fc = new FileOutputStream(blah, true).getChannel()) { + try (FileOutputStream fos = new FileOutputStream(blah, true)) { + FileChannel fc = fos.getChannel(); fc.tryLock().release(); fc.tryLock(0L, 1L, false).release(); fc.lock().release(); @@ -182,30 +187,31 @@ public class Lock { fc.lock(0L, 1L, false).release(); } } -} -class MadWriter { - public MadWriter(String s, boolean b) throws Exception { - File f = new File(s); - RandomAccessFile fos = new RandomAccessFile(f, "rw"); - FileChannel fc = fos.getChannel(); - if (fc.tryLock(10, 10, false) == null) { - System.out.println("bad: Failed to grab adjacent lock"); + /** + * Utility method to be run in secondary process which tries to acquire a + * lock on a FileChannel + */ + static void attemptLock(String fileName, + boolean expectsLock) throws Exception + { + File f = new File(fileName); + try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) { + FileChannel fc = raf.getChannel(); + if (fc.tryLock(10, 10, false) == null) { + System.out.println("bad: Failed to grab adjacent lock"); + } + if (fc.tryLock(0, 10, false) == null) { + if (expectsLock) + System.out.println("bad"); + else + System.out.println("good"); + } else { + if (expectsLock) + System.out.println("good"); + else + System.out.println("bad"); + } } - FileLock lock = fc.tryLock(0, 10, false); - if (lock == null) { - if (b) - System.out.println("bad"); - else - System.out.println("good"); - } else { - if (b) - System.out.println("good"); - else - System.out.println("bad"); - } - fc.close(); - fos.close(); } - } diff --git a/jdk/test/java/nio/file/Files/probeContentType/Basic.java b/jdk/test/java/nio/file/Files/probeContentType/Basic.java index 003f9494f11..9786c701451 100644 --- a/jdk/test/java/nio/file/Files/probeContentType/Basic.java +++ b/jdk/test/java/nio/file/Files/probeContentType/Basic.java @@ -95,7 +95,7 @@ public class Basic { return 0; } - static int checkContentTypes(String[] extensions, String[][] expectedTypes) + static int checkContentTypes(String[] extensions, String[] expectedTypes) throws IOException { if (extensions.length != expectedTypes.length) { System.err.println("Parameter array lengths differ"); @@ -112,27 +112,10 @@ public class Basic { System.err.println("Content type of " + extension + " cannot be determined"); failures++; - } else { - boolean isTypeFound = false; - for (String s : expectedTypes[i]) { - if (type.equals(s)) { - isTypeFound = true; - break; - } - } - if (!isTypeFound) { - System.err.printf("Content type: %s; expected: ", type); - int j = 0; - for (String s : expectedTypes[i]) { - if (j++ == 0) { - System.err.printf("%s", s); - } else { - System.err.printf(", or %s", s); - } - } - System.err.println(); - failures++; - } + } else if (!type.equals(expectedTypes[i])) { + System.err.printf("Content type: %s; expected: %s%n", + type, expectedTypes); + failures++; } } finally { Files.delete(file); @@ -174,8 +157,6 @@ public class Basic { // Verify that certain media extensions are mapped to the correct type. String[] extensions = new String[]{ - "aac", - "flac", "jpg", "mp3", "mp4", @@ -183,15 +164,13 @@ public class Basic { "png", "webm" }; - String[][] expectedTypes = new String[][] { - {"audio/aac", "audio/x-aac", "audio/vnd.dlna.adts"}, - {"audio/flac", "audio/x-flac"}, - {"image/jpeg"}, - {"audio/mpeg"}, - {"video/mp4"}, - {"application/pdf"}, - {"image/png"}, - {"video/webm"} + String[] expectedTypes = new String[] { + "image/jpeg", + "audio/mpeg", + "video/mp4", + "application/pdf", + "image/png", + "video/webm" }; failures += checkContentTypes(extensions, expectedTypes); diff --git a/jdk/test/java/nio/file/Path/PathOps.java b/jdk/test/java/nio/file/Path/PathOps.java index f9964e5f55f..69d0c85e4a8 100644 --- a/jdk/test/java/nio/file/Path/PathOps.java +++ b/jdk/test/java/nio/file/Path/PathOps.java @@ -197,6 +197,19 @@ public class PathOps { return this; } + PathOps relativizeFail(String other) { + out.format("test relativize %s\n", other); + checkPath(); + Path that = FileSystems.getDefault().getPath(other); + try { + Path result = path.relativize(that); + out.format("\tExpected: IllegalArgumentException"); + out.format("\tActual: %s\n", result); + fail(); + } catch (IllegalArgumentException expected) { } + return this; + } + PathOps normalize(String expected) { out.println("check normalized path"); checkPath(); @@ -572,29 +585,709 @@ public class PathOps { .resolveSibling("C:\\", "C:\\"); // relativize - test("foo") - .relativize("foo", "") - .relativize("bar", "..\\bar") - .relativize("..", "..\\..") - .relativize("", ".."); - test("foo\\bar") - .relativize("foo\\bar", "") - .relativize("foo", "..") - .relativize("gus", "..\\..\\gus") - .relativize("..", "..\\..\\..") - .relativize("", "..\\.."); + test("C:\\a") + .relativize("C:\\a", "") + .relativize("C:\\", "..") + .relativize("C:\\.", "..") + .relativize("C:\\..", "..") + .relativize("C:\\..\\..", "..") + .relativize("C:\\a\\b", "b") + .relativize("C:\\a\\b\\c", "b\\c") + .relativize("C:\\a\\.", "") // "." also valid + .relativize("C:\\a\\..", "..") + .relativize("C:\\x", "..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\a\\b") + .relativize("C:\\a\\b", "") + .relativize("C:\\a", "..") + .relativize("C:\\", "..\\..") + .relativize("C:\\.", "..\\..") + .relativize("C:\\..", "..\\..") + .relativize("C:\\..\\..", "..\\..") + .relativize("C:\\a\\b\\c", "c") + .relativize("C:\\a\\.", "..") + .relativize("C:\\a\\..", "..\\..") + .relativize("C:\\x", "..\\..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); test("C:\\a\\b\\c") - .relativize("C:\\a", "..\\..") .relativize("C:\\a\\b\\c", "") - .relativize("C:\\x", "..\\..\\..\\x"); - test("\\\\server\\share\\foo") - .relativize("\\\\server\\share\\bar", "..\\bar") - .relativize("\\\\server\\share\\foo", ""); + .relativize("C:\\a\\b", "..") + .relativize("C:\\a", "..\\..") + .relativize("C:\\", "..\\..\\..") + .relativize("C:\\.", "..\\..\\..") + .relativize("C:\\..", "..\\..\\..") + .relativize("C:\\..\\..", "..\\..\\..") + .relativize("C:\\..\\..\\..", "..\\..\\..") + .relativize("C:\\..\\..\\..\\..", "..\\..\\..") + .relativize("C:\\a\\b\\c\\d", "d") + .relativize("C:\\a\\b\\c\\d\\e", "d\\e") + .relativize("C:\\a\\b\\c\\.", "") // "." also valid + .relativize("C:\\a\\b\\c\\..", "..") + .relativize("C:\\a\\x", "..\\..\\x") + .relativize("C:\\x", "..\\..\\..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\..\\a") + .relativize("C:\\a", "") + .relativize("C:\\", "..") + .relativize("C:\\.", "..") + .relativize("C:\\..", "..") + .relativize("C:\\..\\..", "..") + .relativize("C:\\a\\b", "b") + .relativize("C:\\a\\b\\c", "b\\c") + .relativize("C:\\a\\.", "") // "." also valid + .relativize("C:\\a\\..", "..") + .relativize("C:\\x", "..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\..\\a\\b") + .relativize("C:\\a\\b", "") + .relativize("C:\\a", "..") + .relativize("C:\\", "..\\..") + .relativize("C:\\.", "..\\..") + .relativize("C:\\..", "..\\..") + .relativize("C:\\..\\..", "..\\..") + .relativize("C:\\..\\..\\..", "..\\..") + .relativize("C:\\..\\..\\..\\..", "..\\..") + .relativize("C:\\a\\b\\c", "c") + .relativize("C:\\a\\b\\.", "") // "." also valid + .relativize("C:\\a\\b\\..", "..") + .relativize("C:\\a\\x", "..\\x") + .relativize("C:\\x", "..\\..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\..\\..\\a\\b") + .relativize("C:\\a\\b", "") + .relativize("C:\\a", "..") + .relativize("C:\\", "..\\..") + .relativize("C:\\.", "..\\..") + .relativize("C:\\..", "..\\..") + .relativize("C:\\..\\..", "..\\..") + .relativize("C:\\..\\..\\..", "..\\..") + .relativize("C:\\..\\..\\..\\..", "..\\..") + .relativize("C:\\a\\b\\c", "c") + .relativize("C:\\a\\b\\.", "") // "." also valid + .relativize("C:\\a\\b\\..", "..") + .relativize("C:\\a\\x", "..\\x") + .relativize("C:\\x", "..\\..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\..\\a\\b\\c") + .relativize("C:\\a\\b\\c", "") + .relativize("C:\\a\\b", "..") + .relativize("C:\\a", "..\\..") + .relativize("C:\\", "..\\..\\..") + .relativize("C:\\.", "..\\..\\..") + .relativize("C:\\..", "..\\..\\..") + .relativize("C:\\..\\..", "..\\..\\..") + .relativize("C:\\..\\..\\..", "..\\..\\..") + .relativize("C:\\..\\..\\..\\..", "..\\..\\..") + .relativize("C:\\a\\b\\c\\d", "d") + .relativize("C:\\a\\b\\c\\d\\e", "d\\e") + .relativize("C:\\a\\b\\c\\.", "") // "." also valid + .relativize("C:\\a\\b\\c\\..", "..") + .relativize("C:\\a\\x", "..\\..\\x") + .relativize("C:\\x", "..\\..\\..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\..\\..\\a\\b\\c") + .relativize("C:\\a\\b\\c", "") + .relativize("C:\\a\\b", "..") + .relativize("C:\\a", "..\\..") + .relativize("C:\\", "..\\..\\..") + .relativize("C:\\.", "..\\..\\..") + .relativize("C:\\..", "..\\..\\..") + .relativize("C:\\..\\..", "..\\..\\..") + .relativize("C:\\..\\..\\..", "..\\..\\..") + .relativize("C:\\..\\..\\..\\..", "..\\..\\..") + .relativize("C:\\a\\b\\c\\d", "d") + .relativize("C:\\a\\b\\c\\d\\e", "d\\e") + .relativize("C:\\a\\b\\c\\.", "") // "." also valid + .relativize("C:\\a\\b\\c\\..", "..") + .relativize("C:\\a\\x", "..\\..\\x") + .relativize("C:\\x", "..\\..\\..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\..\\..\\..\\a\\b\\c") + .relativize("C:\\a\\b\\c", "") + .relativize("C:\\a\\b", "..") + .relativize("C:\\a", "..\\..") + .relativize("C:\\", "..\\..\\..") + .relativize("C:\\.", "..\\..\\..") + .relativize("C:\\..", "..\\..\\..") + .relativize("C:\\..\\..", "..\\..\\..") + .relativize("C:\\..\\..\\..", "..\\..\\..") + .relativize("C:\\..\\..\\..\\..", "..\\..\\..") + .relativize("C:\\a\\b\\c\\d", "d") + .relativize("C:\\a\\b\\c\\d\\e", "d\\e") + .relativize("C:\\a\\b\\c\\.", "") // "." also valid + .relativize("C:\\a\\b\\c\\..", "..") + .relativize("C:\\a\\x", "..\\..\\x") + .relativize("C:\\x", "..\\..\\..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\.\\a") + .relativize("C:\\a", "") + .relativize("C:\\", "..") + .relativize("C:\\.", "..") + .relativize("C:\\..", "..") + .relativize("C:\\..\\..", "..") + .relativize("C:\\a\\b", "b") + .relativize("C:\\a\\b\\c", "b\\c") + .relativize("C:\\a\\.", "") // "." also valid + .relativize("C:\\a\\..", "..") + .relativize("C:\\x", "..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\..\\a") + .relativize("C:\\a", "") + .relativize("C:\\", "..") + .relativize("C:\\.", "..") + .relativize("C:\\..", "..") + .relativize("C:\\..\\..", "..") + .relativize("C:\\a\\b", "b") + .relativize("C:\\a\\b\\c", "b\\c") + .relativize("C:\\a\\.", "") // "." also valid + .relativize("C:\\a\\..", "..") + .relativize("C:\\x", "..\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:\\a\\..") + .relativize("C:\\a", "a") + .relativize("C:\\", "") // "." is also valid + .relativize("C:\\.", "") + .relativize("C:\\..", "") + .relativize("C:\\..\\..", "") + .relativize("C:\\a\\.", "a") + .relativize("C:\\a\\..", "") + .relativize("C:\\x", "x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("C:a") + .relativize("C:a", "") + .relativize("C:", "..") + .relativize("C:.", "..") + .relativize("C:..", "..\\..") + .relativize("C:..\\..", "..\\..\\..") + .relativize("C:.\\..", "..\\..") + .relativize("C:a\\b", "b") + .relativize("C:a\\b\\c", "b\\c") + .relativize("C:..\\x", "..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("\\x"); + test("C:a\\b") + .relativize("C:a\\b", "") + .relativize("C:a", "..") + .relativize("C:", "..\\..") + .relativize("C:.", "..\\..") + .relativize("C:..", "..\\..\\..") + .relativize("C:..\\..", "..\\..\\..\\..") + .relativize("C:.\\..", "..\\..\\..") + .relativize("C:a\\b\\c", "c") + .relativize("C:..\\x", "..\\..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("\\x"); + test("C:a\\b\\c") + .relativize("C:a\\b\\c", "") + .relativize("C:a\\b", "..") + .relativize("C:a", "..\\..") + .relativize("C:", "..\\..\\..") + .relativize("C:.", "..\\..\\..") + .relativize("C:..", "..\\..\\..\\..") + .relativize("C:..\\..", "..\\..\\..\\..\\..") + .relativize("C:.\\..", "..\\..\\..\\..") + .relativize("C:a\\b\\c\\d", "d") + .relativize("C:a\\b\\c\\d\\e", "d\\e") + .relativize("C:a\\x", "..\\..\\x") + .relativize("C:..\\x", "..\\..\\..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("x") + .relativizeFail("\\") + .relativizeFail("\\x"); + test("C:") + .relativize("C:a", "a") + .relativize("C:a\\b\\c", "a\\b\\c") + .relativize("C:", "") + .relativize("C:.", "") // "" also valid + .relativize("C:..", "..") + .relativize("C:..\\..", "..\\..") + .relativize("C:.\\..", "..") + .relativizeFail("C:\\x") + .relativizeFail("\\") + .relativizeFail("\\x"); + test("C:..") + .relativize("C:..\\a", "a") + .relativize("C:..", "") + .relativize("C:.\\..", "") + .relativizeFail("C:\\x") + .relativizeFail("\\") + .relativizeFail("\\x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail("x"); + test("C:..\\a") + .relativize("C:..\\a\\b", "b") + .relativize("C:..\\a", "") + .relativize("C:..", "..") + .relativize("C:.\\..", "..") + .relativizeFail("C:\\x") + .relativizeFail("\\") + .relativizeFail("\\x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail("x"); + test("C:..\\a\\b") + .relativize("C:..\\a\\b\\c", "c") + .relativize("C:..\\a\\b", "") + .relativize("C:..\\a", "..") + .relativize("C:..", "..\\..") + .relativize("C:.\\..", "..\\..") + .relativizeFail("C:\\x") + .relativizeFail("\\") + .relativizeFail("\\x") + .relativizeFail("") + .relativizeFail("x"); + test("C:a\\..") + .relativize("C:b", "b") + .relativize("C:", "") + .relativize("C:.", "") // "." also valid + .relativize("C:..", "..") + .relativize("C:a\\..\\b", "b") + .relativize("C:a\\..", "") + .relativize("C:..\\b", "..\\b") + .relativize("C:b\\..", "") + .relativizeFail("C:\\x") + .relativizeFail("\\") + .relativizeFail("\\x") + .relativizeFail("x"); + test("C:a\\..\\b") + .relativize("C:a\\..\\b", "") + .relativize("C:a\\..", "..") + .relativize("C:", "..") + .relativize("C:.", "..") + .relativize("C:..", "..\\..") + .relativize("C:b", "") + .relativize("C:c", "..\\c") + .relativize("C:..\\c", "..\\..\\c") + .relativize("C:a\\..\\b\\c", "c") + .relativizeFail("C:\\x") + .relativizeFail("\\") + .relativizeFail("\\x") + .relativizeFail("x"); + test("\\a") + .relativize("\\a", "") + .relativize("\\", "..") + .relativize("\\.", "..") + .relativize("\\..", "..") + .relativize("\\..\\..", "..") + .relativize("\\a\\b", "b") + .relativize("\\a\\b\\c", "b\\c") + .relativize("\\a\\.", "") // "." also valid + .relativize("\\a\\..", "..") + .relativize("\\x", "..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\a\\b") + .relativize("\\a\\b", "") + .relativize("\\a", "..") + .relativize("\\", "..\\..") + .relativize("\\.", "..\\..") + .relativize("\\..", "..\\..") + .relativize("\\..\\..", "..\\..") + .relativize("\\a\\b\\c", "c") + .relativize("\\a\\.", "..") + .relativize("\\a\\..", "..\\..") + .relativize("\\x", "..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\a\\b\\c") + .relativize("\\a\\b\\c", "") + .relativize("\\a\\b", "..") + .relativize("\\a", "..\\..") + .relativize("\\", "..\\..\\..") + .relativize("\\.", "..\\..\\..") + .relativize("\\..", "..\\..\\..") + .relativize("\\..\\..", "..\\..\\..") + .relativize("\\..\\..\\..", "..\\..\\..") + .relativize("\\..\\..\\..\\..", "..\\..\\..") + .relativize("\\a\\b\\c\\d", "d") + .relativize("\\a\\b\\c\\d\\e", "d\\e") + .relativize("\\a\\b\\c\\.", "") // "." also valid + .relativize("\\a\\b\\c\\..", "..") + .relativize("\\a\\x", "..\\..\\x") + .relativize("\\x", "..\\..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\..\\a") + .relativize("\\a", "") + .relativize("\\", "..") + .relativize("\\.", "..") + .relativize("\\..", "..") + .relativize("\\..\\..", "..") + .relativize("\\a\\b", "b") + .relativize("\\a\\b\\c", "b\\c") + .relativize("\\a\\.", "") // "." also valid + .relativize("\\a\\..", "..") + .relativize("\\x", "..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\..\\a\\b") + .relativize("\\a\\b", "") + .relativize("\\a", "..") + .relativize("\\", "..\\..") + .relativize("\\.", "..\\..") + .relativize("\\..", "..\\..") + .relativize("\\..\\..", "..\\..") + .relativize("\\..\\..\\..", "..\\..") + .relativize("\\..\\..\\..\\..", "..\\..") + .relativize("\\a\\b\\c", "c") + .relativize("\\a\\b\\.", "") // "." also valid + .relativize("\\a\\b\\..", "..") + .relativize("\\a\\x", "..\\x") + .relativize("\\x", "..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\..\\..\\a\\b") + .relativize("\\a\\b", "") + .relativize("\\a", "..") + .relativize("\\", "..\\..") + .relativize("\\.", "..\\..") + .relativize("\\..", "..\\..") + .relativize("\\..\\..", "..\\..") + .relativize("\\..\\..\\..", "..\\..") + .relativize("\\..\\..\\..\\..", "..\\..") + .relativize("\\a\\b\\c", "c") + .relativize("\\a\\b\\.", "") // "." also valid + .relativize("\\a\\b\\..", "..") + .relativize("\\a\\x", "..\\x") + .relativize("\\x", "..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\..\\a\\b\\c") + .relativize("\\a\\b\\c", "") + .relativize("\\a\\b", "..") + .relativize("\\a", "..\\..") + .relativize("\\", "..\\..\\..") + .relativize("\\.", "..\\..\\..") + .relativize("\\..", "..\\..\\..") + .relativize("\\..\\..", "..\\..\\..") + .relativize("\\..\\..\\..", "..\\..\\..") + .relativize("\\..\\..\\..\\..", "..\\..\\..") + .relativize("\\a\\b\\c\\d", "d") + .relativize("\\a\\b\\c\\d\\e", "d\\e") + .relativize("\\a\\b\\c\\.", "") // "." also valid + .relativize("\\a\\b\\c\\..", "..") + .relativize("\\a\\x", "..\\..\\x") + .relativize("\\x", "..\\..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\..\\..\\a\\b\\c") + .relativize("\\a\\b\\c", "") + .relativize("\\a\\b", "..") + .relativize("\\a", "..\\..") + .relativize("\\", "..\\..\\..") + .relativize("\\.", "..\\..\\..") + .relativize("\\..", "..\\..\\..") + .relativize("\\..\\..", "..\\..\\..") + .relativize("\\..\\..\\..", "..\\..\\..") + .relativize("\\..\\..\\..\\..", "..\\..\\..") + .relativize("\\a\\b\\c\\d", "d") + .relativize("\\a\\b\\c\\d\\e", "d\\e") + .relativize("\\a\\b\\c\\.", "") // "." also valid + .relativize("\\a\\b\\c\\..", "..") + .relativize("\\a\\x", "..\\..\\x") + .relativize("\\x", "..\\..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\..\\..\\..\\a\\b\\c") + .relativize("\\a\\b\\c", "") + .relativize("\\a\\b", "..") + .relativize("\\a", "..\\..") + .relativize("\\", "..\\..\\..") + .relativize("\\.", "..\\..\\..") + .relativize("\\..", "..\\..\\..") + .relativize("\\..\\..", "..\\..\\..") + .relativize("\\..\\..\\..", "..\\..\\..") + .relativize("\\..\\..\\..\\..", "..\\..\\..") + .relativize("\\a\\b\\c\\d", "d") + .relativize("\\a\\b\\c\\d\\e", "d\\e") + .relativize("\\a\\b\\c\\.", "") // "." also valid + .relativize("\\a\\b\\c\\..", "..") + .relativize("\\a\\x", "..\\..\\x") + .relativize("\\x", "..\\..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\.\\a") + .relativize("\\a", "") + .relativize("\\", "..") + .relativize("\\.", "..") + .relativize("\\..", "..") + .relativize("\\..\\..", "..") + .relativize("\\a\\b", "b") + .relativize("\\a\\b\\c", "b\\c") + .relativize("\\a\\.", "") // "." also valid + .relativize("\\a\\..", "..") + .relativize("\\x", "..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\..\\a") + .relativize("\\a", "") + .relativize("\\", "..") + .relativize("\\.", "..") + .relativize("\\..", "..") + .relativize("\\..\\..", "..") + .relativize("\\a\\b", "b") + .relativize("\\a\\b\\c", "b\\c") + .relativize("\\a\\.", "") // "." also valid + .relativize("\\a\\..", "..") + .relativize("\\x", "..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\a\\..") + .relativize("\\a", "a") + .relativize("\\", "") // "." is also valid + .relativize("\\.", "") + .relativize("\\..", "") + .relativize("\\..\\..", "") + .relativize("\\a\\.", "a") + .relativize("\\a\\..", "") + .relativize("\\x", "x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("\\") + .relativize("\\a", "a") + .relativize("\\", "") // "." is also valid + .relativize("\\.", "") + .relativize("\\..", "") + .relativize("\\..\\..", "") + .relativize("\\a\\.", "a") + .relativize("\\a\\..", "") + .relativize("\\x", "x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("a") + .relativize("a", "") + .relativize("", "..") + .relativize(".", "..") + .relativize("..", "..\\..") + .relativize("..\\..", "..\\..\\..") + .relativize(".\\..", "..\\..") + .relativize("a\\b", "b") + .relativize("a\\b\\c", "b\\c") + .relativize("..\\x", "..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("\\") + .relativizeFail("\\x"); + test("a\\b") + .relativize("a\\b", "") + .relativize("a", "..") + .relativize("", "..\\..") + .relativize(".", "..\\..") + .relativize("..", "..\\..\\..") + .relativize("..\\..", "..\\..\\..\\..") + .relativize(".\\..", "..\\..\\..") + .relativize("a\\b\\c", "c") + .relativize("..\\x", "..\\..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("\\") + .relativizeFail("\\x"); + test("a\\b\\c") + .relativize("a\\b\\c", "") + .relativize("a\\b", "..") + .relativize("a", "..\\..") + .relativize("", "..\\..\\..") + .relativize(".", "..\\..\\..") + .relativize("..", "..\\..\\..\\..") + .relativize("..\\..", "..\\..\\..\\..\\..") + .relativize(".\\..", "..\\..\\..\\..") + .relativize("a\\b\\c\\d", "d") + .relativize("a\\b\\c\\d\\e", "d\\e") + .relativize("a\\x", "..\\..\\x") + .relativize("..\\x", "..\\..\\..\\..\\x") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("\\") + .relativizeFail("\\x"); test("") .relativize("a", "a") .relativize("a\\b\\c", "a\\b\\c") + .relativize("", "") + .relativize(".", ".") .relativize("..", "..") - .relativize("", ""); + .relativize("..\\..", "..\\..") + .relativize(".\\..", ".\\..") // ".." also valid + .relativizeFail("\\") + .relativizeFail("\\x"); + test("..") + .relativize("..\\a", "a") + .relativize("..", "") + .relativize(".\\..", "") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("\\") + .relativizeFail("\\x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail("x"); + test("..\\a") + .relativize("..\\a\\b", "b") + .relativize("..\\a", "") + .relativize("..", "..") + .relativize(".\\..", "..") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("\\") + .relativizeFail("\\x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail("x"); + test("..\\a\\b") + .relativize("..\\a\\b\\c", "c") + .relativize("..\\a\\b", "") + .relativize("..\\a", "..") + .relativize("..", "..\\..") + .relativize(".\\..", "..\\..") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("\\") + .relativizeFail("\\x") + .relativizeFail("") + .relativizeFail("x"); + test("a\\..") + .relativize("b", "b") + .relativize("", "") + .relativize(".", "") // "." also valid + .relativize("..", "..") + .relativize("a\\..\\b", "b") + .relativize("a\\..", "") + .relativize("..\\b", "..\\b") + .relativize("b\\..", "") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("\\") + .relativizeFail("\\x"); + test("a\\..\\b") + .relativize("a\\..\\b", "") + .relativize("a\\..", "..") + .relativize("", "..") + .relativize(".", "..") + .relativize("..", "..\\..") + .relativize("b", "") + .relativize("c", "..\\c") + .relativize("..\\c", "..\\..\\c") + .relativize("a\\..\\b\\c", "c") + .relativizeFail("C:\\x") + .relativizeFail("C:x") + .relativizeFail("\\") + .relativizeFail("\\x"); // normalize test("C:\\") @@ -971,20 +1664,324 @@ public class PathOps { .resolve("", ""); // relativize + test("/a") + .relativize("/a", "") + .relativize("/", "..") + .relativize("/.", "..") + .relativize("/..", "..") + .relativize("/../..", "..") + .relativize("/a/b", "b") + .relativize("/a/b/c", "b/c") + .relativize("/a/.", "") // "." also valid + .relativize("/a/..", "..") + .relativize("/x", "../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/a/b") + .relativize("/a/b", "") + .relativize("/a", "..") + .relativize("/", "../..") + .relativize("/.", "../..") + .relativize("/..", "../..") + .relativize("/../..", "../..") + .relativize("/a/b/c", "c") + .relativize("/a/.", "..") + .relativize("/a/..", "../..") + .relativize("/x", "../../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); test("/a/b/c") .relativize("/a/b/c", "") + .relativize("/a/b", "..") + .relativize("/a", "../..") + .relativize("/", "../../..") + .relativize("/.", "../../..") + .relativize("/..", "../../..") + .relativize("/../..", "../../..") + .relativize("/../../..", "../../..") + .relativize("/../../../..", "../../..") + .relativize("/a/b/c/d", "d") .relativize("/a/b/c/d/e", "d/e") + .relativize("/a/b/c/.", "") // "." also valid + .relativize("/a/b/c/..", "..") .relativize("/a/x", "../../x") - .relativize("/x", "../../../x"); + .relativize("/x", "../../../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/../a") + .relativize("/a", "") + .relativize("/", "..") + .relativize("/.", "..") + .relativize("/..", "..") + .relativize("/../..", "..") + .relativize("/a/b", "b") + .relativize("/a/b/c", "b/c") + .relativize("/a/.", "") // "." also valid + .relativize("/a/..", "..") + .relativize("/x", "../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/../a/b") + .relativize("/a/b", "") + .relativize("/a", "..") + .relativize("/", "../..") + .relativize("/.", "../..") + .relativize("/..", "../..") + .relativize("/../..", "../..") + .relativize("/../../..", "../..") + .relativize("/../../../..", "../..") + .relativize("/a/b/c", "c") + .relativize("/a/b/.", "") // "." also valid + .relativize("/a/b/..", "..") + .relativize("/a/x", "../x") + .relativize("/x", "../../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/../../a/b") + .relativize("/a/b", "") + .relativize("/a", "..") + .relativize("/", "../..") + .relativize("/.", "../..") + .relativize("/..", "../..") + .relativize("/../..", "../..") + .relativize("/../../..", "../..") + .relativize("/../../../..", "../..") + .relativize("/a/b/c", "c") + .relativize("/a/b/.", "") // "." also valid + .relativize("/a/b/..", "..") + .relativize("/a/x", "../x") + .relativize("/x", "../../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/../a/b/c") + .relativize("/a/b/c", "") + .relativize("/a/b", "..") + .relativize("/a", "../..") + .relativize("/", "../../..") + .relativize("/.", "../../..") + .relativize("/..", "../../..") + .relativize("/../..", "../../..") + .relativize("/../../..", "../../..") + .relativize("/../../../..", "../../..") + .relativize("/a/b/c/d", "d") + .relativize("/a/b/c/d/e", "d/e") + .relativize("/a/b/c/.", "") // "." also valid + .relativize("/a/b/c/..", "..") + .relativize("/a/x", "../../x") + .relativize("/x", "../../../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/../../a/b/c") + .relativize("/a/b/c", "") + .relativize("/a/b", "..") + .relativize("/a", "../..") + .relativize("/", "../../..") + .relativize("/.", "../../..") + .relativize("/..", "../../..") + .relativize("/../..", "../../..") + .relativize("/../../..", "../../..") + .relativize("/../../../..", "../../..") + .relativize("/a/b/c/d", "d") + .relativize("/a/b/c/d/e", "d/e") + .relativize("/a/b/c/.", "") // "." also valid + .relativize("/a/b/c/..", "..") + .relativize("/a/x", "../../x") + .relativize("/x", "../../../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/../../../a/b/c") + .relativize("/a/b/c", "") + .relativize("/a/b", "..") + .relativize("/a", "../..") + .relativize("/", "../../..") + .relativize("/.", "../../..") + .relativize("/..", "../../..") + .relativize("/../..", "../../..") + .relativize("/../../..", "../../..") + .relativize("/../../../..", "../../..") + .relativize("/a/b/c/d", "d") + .relativize("/a/b/c/d/e", "d/e") + .relativize("/a/b/c/.", "") // "." also valid + .relativize("/a/b/c/..", "..") + .relativize("/a/x", "../../x") + .relativize("/x", "../../../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/./a") + .relativize("/a", "") + .relativize("/", "..") + .relativize("/.", "..") + .relativize("/..", "..") + .relativize("/../..", "..") + .relativize("/a/b", "b") + .relativize("/a/b/c", "b/c") + .relativize("/a/.", "") // "." also valid + .relativize("/a/..", "..") + .relativize("/x", "../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/../a") + .relativize("/a", "") + .relativize("/", "..") + .relativize("/.", "..") + .relativize("/..", "..") + .relativize("/../..", "..") + .relativize("/a/b", "b") + .relativize("/a/b/c", "b/c") + .relativize("/a/.", "") // "." also valid + .relativize("/a/..", "..") + .relativize("/x", "../x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/a/..") + .relativize("/a", "a") + .relativize("/", "") // "." is also valid + .relativize("/.", "") + .relativize("/..", "") + .relativize("/../..", "") + .relativize("/a/.", "a") + .relativize("/a/..", "") + .relativize("/x", "x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("/") + .relativize("/a", "a") + .relativize("/", "") // "." is also valid + .relativize("/.", "") + .relativize("/..", "") + .relativize("/../..", "") + .relativize("/a/.", "a") + .relativize("/a/..", "") + .relativize("/x", "x") + .relativizeFail("x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail(".."); + test("a") + .relativize("a", "") + .relativize("", "..") + .relativize(".", "..") + .relativize("..", "../..") + .relativize("../..", "../../..") + .relativize("./..", "../..") + .relativize("a/b", "b") + .relativize("a/b/c", "b/c") + .relativize("../x", "../../x") + .relativizeFail("/") + .relativizeFail("/x"); + test("a/b") + .relativize("a/b", "") + .relativize("a", "..") + .relativize("", "../..") + .relativize(".", "../..") + .relativize("..", "../../..") + .relativize("../..", "../../../..") + .relativize("./..", "../../..") + .relativize("a/b/c", "c") + .relativize("../x", "../../../x") + .relativizeFail("/") + .relativizeFail("/x"); test("a/b/c") + .relativize("a/b/c", "") + .relativize("a/b", "..") + .relativize("a", "../..") + .relativize("", "../../..") + .relativize(".", "../../..") + .relativize("..", "../../../..") + .relativize("../..", "../../../../..") + .relativize("./..", "../../../..") .relativize("a/b/c/d", "d") + .relativize("a/b/c/d/e", "d/e") .relativize("a/x", "../../x") - .relativize("x", "../../../x") - .relativize("", "../../.."); + .relativize("../x", "../../../../x") + .relativizeFail("/") + .relativizeFail("/x"); test("") .relativize("a", "a") .relativize("a/b/c", "a/b/c") - .relativize("", ""); + .relativize("", "") + .relativize(".", ".") + .relativize("..", "..") + .relativize("../..", "../..") + .relativize("./..", "./..") // ".." also valid + .relativizeFail("/") + .relativizeFail("/x"); + test("..") + .relativize("../a", "a") + .relativize("..", "") + .relativize("./..", "") + .relativizeFail("/") + .relativizeFail("/x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail("x"); + test("../a") + .relativize("../a/b", "b") + .relativize("../a", "") + .relativize("..", "..") + .relativize("./..", "..") + .relativizeFail("/") + .relativizeFail("/x") + .relativizeFail("") + .relativizeFail(".") + .relativizeFail("x"); + test("../a/b") + .relativize("../a/b/c", "c") + .relativize("../a/b", "") + .relativize("../a", "..") + .relativize("..", "../..") + .relativize("./..", "../..") + .relativizeFail("/") + .relativizeFail("/x") + .relativizeFail("") + .relativizeFail("x"); + test("a/..") + .relativize("b", "b") + .relativize("", "") + .relativize(".", "") // "." also valid + .relativize("..", "..") + .relativize("a/../b", "b") + .relativize("a/..", "") + .relativize("../b", "../b") + .relativize("b/..", "") + .relativizeFail("/") + .relativizeFail("/x"); + test("a/../b") + .relativize("a/../b", "") + .relativize("a/..", "..") + .relativize("", "..") + .relativize(".", "..") + .relativize("..", "../..") + .relativize("b", "") + .relativize("c", "../c") + .relativize("../c", "../../c") + .relativize("a/../b/c", "c") + .relativizeFail("/") + .relativizeFail("/x"); // normalize test("/") diff --git a/jdk/test/java/nio/file/WatchService/LotsOfCancels.java b/jdk/test/java/nio/file/WatchService/LotsOfCancels.java index 66597f35535..c5008e3ba5c 100644 --- a/jdk/test/java/nio/file/WatchService/LotsOfCancels.java +++ b/jdk/test/java/nio/file/WatchService/LotsOfCancels.java @@ -53,10 +53,11 @@ public class LotsOfCancels { Path testDir = Paths.get(System.getProperty("test.dir", ".")); Path top = Files.createTempDirectory(testDir, "LotsOfCancels"); for (int i=1; i<=16; i++) { + int id = i; Path dir = Files.createDirectory(top.resolve("dir-" + i)); WatchService watcher = FileSystems.getDefault().newWatchService(); - pool.submit(() -> handle(dir, watcher)); - pool.submit(() -> poll(watcher)); + pool.submit(() -> handle(id, dir, watcher)); + pool.submit(() -> poll(id, watcher)); } } finally { pool.shutdown(); @@ -74,7 +75,8 @@ public class LotsOfCancels { * Stress the given WatchService, specifically the cancel method, in * the given directory. Closes the WatchService when done. */ - static void handle(Path dir, WatchService watcher) { + static void handle(int id, Path dir, WatchService watcher) { + System.out.printf("begin handle %d%n", id); try { try { Path file = dir.resolve("anyfile"); @@ -85,12 +87,15 @@ public class LotsOfCancels { key.cancel(); } } finally { + System.out.printf("WatchService %d closing ...%n", id); watcher.close(); + System.out.printf("WatchService %d closed %n", id); } } catch (Exception e) { e.printStackTrace(); failed = true; } + System.out.printf("end handle %d%n", id); } /** @@ -98,7 +103,8 @@ public class LotsOfCancels { * queue drained, it also hogs a CPU core which seems necessary to * tickle the original bug. */ - static void poll(WatchService watcher) { + static void poll(int id, WatchService watcher) { + System.out.printf("begin poll %d%n", id); try { for (;;) { WatchKey key = watcher.take(); @@ -108,10 +114,12 @@ public class LotsOfCancels { } } } catch (ClosedWatchServiceException expected) { - // nothing to do + // nothing to do but print + System.out.printf("poll %d expected exception %s%n", id, expected); } catch (Exception e) { e.printStackTrace(); failed = true; } + System.out.printf("end poll %d%n", id); } } diff --git a/jdk/test/java/nio/file/WatchService/UpdateInterference.java b/jdk/test/java/nio/file/WatchService/UpdateInterference.java index 5bd88121795..93219d18edb 100644 --- a/jdk/test/java/nio/file/WatchService/UpdateInterference.java +++ b/jdk/test/java/nio/file/WatchService/UpdateInterference.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,9 @@ import java.util.concurrent.TimeUnit; import static java.nio.file.StandardWatchEventKinds.*; public class UpdateInterference { + + private static volatile boolean stop; + public static void main(String[] args) throws IOException, InterruptedException { final Path root = Files.createTempDirectory("test"); final Path foo = root.resolve("foo"); @@ -43,64 +46,89 @@ public class UpdateInterference { Files.createDirectory(bar); Files.createDirectory(baz); - final WatchService watcher = root.getFileSystem().newWatchService(); - final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE); - final WatchKey barKey = bar.register(watcher, ENTRY_CREATE); + try (final WatchService watcher = root.getFileSystem().newWatchService()) { + final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE); + final WatchKey barKey = bar.register(watcher, ENTRY_CREATE); - new Thread() { - { setDaemon(true); } + Thread t1 = null; + Thread t2 = null; + try { + t1 = new Thread() { - @Override - public void run() { - while (true) { - try { - final Path temp = Files.createTempFile(foo, "temp", ".tmp"); - Files.delete(temp); - Thread.sleep(10); - } catch (IOException | InterruptedException e) { - throw new RuntimeException(e); - } - } - } - }.start(); - - new Thread() { - { setDaemon(true); } - - @Override - public void run() { - WatchKey bazKeys[] = new WatchKey[32]; - while (true) { - try { - for( int i = 0; i < bazKeys.length; i++) { - bazKeys[i] = baz.register(watcher, ENTRY_CREATE); + @Override + public void run() { + while (!stop) { + try { + final Path temp = Files.createTempFile(foo, "temp", ".tmp"); + Files.delete(temp); + Thread.sleep(10); + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } } - for( int i = 0; i < bazKeys.length; i++) { - bazKeys[i].cancel(); - } - Thread.sleep(1); - } catch (IOException | InterruptedException e) { - throw new RuntimeException(e); } + }; + + t2 = new Thread() { + + @Override + public void run() { + WatchKey bazKeys[] = new WatchKey[32]; + while (!stop) { + try { + for( int i = 0; i < bazKeys.length; i++) { + bazKeys[i] = baz.register(watcher, ENTRY_CREATE); + } + for( int i = 0; i < bazKeys.length; i++) { + bazKeys[i].cancel(); + } + Thread.sleep(1); + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } + } + }; + + t1.start(); + t2.start(); + + long time = System.currentTimeMillis(); + while ((System.currentTimeMillis() - time) < 15000) { + final WatchKey key = watcher.poll(60, TimeUnit.SECONDS); + if (key == null) continue; + + if (key != fooKey) { + List> pollEvents = key.pollEvents(); + for (WatchEvent watchEvent : pollEvents) { + System.out.println(watchEvent.count() + " " + + watchEvent.kind() + " " + + watchEvent.context()); + } + throw new RuntimeException("Event received for unexpected key"); + } + key.reset(); + } + } finally { + // the threads should stop before WatchService is closed + // to avoid ClosedWatchServiceException + stop = true; + + // wait for threads to finish + if (t1 != null) { + t1.join(); + } + + if (t2 != null) { + t2.join(); } } - }.start(); - - long time = System.currentTimeMillis(); - while ((System.currentTimeMillis() - time) < 15000) { - final WatchKey key = watcher.poll(60, TimeUnit.SECONDS); - if (key == null) continue; - - if (key != fooKey) { - List> pollEvents = key.pollEvents(); - for (WatchEvent watchEvent : pollEvents) { - System.out.println(watchEvent.count() + " " + - watchEvent.kind() + " " + - watchEvent.context()); - } - throw new RuntimeException("Event received for unexpected key"); - } - key.reset(); + } finally { + // clean up + Files.delete(foo); + Files.delete(bar); + Files.delete(baz); + Files.delete(root); } } } diff --git a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java index c121079dae6..76466431033 100644 --- a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java +++ b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -419,6 +419,21 @@ public class TCKZoneOffset extends AbstractDateTimeTest { ZoneOffset.ofHoursMinutesSeconds(-19, 0, 0); } + @Test(expectedExceptions=DateTimeException.class) + public void test_factory_int_hours_minutes_seconds_minutesMinValue() { + ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, -1); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_factory_int_hours_minutes_seconds_secondsMinValue() { + ZoneOffset.ofHoursMinutesSeconds(0, 0, Integer.MIN_VALUE); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_factory_int_hours_minutes_seconds_minutesAndSecondsMinValue() { + ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, Integer.MIN_VALUE); + } + //----------------------------------------------------------------------- @Test public void test_factory_ofTotalSeconds() { @@ -437,6 +452,11 @@ public class TCKZoneOffset extends AbstractDateTimeTest { ZoneOffset.ofTotalSeconds(-18 * 60 * 60 - 1); } + @Test(expectedExceptions=DateTimeException.class) + public void test_factory_ofTotalSeconds_minValue() { + ZoneOffset.ofTotalSeconds(Integer.MIN_VALUE); + } + //----------------------------------------------------------------------- // from() //----------------------------------------------------------------------- diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java index c521b7edd58..26095ad1bb0 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java @@ -359,6 +359,21 @@ public class ConcurrentHashMapTest extends JSR166TestCase { assertTrue(s.contains(five)); } + /** + * Test keySet().removeAll on empty map + */ + public void testKeySet_empty_removeAll() { + ConcurrentHashMap map = new ConcurrentHashMap<>(); + Set set = map.keySet(); + set.removeAll(Collections.emptyList()); + assertTrue(map.isEmpty()); + assertTrue(set.isEmpty()); + // following is test for JDK-8163353 + set.removeAll(Collections.emptySet()); + assertTrue(map.isEmpty()); + assertTrue(set.isEmpty()); + } + /** * keySet.toArray returns contains all keys */ diff --git a/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java b/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java index bae8265be67..4ea94150844 100644 --- a/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java +++ b/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java @@ -80,7 +80,7 @@ public class MultiReleaseJarAPI { } try (JarFile jf = new JarFile(multirelease)) { - Assert.assertFalse(jf.isMultiRelease()); + Assert.assertTrue(jf.isMultiRelease()); } try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Runtime.version())) { diff --git a/jdk/test/javax/crypto/CryptoPermissions/TestUnlimited.java b/jdk/test/javax/crypto/CryptoPermissions/TestUnlimited.java new file mode 100644 index 00000000000..e6a8f7f37cc --- /dev/null +++ b/jdk/test/javax/crypto/CryptoPermissions/TestUnlimited.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8061842 + * @summary Package jurisdiction policy files as something other than JAR + * @run main/othervm TestUnlimited "" exception + * @run main/othervm TestUnlimited limited fail + * @run main/othervm TestUnlimited unlimited pass + * @run main/othervm TestUnlimited unlimited/ pass + * @run main/othervm TestUnlimited NosuchDir exception + * @run main/othervm TestUnlimited . exception + * @run main/othervm TestUnlimited /tmp/unlimited exception + * @run main/othervm TestUnlimited ../policy/unlimited exception + * @run main/othervm TestUnlimited ./unlimited exception + * @run main/othervm TestUnlimited /unlimited exception + */ +import javax.crypto.*; +import java.security.Security; + +public class TestUnlimited { + + public static void main(String[] args) throws Exception { + /* + * Override the Security property to allow for unlimited policy. + * Would need appropriate permissions if Security Manager were + * active. + */ + if (args.length != 2) { + throw new Exception("Two args required"); + } + + boolean expected = args[1].equals("pass"); + boolean exception = args[1].equals("exception"); + boolean result = false; + + System.out.println("Testing: " + args[0]); + + if (args[0].equals("\"\"")) { + Security.setProperty("crypto.policy", ""); + } else { + Security.setProperty("crypto.policy", args[0]); + } + + /* + * Use the AES as the test Cipher + * If there is an error initializing, we will never get past here. + */ + try { + int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES"); + System.out.println("max AES key len:" + maxKeyLen); + if (maxKeyLen > 128) { + System.out.println("Unlimited policy is active"); + result = true; + } else { + System.out.println("Unlimited policy is NOT active"); + result = false; + } + } catch (Throwable e) { + if (!exception) { + throw new Exception(); + } + } + + System.out.println( + "Expected:\t" + expected + "\nResult:\t\t" + result); + if (expected != result) { + throw new Exception(); + } + + System.out.println("DONE!"); + } +} diff --git a/jdk/test/javax/xml/crypto/dsig/SecureValidationPolicy.java b/jdk/test/javax/xml/crypto/dsig/SecureValidationPolicy.java new file mode 100644 index 00000000000..53642c02bcf --- /dev/null +++ b/jdk/test/javax/xml/crypto/dsig/SecureValidationPolicy.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8151893 + * @summary Tests for the jdk.xml.dsig.secureValidationPolicy security property + * @modules java.xml.crypto/org.jcp.xml.dsig.internal.dom + */ + +import java.security.Security; +import java.util.List; +import org.jcp.xml.dsig.internal.dom.Policy; + +public class SecureValidationPolicy { + + public static void main(String[] args) throws Exception { + + List restrictedSchemes = List.of("file:/tmp/foo", + "http://java.com", "https://java.com"); + List restrictedAlgs = List.of( + "http://www.w3.org/TR/1999/REC-xslt-19991116", + "http://www.w3.org/2001/04/xmldsig-more#rsa-md5", + "http://www.w3.org/2001/04/xmldsig-more#hmac-md5", + "http://www.w3.org/2001/04/xmldsig-more#md5"); + + // Test expected defaults + System.out.println("Testing defaults"); + if (!Policy.restrictNumTransforms(6)) { + throw new Exception("maxTransforms not enforced"); + } + if (!Policy.restrictNumReferences(31)) { + throw new Exception("maxReferences not enforced"); + } + for (String scheme : restrictedSchemes) { + if (!Policy.restrictReferenceUriScheme(scheme)) { + throw new Exception(scheme + " scheme not restricted"); + } + } + for (String alg : restrictedAlgs) { + if (!Policy.restrictAlg(alg)) { + throw new Exception(alg + " alg not restricted"); + } + } + if (!Policy.restrictDuplicateIds()) { + throw new Exception("noDuplicateIds not enforced"); + } + if (!Policy.restrictRetrievalMethodLoops()) { + throw new Exception("noRetrievalMethodLoops not enforced"); + } + } +} diff --git a/jdk/test/jdk/lambda/TEST.properties b/jdk/test/jdk/lambda/TEST.properties index 772348b784c..58528a633db 100644 --- a/jdk/test/jdk/lambda/TEST.properties +++ b/jdk/test/jdk/lambda/TEST.properties @@ -3,4 +3,4 @@ TestNG.dirs = . javatest.maxOutputSize = 250000 -modules = jdk.compiler +modules = jdk.compiler jdk.zipfs diff --git a/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java b/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java index 613a854faa2..a0a32fce292 100644 --- a/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java +++ b/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ * @summary Verify the defining class loader of each module never delegates * to its child class loader. Also sanity check java.compact2 * requires. + * @modules java.compact2 * @run testng/othervm --add-modules=ALL-SYSTEM VerifyModuleDelegation */ @@ -33,7 +34,9 @@ import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleFinder; import java.lang.module.ModuleReference; import java.lang.reflect.Layer; +import java.lang.reflect.Module; import java.util.Set; +import static java.util.stream.Collectors.toSet; import static java.lang.module.ModuleDescriptor.Requires.Modifier.*; @@ -58,8 +61,9 @@ public class VerifyModuleDelegation { .requires(Set.of(PUBLIC), "java.xml") .build(); - private static final Set MREFS - = ModuleFinder.ofSystem().findAll(); + private static final Set MREFS + = Layer.boot().modules().stream().map(Module::getDescriptor) + .collect(toSet()); private void check(ModuleDescriptor md, ModuleDescriptor ref) { assertTrue(md.requires().size() == ref.requires().size()); @@ -69,7 +73,7 @@ public class VerifyModuleDelegation { @Test public void checkJavaBase() { ModuleDescriptor md = - MREFS.stream().map(ModuleReference::descriptor) + MREFS.stream() .filter(d -> d.name().equals(JAVA_BASE)) .findFirst().orElseThrow(Error::new); @@ -78,7 +82,7 @@ public class VerifyModuleDelegation { @Test public void checkCompact2() { ModuleDescriptor md = - MREFS.stream().map(ModuleReference::descriptor) + MREFS.stream() .filter(d -> d.name().equals(JAVA_COMPACT2)) .findFirst().orElseThrow(Error::new); check(md, COMPACT2); @@ -87,7 +91,7 @@ public class VerifyModuleDelegation { @Test public void checkLoaderDelegation() { Layer boot = Layer.boot(); - MREFS.stream().map(ModuleReference::descriptor) + MREFS.stream() .forEach(md -> md.requires().stream().forEach(req -> { // check if M requires D and D's loader must be either the diff --git a/jdk/test/jdk/modules/scenarios/container/ContainerTest.java b/jdk/test/jdk/modules/scenarios/container/ContainerTest.java index 1ad5f352080..f56245413ac 100644 --- a/jdk/test/jdk/modules/scenarios/container/ContainerTest.java +++ b/jdk/test/jdk/modules/scenarios/container/ContainerTest.java @@ -26,6 +26,8 @@ * @library /lib/testlibrary * @modules jdk.jartool/sun.tools.jar * jdk.compiler + * jdk.zipfs + * java.se * @build ContainerTest CompilerUtils jdk.testlibrary.* * @run testng ContainerTest * @summary Starts a simple container that uses dynamic configurations diff --git a/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java b/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java index 6e483c6e21a..6c116010ee0 100644 --- a/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java +++ b/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java @@ -28,7 +28,7 @@ * @library /lib/testlibrary/java/util/jar * @build Compiler JarBuilder CreateMultiReleaseTestJars * @run testng MultiReleaseJarTest - * @modules java.compiler + * @modules jdk.compiler * jdk.jartool * jdk.zipfs */ diff --git a/jdk/test/jdk/nio/zipfs/jarfs/JFSTester.java b/jdk/test/jdk/nio/zipfs/jarfs/JFSTester.java new file mode 100644 index 00000000000..881e27dbd4f --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/jarfs/JFSTester.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8164389 + * @summary walk entries in a jdk.nio.zipfs.JarFileSystem + * @modules jdk.jartool/sun.tools.jar + * @run testng JFSTester + */ + +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class JFSTester { + private URI jarURI; + private Path jarfile; + + @BeforeClass + public void initialize() throws Exception { + String userdir = System.getProperty("user.dir","."); + jarfile = Paths.get(userdir, "test.jar"); + String srcdir = System.getProperty("test.src"); + String[] args = ( + "-cf " + + jarfile.toString() + + " -C " + + srcdir + + " root --release 9 -C " + + srcdir + + System.getProperty("file.separator") + + "v9 root" + ).split(" +"); + new sun.tools.jar.Main(System.out, System.err, "jar").run(args); + String ssp = jarfile.toUri().toString(); + jarURI = new URI("jar", ssp, null); + } + + @AfterClass + public void close() throws IOException { + Files.deleteIfExists(jarfile); + } + + @Test + public void testWalk() throws IOException { + + // no configuration, treat multi-release jar as unversioned + Map env = new HashMap<>(); + Set contents = doTest(env); + Set baseContents = Set.of( + "This is leaf 1.\n", + "This is leaf 2.\n", + "This is leaf 3.\n", + "This is leaf 4.\n" + ); + Assert.assertEquals(contents, baseContents); + + // a configuration and jar file is multi-release + env.put("multi-release", "9"); + contents = doTest(env); + Set versionedContents = Set.of( + "This is versioned leaf 1.\n", + "This is versioned leaf 2.\n", + "This is versioned leaf 3.\n", + "This is versioned leaf 4.\n" + ); + Assert.assertEquals(contents, versionedContents); + } + + private Set doTest(Map env) throws IOException { + Set contents; + try (FileSystem fs = FileSystems.newFileSystem(jarURI, env)) { + Path root = fs.getPath("root"); + contents = Files.walk(root) + .filter(p -> !Files.isDirectory(p)) + .map(this::pathToContents) + .collect(Collectors.toSet()); + } + return contents; + } + + private String pathToContents(Path path) { + try { + return new String(Files.readAllBytes(path)); + } catch (IOException x) { + throw new UncheckedIOException(x); + } + } +} diff --git a/jdk/test/jdk/nio/zipfs/jarfs/root/dir1/leaf1.txt b/jdk/test/jdk/nio/zipfs/jarfs/root/dir1/leaf1.txt new file mode 100644 index 00000000000..05f9592a818 --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/jarfs/root/dir1/leaf1.txt @@ -0,0 +1 @@ +This is leaf 1. diff --git a/jdk/test/jdk/nio/zipfs/jarfs/root/dir1/leaf2.txt b/jdk/test/jdk/nio/zipfs/jarfs/root/dir1/leaf2.txt new file mode 100644 index 00000000000..19229fa2322 --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/jarfs/root/dir1/leaf2.txt @@ -0,0 +1 @@ +This is leaf 2. diff --git a/jdk/test/jdk/nio/zipfs/jarfs/root/dir2/leaf3.txt b/jdk/test/jdk/nio/zipfs/jarfs/root/dir2/leaf3.txt new file mode 100644 index 00000000000..724fae66d88 --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/jarfs/root/dir2/leaf3.txt @@ -0,0 +1 @@ +This is leaf 3. diff --git a/jdk/test/jdk/nio/zipfs/jarfs/root/dir2/leaf4.txt b/jdk/test/jdk/nio/zipfs/jarfs/root/dir2/leaf4.txt new file mode 100644 index 00000000000..3fafaadeda0 --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/jarfs/root/dir2/leaf4.txt @@ -0,0 +1 @@ +This is leaf 4. diff --git a/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir1/leaf1.txt b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir1/leaf1.txt new file mode 100644 index 00000000000..9092c1883d3 --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir1/leaf1.txt @@ -0,0 +1 @@ +This is versioned leaf 1. diff --git a/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir1/leaf2.txt b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir1/leaf2.txt new file mode 100644 index 00000000000..9a2d266edf1 --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir1/leaf2.txt @@ -0,0 +1 @@ +This is versioned leaf 2. diff --git a/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir2/leaf3.txt b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir2/leaf3.txt new file mode 100644 index 00000000000..6491cae8b83 --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir2/leaf3.txt @@ -0,0 +1 @@ +This is versioned leaf 3. diff --git a/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir2/leaf4.txt b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir2/leaf4.txt new file mode 100644 index 00000000000..aa5563cb709 --- /dev/null +++ b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir2/leaf4.txt @@ -0,0 +1 @@ +This is versioned leaf 4. diff --git a/jdk/test/jdk/security/JavaDotSecurity/final_java_security b/jdk/test/jdk/security/JavaDotSecurity/final_java_security index cd39bea3560..f5d9c68933c 100644 --- a/jdk/test/jdk/security/JavaDotSecurity/final_java_security +++ b/jdk/test/jdk/security/JavaDotSecurity/final_java_security @@ -10,6 +10,7 @@ foo.5=8 foo.6=9a foo.7=10 foo.8=12 +crypto.policy=somepolicy package.access=sun.,\ solaris.,\ diff --git a/jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh b/jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh index aa1371f71cb..5dc58345fc3 100644 --- a/jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh +++ b/jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh @@ -46,7 +46,13 @@ if [ ! -f $TOOLSRC ]; then fi $JAVAC -d . $TOOLSRC -$JAVA $TOOLNAME $TESTSRC/raw_java_security outfile solaris sparc $TESTSRC/more_restricted +$JAVA $TOOLNAME \ + $TESTSRC/raw_java_security \ + outfile \ + solaris \ + sparc \ + somepolicy \ + $TESTSRC/more_restricted # On Windows, line end could be different. -b is a cross-platform option. -diff -b outfile $TESTSRC/final_java_security \ No newline at end of file +diff -b outfile $TESTSRC/final_java_security diff --git a/jdk/test/jdk/security/JavaDotSecurity/raw_java_security b/jdk/test/jdk/security/JavaDotSecurity/raw_java_security index 8a8a7d3cdde..9aa3c42e668 100644 --- a/jdk/test/jdk/security/JavaDotSecurity/raw_java_security +++ b/jdk/test/jdk/security/JavaDotSecurity/raw_java_security @@ -44,6 +44,7 @@ foo.tbd=11 #ifndef macosx-x64 foo.tbd=12 #endif +crypto.policy=crypto.policydir-tbd package.access=sun.,\ #ifdef solaris diff --git a/jdk/test/jdk/security/jarsigner/Spec.java b/jdk/test/jdk/security/jarsigner/Spec.java index a4853bf08c2..b36b90690df 100644 --- a/jdk/test/jdk/security/jarsigner/Spec.java +++ b/jdk/test/jdk/security/jarsigner/Spec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ * @modules java.base/sun.security.tools.keytool * java.base/sun.security.provider.certpath * jdk.jartool + * jdk.crypto.ec */ import com.sun.jarsigner.ContentSigner; diff --git a/jdk/test/sun/security/krb5/auto/BadKdc1.java b/jdk/test/sun/security/krb5/auto/BadKdc1.java index bc70c2a8b74..0ac77b60868 100644 --- a/jdk/test/sun/security/krb5/auto/BadKdc1.java +++ b/jdk/test/sun/security/krb5/auto/BadKdc1.java @@ -44,16 +44,16 @@ public class BadKdc1 { } BadKdc.go( - "121212222222(32){1,2}1222(32){1,2}", // 1 2 + "121212222222(32){1,3}1222(32){1,3}", // 1 2 // The above line means try kdc1 for 2 seconds then kdc1 // for 2 seconds... finally kdc3 for 2 seconds. - "1222(32){1,2}1222(32){1,2}", // 1 2 + "1222(32){1,3}1222(32){1,3}", // 1 2 // refresh - "121212222222(32){1,2}1222(32){1,2}", // 1 2 + "121212222222(32){1,3}1222(32){1,3}", // 1 2 // k3 off k2 on - "(122212(22){1,2}|1222323232-)", // 1 + "(122212(22){1,3}|1222323232-)", // 1 // k1 on - "(12(12){1,2}|122212|122232-)" // empty + "(12(12){1,3}|122212|122232-)" // empty ); } } diff --git a/jdk/test/sun/security/krb5/auto/BadKdc2.java b/jdk/test/sun/security/krb5/auto/BadKdc2.java index 4291d5c14c0..a490ca73c87 100644 --- a/jdk/test/sun/security/krb5/auto/BadKdc2.java +++ b/jdk/test/sun/security/krb5/auto/BadKdc2.java @@ -42,14 +42,14 @@ public class BadKdc2 { Security.setProperty( "krb5.kdc.bad.policy", "tryLess:2," + BadKdc.toReal(1000)); BadKdc.go( - "121212222222(32){1,2}11112121(32){1,2}", // 1 2 - "11112121(32){1,2}11112121(32){1,2}", // 1 2 + "121212222222(32){1,3}11112121(32){1,3}", // 1 2 + "11112121(32){1,3}11112121(32){1,3}", // 1 2 // refresh - "121212222222(32){1,2}11112121(32){1,2}", // 1 2 + "121212222222(32){1,3}11112121(32){1,3}", // 1 2 // k3 off k2 on - "1111(21){1,2}1111(22){1,2}", // 1 + "1111(21){1,3}1111(22){1,3}", // 1 // k1 on - "(11){1,2}(12){1,2}" // empty + "(11){1,3}(12){1,3}" // empty ); } } diff --git a/jdk/test/sun/security/krb5/auto/BadKdc4.java b/jdk/test/sun/security/krb5/auto/BadKdc4.java index 877e5400df9..8d64db2faca 100644 --- a/jdk/test/sun/security/krb5/auto/BadKdc4.java +++ b/jdk/test/sun/security/krb5/auto/BadKdc4.java @@ -37,12 +37,12 @@ public class BadKdc4 { throws Exception { Security.setProperty("krb5.kdc.bad.policy", ""); BadKdc.go( - "121212222222(32){1,2}121212222222(32){1,2}", - "121212222222(32){1,2}121212222222(32){1,2}", + "121212222222(32){1,3}121212222222(32){1,3}", + "121212222222(32){1,3}121212222222(32){1,3}", // refresh - "121212222222(32){1,2}121212222222(32){1,2}", + "121212222222(32){1,3}121212222222(32){1,3}", // k3 off k2 on - "121212(22){1,2}121212(22){1,2}", + "121212(22){1,3}121212(22){1,3}", // k1 on "(12){2,4}" ); diff --git a/jdk/test/sun/security/krb5/auto/KdcPolicy.java b/jdk/test/sun/security/krb5/auto/KdcPolicy.java new file mode 100644 index 00000000000..f4501a5779b --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/KdcPolicy.java @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.net.DatagramSocket; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.Security; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.security.auth.login.LoginException; +import sun.security.krb5.Asn1Exception; +import sun.security.krb5.Config; + +/* + * @test + * @bug 8164656 + * @run main/othervm KdcPolicy udp + * @run main/othervm KdcPolicy tcp + * @summary krb5.kdc.bad.policy test + */ +public class KdcPolicy { + + // Is this test on UDP? + static boolean udp; + + public static void main(String[] args) throws Exception { + + udp = args[0].equals("udp"); + + try { + main0(); + } catch (LoginException le) { + Throwable cause = le.getCause(); + if (cause instanceof Asn1Exception) { + System.out.println("Another process sends a packet to " + + "this server. Ignored."); + return; + } + throw le; + } + } + + static DebugMatcher cm = new DebugMatcher(); + + static void main0() throws Exception { + + System.setProperty("sun.security.krb5.debug", "true"); + + // One real KDC. Must be created before fake KDCs + // to read the TestHosts file. + OneKDC kdc = new OneKDC(null); + + // Two fake KDCs, d1 and d2 only listen but do not respond. + + if (udp) { + try (DatagramSocket d1 = new DatagramSocket(); + DatagramSocket d2 = new DatagramSocket()) { + run(d1.getLocalPort(), d2.getLocalPort(), kdc.getPort()); + } + } else { + try (ServerSocket d1 = new ServerSocket(0); + ServerSocket d2 = new ServerSocket(0)) { + run(d1.getLocalPort(), d2.getLocalPort(), kdc.getPort()); + } + } + } + + static void run(int p1, int p2, int p3) throws Exception { + + // cm.kdc() will return a and b for fake KDCs, and c for real KDC. + cm.addPort(-1).addPort(p1).addPort(p2).addPort(p3); + + System.setProperty("java.security.krb5.conf", "alternative-krb5.conf"); + + // Check default timeout is 30s. Use real KDC only, otherwise too + // slow to wait for timeout. + writeConf(-1, -1, p3); + test("c30000c30000"); + + // 1. Default policy is tryLast + //Security.setProperty("krb5.kdc.bad.policy", "tryLast"); + + // Need a real KDC, otherwise there is no last good. + // This test waste 3 seconds waiting for d1 to timeout. + // It is possible the real KDC cannot fulfil the request + // in 3s, so it might fail (either 1st time or 2nd time). + writeConf(1, 3000, p1, p3); + test("a3000c3000c3000|a3000c3000-|a3000c3000c3000-"); + + // If a test case won't use a real KDC, it can be sped up. + writeConf(3, 5, p1, p2); + test("a5a5a5b5b5b5-"); // default max_retries == 3 + test("a5a5a5b5b5b5-"); // all bad means no bad + + // 2. No policy. + Security.setProperty("krb5.kdc.bad.policy", ""); + Config.refresh(); + + // This case needs a real KDC, otherwise, all bad means no + // bad and we cannot tell the difference. This case waste 3 + // seconds on d1 to timeout twice. It is possible the real KDC + // cannot fulfil the request within 3s, so it might fail + // (either 1st time or 2nd time). + writeConf(1, 3000, p1, p3); + test("a3000c3000a3000c3000|a3000c3000-|a3000c3000a3000c3000-"); + + // 3. tryLess with no argument means tryLess:1,5000 + Security.setProperty("krb5.kdc.bad.policy", "tryLess"); + + // This case will waste 11s. We are checking that the default + // value of 5000 in tryLess is only used if it's less than timeout + // in krb5.conf + writeConf(1, 6000, p1); + test("a6000-"); // timeout in krb5.conf is 6s + test("a5000-"); // tryLess to 5s. This line can be made faster if + // d1 is a read KDC, but we have no existing method + // to start KDC on an existing ServerSocket (port). + + writeConf(-1, 4, p1, p2); + test("a4a4a4b4b4b4-"); // default max_retries == 3 + test("a4b4-"); // tryLess to 1. And since 4 < 5000, use 4. + Config.refresh(); + test("a4a4a4b4b4b4-"); + + writeConf(5, 4, p1, p2); + test("a4a4a4a4a4b4b4b4b4b4-"); // user-provided max_retries == 5 + test("a4b4-"); + Config.refresh(); + test("a4a4a4a4a4b4b4b4b4b4-"); + + // 3. tryLess with arguments + Security.setProperty("krb5.kdc.bad.policy", + "tryLess:2,5"); + + writeConf(-1, 6, p1, p2); + test("a6a6a6b6b6b6-"); // default max_retries == 3 + test("a5a5b5b5-"); // tryLess to 2 + Config.refresh(); + test("a6a6a6b6b6b6-"); + + writeConf(5, 4, p1, p2); + test("a4a4a4a4a4b4b4b4b4b4-"); // user-provided max_retries == 5 + test("a4a4b4b4-"); // tryLess to 2 + Config.refresh(); + test("a4a4a4a4a4b4b4b4b4b4-"); + } + + /** + * Writes a krb5.conf file. + * @param max max_retries, -1 if not set + * @param to kdc_timeout, -1 if not set + * @param ports where KDCs listen on + */ + static void writeConf(int max, int to, int... ports) throws Exception { + + // content of krb5.conf + String conf = ""; + + // Extra settings in [libdefaults] + String inDefaults = ""; + + // Extra settings in [realms] + String inRealm = ""; + + // We will randomly put extra settings only in [libdefaults], + // or in [realms] but with different values in [libdefaults], + // to prove that settings in [realms] override those in [libdefaults]. + Random r = new Random(); + + if (max > 0) { + if (r.nextBoolean()) { + inDefaults += "max_retries = " + max + "\n"; + } else { + inRealm += " max_retries = " + max + "\n"; + inDefaults += "max_retries = " + (max + 1) + "\n"; + } + } + + if (to > 0) { + if (r.nextBoolean()) { + inDefaults += "kdc_timeout = " + to + "\n"; + } else { + inRealm += " kdc_timeout = " + to + "\n"; + inDefaults += "kdc_timeout = " + (to + 1) + "\n"; + } + } + + if (udp) { + if (r.nextBoolean()) { + inDefaults += "udp_preference_limit = 10000\n"; + } else if (r.nextBoolean()) { + inRealm += " udp_preference_limit = 10000\n"; + inDefaults += "udp_preference_limit = 1\n"; + } // else no settings means UDP + } else { + if (r.nextBoolean()) { + inDefaults += "udp_preference_limit = 1\n"; + } else { + inRealm += " udp_preference_limit = 1\n"; + inDefaults += "udp_preference_limit = 10000\n"; + } + } + + conf = "[libdefaults]\n" + + "default_realm = " + OneKDC.REALM + "\n" + + inDefaults + + "\n" + + "[realms]\n" + + OneKDC.REALM + " = {\n"; + + for (int port : ports) { + conf += " kdc = " + OneKDC.KDCHOST + ":" + port + "\n" + + inRealm; + } + + conf += "}\n"; + + Files.write(Paths.get("alternative-krb5.conf"), conf.getBytes()); + Config.refresh(); + } + + /** + * One call of krb5 login. As long as the result matches one of expected, + * the test is considered as success. The grammar of expected is + * + * kdc#, timeout, kdc#, timeout, ..., optional "-" for failure + */ + static void test(String... expected) throws Exception { + + System.out.println("------------------TEST----------------------"); + PrintStream oldOut = System.out; + boolean failed = false; + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bo)); + try { + Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); + } catch (Exception e) { + failed = true; + } finally { + System.setOut(oldOut); + } + + String[] lines = new String(bo.toByteArray()).split("\n"); + StringBuilder sb = new StringBuilder(); + for (String line: lines) { + if (cm.match(line)) { + if (udp != cm.isUDP()) { + sb.append("x"); + } + sb.append(cm.kdc()).append(cm.timeout()); + } + } + if (failed) sb.append('-'); + + String output = sb.toString(); + + boolean found = false; + for (String ex : expected) { + if (output.matches(ex)) { + System.out.println("Expected: " + ex + ", actual " + output); + found = true; + break; + } + } + + if (!found) { + System.out.println("--------------- ERROR START -------------"); + System.out.println(new String(bo.toByteArray())); + System.out.println("--------------- ERROR END ---------------"); + throw new Exception("Does not match. Output is " + output); + } + } + + /** + * A helper class to match the krb5 debug output: + * >>> KDCCommunication: kdc=host UDP:11555, timeout=200,Attempt =1, #bytes=138 + * + * Example: + * DebugMatcher cm = new DebugMatcher(); + * cm.addPort(12345).addPort(11555); + * for (String line : debugOutput) { + * if (cm.match(line)) { + * System.out.printf("%c%d\n", cm.kdc(), cm.timeout()); + * // shows b200 for the example above + * } + * } + */ + static class DebugMatcher { + + static final Pattern re = Pattern.compile( + ">>> KDCCommunication: kdc=\\S+ (TCP|UDP):(\\d+), " + + "timeout=(\\d+),Attempt\\s*=(\\d+)"); + + List kdcPorts = new ArrayList<>(); + Matcher matcher; + + /** + * Add KDC ports one by one. See {@link #kdc()}. + */ + DebugMatcher addPort(int port) { + if (port > 0) { + kdcPorts.add(port); + } else { + kdcPorts.clear(); + } + return this; + } + + /** + * When a line matches the ">>> KDCCommunication:" pattern. After a + * match, the getters below can be called on this match. + */ + boolean match(String line) { + matcher = re.matcher(line); + return matcher.find(); + } + + /** + * Protocol of this match, "UDP" or "TCP". + */ + boolean isUDP() { + return matcher.group(1).equals("UDP"); + } + + /** + * KDC for this match, "a" for the one 1st added bt addPort(), "b" + * for second, etc. Undefined for not added. + */ + char kdc() { + int port = Integer.parseInt(matcher.group(2)); + return (char) (kdcPorts.indexOf(port) + 'a'); + } + + /** + * Timeout value for this match. + */ + int timeout() { + return Integer.parseInt(matcher.group(3)); + } + } +} diff --git a/jdk/test/sun/security/ssl/SSLSocketImpl/CloseSocket.java b/jdk/test/sun/security/ssl/SSLSocketImpl/CloseSocket.java index 4c532beb8ac..12bfb4ef001 100644 --- a/jdk/test/sun/security/ssl/SSLSocketImpl/CloseSocket.java +++ b/jdk/test/sun/security/ssl/SSLSocketImpl/CloseSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,67 +26,96 @@ * @bug 4674913 * @summary Verify that EOFException are correctly handled during the handshake * @author Andreas Sterbenz + * @run main/othervm CloseSocket */ -import java.io.*; -import java.net.*; - -import javax.net.ssl.*; +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; public class CloseSocket { - public static void main(String[] args) throws Exception { - final ServerSocket serverSocket = new ServerSocket(0); - int serverPort = serverSocket.getLocalPort(); - new Thread() { - public void run() { - try { - Socket s = serverSocket.accept(); - System.out.println("Server accepted connection"); - // wait a bit before closing the socket to give - // the client time to send its hello message - Thread.currentThread().sleep(100); - s.close(); - System.out.println("Server closed socket, done."); - } catch (Exception e) { - System.out.println("Server exception:"); - e.printStackTrace(); - } - } - }.start(); - SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault(); - SSLSocket socket = (SSLSocket)factory.createSocket("localhost", serverPort); - System.out.println("Client established TCP connection"); - boolean failed = false; - try { - System.out.println("Starting handshake..."); - socket.startHandshake(); - System.out.println("ERROR: no exception"); - failed = true; - } catch (IOException e) { - System.out.println("Failed as expected: " + e); - } - try { - System.out.println("Trying read..."); + private static ArrayList testCases = new ArrayList<>(); + + static { + testCases.add(socket -> socket.startHandshake()); + testCases.add(socket -> { InputStream in = socket.getInputStream(); - int b = in.read(); - System.out.println("ERROR: no exception, read: " + b); - failed = true; - } catch (IOException e) { - System.out.println("Failed as expected: " + e); - } - try { - System.out.println("Trying read..."); + in.read(); + }); + testCases.add(socket -> { OutputStream out = socket.getOutputStream(); out.write(43); - System.out.println("ERROR: no exception"); - failed = true; - } catch (IOException e) { - System.out.println("Failed as expected: " + e); - } - if (failed) { - throw new Exception("One or more tests failed"); + }); + } + + public static void main(String[] args) throws Exception { + try (Server server = new Server()) { + new Thread(server).start(); + + SocketFactory factory = SSLSocketFactory.getDefault(); + try (SSLSocket socket = (SSLSocket) factory.createSocket("localhost", + server.getPort())) { + socket.setSoTimeout(2000); + System.out.println("Client established TCP connection"); + boolean failed = false; + for (TestCase testCase : testCases) { + try { + testCase.test(socket); + System.out.println("ERROR: no exception"); + failed = true; + } catch (IOException e) { + System.out.println("Failed as expected: " + e); + } + } + if (failed) { + throw new Exception("One or more tests failed"); + } + } } } + static class Server implements AutoCloseable, Runnable { + + final ServerSocket serverSocket; + + Server() throws IOException { + serverSocket = new ServerSocket(0); + } + + public int getPort() { + return serverSocket.getLocalPort(); + } + + @Override + public void run() { + try (Socket s = serverSocket.accept()) { + System.out.println("Server accepted connection"); + // wait a bit before closing the socket to give + // the client time to send its hello message + Thread.currentThread().sleep(100); + s.close(); + System.out.println("Server closed socket, done."); + } catch (Exception e) { + throw new RuntimeException("Problem in test execution", e); + } + } + + @Override + public void close() throws Exception { + if (!serverSocket.isClosed()) { + serverSocket.close(); + } + } + } + + interface TestCase { + void test(SSLSocket socket) throws IOException; + } } diff --git a/jdk/test/tools/jlink/CustomPluginTest.java b/jdk/test/tools/jlink/CustomPluginTest.java index dc7a774ca51..aef3ace833e 100644 --- a/jdk/test/tools/jlink/CustomPluginTest.java +++ b/jdk/test/tools/jlink/CustomPluginTest.java @@ -67,6 +67,7 @@ public class CustomPluginTest { testHelloProvider(helper, pluginModulePath); testCustomPlugins(helper, pluginModulePath); + testModuleVerification(helper, pluginModulePath); } private void testCustomPlugins(Helper helper, Path pluginModulePath) { @@ -93,8 +94,7 @@ public class CustomPluginTest { String name = "customplugin"; Path src = Paths.get(System.getProperty("test.src")).resolve(name); Path classes = helper.getJmodClassesDir().resolve(name); - JImageGenerator.compile(src, classes, - "--add-exports", "jdk.jlink/jdk.tools.jlink.internal=customplugin"); + JImageGenerator.compile(src, classes); return JImageGenerator.getJModTask() .addClassPath(classes) .jmod(helper.getJmodDir().resolve(name + ".jmod")) @@ -136,4 +136,44 @@ public class CustomPluginTest { throw new AssertionError("Custom plugin not called"); } } + + private void testModuleVerification(Helper helper, Path pluginModulePath) throws IOException { + { + // dependent module missing check + String moduleName = "bar"; // 8147491 + Path jmodFoo = helper.generateDefaultJModule("foo").assertSuccess(); + Path jmodBar = helper.generateDefaultJModule(moduleName, "foo").assertSuccess(); + // rogue filter removes "foo" module resources which are + // required by "bar" module. Module checks after plugin + // application should detect and report error. + JImageGenerator.getJLinkTask() + .modulePath(helper.defaultModulePath()) + .pluginModulePath(pluginModulePath) + .output(helper.createNewImageDir(moduleName)) + .addMods(moduleName) + .option("--rogue-filter") + .option("/foo/") + .call() + .assertFailure("java.lang.module.ResolutionException"); + } + + { + // package exported by one module used as concealed package + // in another module. But, module-info.class is not updated! + String moduleName = "jdk.scripting.nashorn"; + JImageGenerator.getJLinkTask() + .modulePath(helper.defaultModulePath()) + .pluginModulePath(pluginModulePath) + .output(helper.createNewImageDir(moduleName)) + .addMods(moduleName) + // "java.logging" includes a package 'javax.script' + // which is an exported package from "java.scripting" module! + // module-info.class of java.logging left "as is". + .option("--rogue-adder") + .option("/java.logging/javax/script/Foo.class") + .call() + .assertFailure( + "Module java.logging's descriptor returns inconsistent package set"); + } + } } diff --git a/jdk/test/tools/jlink/ImageFileCreatorTest.java b/jdk/test/tools/jlink/ImageFileCreatorTest.java index 694bd898045..c88ae4bada1 100644 --- a/jdk/test/tools/jlink/ImageFileCreatorTest.java +++ b/jdk/test/tools/jlink/ImageFileCreatorTest.java @@ -220,7 +220,7 @@ public class ImageFileCreatorTest { }; ImagePluginStack stack = new ImagePluginStack(noopBuilder, Collections.emptyList(), - null); + null, false); ImageFileCreator.create(archives, ByteOrder.nativeOrder(), stack); } diff --git a/jdk/test/tools/jlink/customplugin/module-info.java b/jdk/test/tools/jlink/customplugin/module-info.java index 4b51ff86769..b2d9f237668 100644 --- a/jdk/test/tools/jlink/customplugin/module-info.java +++ b/jdk/test/tools/jlink/customplugin/module-info.java @@ -25,4 +25,6 @@ module customplugin { requires jdk.jlink; provides jdk.tools.jlink.plugin.Plugin with plugin.HelloPlugin; provides jdk.tools.jlink.plugin.Plugin with plugin.CustomPlugin; + provides jdk.tools.jlink.plugin.Plugin with plugin.RogueAdderPlugin; + provides jdk.tools.jlink.plugin.Plugin with plugin.RogueFilterPlugin; } diff --git a/jdk/test/tools/jlink/customplugin/plugin/RogueAdderPlugin.java b/jdk/test/tools/jlink/customplugin/plugin/RogueAdderPlugin.java new file mode 100644 index 00000000000..fe78a642940 --- /dev/null +++ b/jdk/test/tools/jlink/customplugin/plugin/RogueAdderPlugin.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package plugin; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.module.ModuleDescriptor; +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; +import jdk.tools.jlink.plugin.ResourcePool; +import jdk.tools.jlink.plugin.ResourcePoolBuilder; +import jdk.tools.jlink.plugin.ResourcePoolEntry; +import jdk.tools.jlink.plugin.ResourcePoolModule; +import jdk.tools.jlink.plugin.Plugin; + +/** + * Rogue adder plugin + */ +public final class RogueAdderPlugin implements Plugin { + public static final String NAME = "rogue-adder"; + private String resName; + + @Override + public String getName() { + return NAME; + } + + @Override + public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) { + in.transformAndCopy(Function.identity(), out); + out.add(ResourcePoolEntry.create(resName, new byte[1])); + return out.build(); + } + + @Override + public String getDescription() { + return NAME + "-description"; + } + + @Override + public Category getType() { + return Category.FILTER; + } + + @Override + public boolean hasArguments() { + return true; + } + + @Override + public void configure(Map config) { + resName = config.get(NAME); + } +} diff --git a/jdk/test/tools/jlink/customplugin/plugin/RogueFilterPlugin.java b/jdk/test/tools/jlink/customplugin/plugin/RogueFilterPlugin.java new file mode 100644 index 00000000000..ae4bf3f8183 --- /dev/null +++ b/jdk/test/tools/jlink/customplugin/plugin/RogueFilterPlugin.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package plugin; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Collections; +import java.util.Map; +import jdk.tools.jlink.plugin.ResourcePoolEntry; +import jdk.tools.jlink.plugin.ResourcePool; +import jdk.tools.jlink.plugin.ResourcePoolBuilder; +import jdk.tools.jlink.plugin.Plugin; + +/** + * Rogue filter plugin + */ +public final class RogueFilterPlugin implements Plugin { + public static final String NAME = "rogue-filter"; + private String prefix; + + @Override + public String getName() { + return NAME; + } + + @Override + public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) { + in.transformAndCopy((file) -> { + return file.path().startsWith(prefix)? null : file; + }, out); + return out.build(); + } + + @Override + public String getDescription() { + return NAME + "-description"; + } + + @Override + public Category getType() { + return Category.FILTER; + } + + @Override + public boolean hasArguments() { + return true; + } + + @Override + public void configure(Map config) { + prefix = config.get(NAME); + } +} diff --git a/jdk/test/tools/jlink/plugins/GenerateJLIClassesPluginTest.java b/jdk/test/tools/jlink/plugins/GenerateJLIClassesPluginTest.java index 53010cfa217..ae2d3ec5945 100644 --- a/jdk/test/tools/jlink/plugins/GenerateJLIClassesPluginTest.java +++ b/jdk/test/tools/jlink/plugins/GenerateJLIClassesPluginTest.java @@ -73,47 +73,6 @@ public class GenerateJLIClassesPluginTest { classFilesForSpecies(GenerateJLIClassesPlugin.defaultSpecies()), List.of()); - - // Test a valid set of options - result = JImageGenerator.getJLinkTask() - .modulePath(helper.defaultModulePath()) - .output(helper.createNewImageDir("generate-jli")) - .option("--generate-jli-classes=bmh:bmh-species=LL,L3") - .addMods("java.base") - .call(); - - image = result.assertSuccess(); - - JImageValidator.validate( - image.resolve("lib").resolve("modules"), - classFilesForSpecies(List.of("LL", "L3")), - classFilesForSpecies(List.of("L4"))); - - - // Test disabling BMH species generation - result = JImageGenerator.getJLinkTask() - .modulePath(helper.defaultModulePath()) - .output(helper.createNewImageDir("generate-jli")) - .option("--generate-jli-classes=not-bmh:bmh-species=LL,L3") - .addMods("java.base") - .call(); - - image = result.assertSuccess(); - JImageValidator.validate( - image.resolve("lib").resolve("modules"), - List.of(), - classFilesForSpecies(List.of("LL", "L3", "L4"))); - - - // Test an invalid set of options - result = JImageGenerator.getJLinkTask() - .modulePath(helper.defaultModulePath()) - .output(helper.createNewImageDir("generate-jli")) - .option("--generate-jli-classes=bmh:bmh-species=LL,L7V") - .addMods("java.base") - .call(); - - result.assertFailure(); } private static List classFilesForSpecies(List species) { diff --git a/jdk/test/tools/launcher/VersionCheck.java b/jdk/test/tools/launcher/VersionCheck.java index 10fce9781f9..afbde0782a3 100644 --- a/jdk/test/tools/launcher/VersionCheck.java +++ b/jdk/test/tools/launcher/VersionCheck.java @@ -82,6 +82,7 @@ public class VersionCheck extends TestHelper { "jcmd", "jconsole", "jcontrol", + "jdeprscan", "jdeps", "jimage", "jinfo", diff --git a/langtools/.hgtags b/langtools/.hgtags index 06cc131cdbd..4fdf92ea61c 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -375,3 +375,4 @@ e181909291981038b041ed4d22714c4760e049cd jdk-9+129 3665ebc22a42c8f33777ee025ba0e300e6086a8c jdk-9+130 aebfafc43714d5a27d5064d8a0011eaccde633cf jdk-9+131 2c17b65a37a8d7afdb9f96d5f11b28a3f21c78f2 jdk-9+132 +7efa4b3477b2b93edbdb4abf827b74c6391f056e jdk-9+133 diff --git a/langtools/make/CompileInterim.gmk b/langtools/make/CompileInterim.gmk index 06a13d92ba8..171c830fb1a 100644 --- a/langtools/make/CompileInterim.gmk +++ b/langtools/make/CompileInterim.gmk @@ -32,7 +32,7 @@ include JavaCompilation.gmk include SetupJavaCompilers.gmk ################################################################################ -# Setup the rules to build interim langtools, which is compiled by the boot +# Setup the rules to build interim langtools, which is compiled by the boot # javac and can be run on the boot jdk. This will be used to compile # the rest of the product. Each module is compiled separately to allow a modular # boot jdk to override system classes using -Xoverride:. @@ -45,7 +45,8 @@ define SetupInterimModule DISABLE_SJAVAC := true, \ SRC := $(LANGTOOLS_TOPDIR)/src/$(strip $1)/share/classes \ $$(wildcard $(SUPPORT_OUTPUTDIR)/gensrc/$(strip $1)), \ - EXCLUDES := sun com/sun/tools/jdeps com/sun/tools/javap, \ + EXCLUDES := sun com/sun/tools/jdeps com/sun/tools/javap \ + com/sun/tools/jdeprscan, \ EXCLUDE_FILES := module-info.java, \ COPY := .gif .png .xml .css .js javax.tools.JavaCompilerTool, \ BIN := $(BUILDTOOLS_OUTPUTDIR)/override_modules/$(strip $1), \ diff --git a/langtools/make/build.xml b/langtools/make/build.xml index c844103ed54..3fec57e54ef 100644 --- a/langtools/make/build.xml +++ b/langtools/make/build.xml @@ -88,18 +88,18 @@ - + - + - - + + + + +JDeprScan Internals +----- + +**EXPERIMENTAL OPTIONS** + + --Xload-class CLASSNAME + + Loads deprecation data from the class named CLASSNAME instead of from + the JDK image. + + --Xload-csv CVSFILE + + Loads deprecation data from file CSVFILE. + + --Xload-dir DIR + + Loads deprecation data from the class hierarchy rooted + at the directory named DIR. + + --Xload-jar JARFILE + + Loads deprecation data from the classes contained in the + jar file named JARFILE. + + --Xload-jdk9 JAVA_HOME + + Loads deprecation data from a modular JDK whose home + directory is at JAVA_HOME. This essentially adds the given + path to the system-modules location. + + --Xload-old-jdk JAVA_HOME + + Loads deprecation data from an old (non-modular) JDK whose + home directory is at JAVA_HOME. This essentially scans the + rt.jar file from that JDK. + + --Xload-self + + Loads deprecation data from the running JDK image by + traversing the entire jrt: filesystem. This differs from + -release 9, which traverses modules, packages, and classes by + starting from a set of root modules and using javax.lang.model + mechanisms (as opposed to filesystem mechanisms) for + traversing contained elements recursively. + + --Xcompiler-arg ARG + + Adds ARG to the list of arguments passed to the compiler. + + --Xcsv-comment COMMENT + + Adds a comment line containing COMMENT to the top of the CSV + that is emitted. Valid only when --Xprint-csv is + specified. More than one --Xcsv-comment option is permitted, + which will cause a corresponding number of comment lines to be + emitted to the CSV file. + + --Xprint-csv + + Prints out the loaded deprecation information in CSV format + to standard output. In this mode, no scanning is done, so + there must not be any additional directory, jar, or classname + arguments. + +**CSV FILE SYNTAX** + +The `-Xprint-csv` option causes **jdeprscan** to emit the loaded +deprecation data in CSV (comma-separated value) format. The general +syntax of CSV is documented in [RFC 4180][RFC] with supplemental +information in a [Wikipedia article][wiki]. + +The file is encoded in UTF-8. + +The file consists of a series of lines. Any of the standard line +separators CR (U+000D), LF (U+000A), or a CR immediately followed by +LF, are supported. Newlines are only supported between records and +are not supported within field values. + +Comment lines start with a `#` (U+0023) character in the first +column. The entire line is ignored up until the next line separator +sequence. + +Each line is divided into fields separated by the comma `,` (U+002C) +character. Horizontal whitespace is not treated specially; that is, +it is considered part of a field's value. An empty line is considered +to have one field which is the empty string. + +A field value that contains a comma or a quote quotation mark `"` +(U+0022) must be surrounded by quotation marks. The surrounding +quotation marks are not considered part of the field value. Any +quotation marks that are part of a field value must be repeated in +addition to being surrounded by quotation marks. + +It is a syntax error if a quotation mark appears within an unquoted field; +if a quoted field isn't immediately followed by a comma or line +separator; or if a quoted field is left unclosed at the end of the line. + +For example, a record with the following four fields: + +1. abcd +2. ef,gh +3. ij"kl +4. mnop + +would be encoded as follows: + + abcd,"ef,gh","ij""kl",mnop + +**CSV FILE DATA** + +The first line of output must be the following: + + #jdepr1 + +This is strictly a comment line, but it serves as a file +identifier. The "1" indicates version 1 of this file. + +Zero or more comment lines follow, containing text that is specified +by the `-Xcsv-comment` options. + +Subsequent non-comment lines must have the following five fields: + + kind,typeName,descOrName,since,forRemoval + +Fields are defined as follows: + + * _kind_ - one of CONSTRUCTOR, FIELD, METHOD, ENUM\_CONSTANT, + CLASS, INTERFACE, ENUM, or ANNOTATION\_TYPE. These correspond to + enumeration constants from the `javax.lang.model.element.ElementKind` + enum. + + * _typeName_ - the fully qualified name of the type (if *kind* is + CLASS, INTERFACE, ENUM, or ANNOTATION\_TYPE) or of the enclosing + type (if _kind_ is CONSTRUCTOR, FIELD, METHOD, or + ENUM\_CONSTANT). This value is a _binary name_ [JLS 13.1][jls131] + using a slash character `/` (U+002F) to separate package and + top-level name components, and a dollar sign `$` (U+0024) to + separate nested name components. For example, the `Thread.State` + enum that appears in Java SE would have the following typeName: + + java/lang/Thread$State + + * _descOrName_ - if _kind_ is METHOD or CONSTRUCTOR, this is the method's + or constructor's descriptor [JVMS 4.3.3][jvms433]; if _kind_ is FIELD or + ENUM\_CONSTANT, this is its name; otherwise this field is empty. + A method's descriptor includes its name, parameter types, and return + type. For example, the method + + public void String.getBytes(int srcBegin, + int srcEnd, + byte[] dst, + int dstBegin) + + has the descriptor + + getBytes(II[BI)V + + * _since_ - the value of the `since` element of the `@Deprecated` + annotation, or empty if this element is not present. + + * _forRemoval_ - the value of the `forRemoval` element of the + `@Deprecated` annotation, a boolean, either "true" or "false". + +Note that the _since_ field can have arbitrary text (excluding +line separators) and is thus subject to quoting. + +**EXAMPLE OUTPUT** + +Given the following method declaration and annotation from the +`java.lang.Runtime` class, + + @Deprecated(since="1.2", + forRemoval=true) + public static void runFinalizersOnExit(boolean value) + +the following line will be emitted from **jdeprscan -Xprint-csv**: + + METHOD,java/lang/Runtime,runFinalizersOnExit(Z)V,1.2,true + + +[RFC]: https://www.ietf.org/rfc/rfc4180.txt + +[wiki]: https://en.wikipedia.org/wiki/Comma-separated_values + +[jls131]: http://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1 + +[jvms433]: http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3 diff --git a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/readme.md b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/readme.md new file mode 100644 index 00000000000..f51a1ea0c9b --- /dev/null +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/readme.md @@ -0,0 +1,180 @@ + + + +JDeprScan Tool Command Reference +----- + +**NAME** + + jdeprscan - Java deprecation scanner + +**SYNOPSIS** + + jdeprscan [options] {dir | jar | class} ... + +**OPTIONS** + + -cp PATH + --class-path PATH + + Sets the classpath to PATH. + + --for-removal + + Limit reporting to deprecations whose forRemoval element + is true. + + --full-version + + Prints the full version string of the tool and exits. + + -h + --help + + Prints a help message and exits. + + -l + --list + + Prints out the set of deprecated APIs. + + --release 6|7|8|9 + + Specifies the Java SE release that is the source of + the list of deprecated APIs. If no --release option is + provided, the latest release is used. + + -v + --verbose + + Enables additional output. + + --version + + Prints the version string of the tool and exits. + +**DESCRIPTION** + +**jdeprscan** scans a class library for uses of deprecated APIs. +**jdeprscan** processes one or more arguments, which can be any +combination of a directory, a jar file, or a class name. + +A directory argument must specify a path to a directory hierarchy that +reflects the Java package hierarchy of the classes it contains. +**jdeprscan** will scan each class found in the directory hierarchy +and report information about how those classes use deprecated APIs. + +Given a jar file, **jdeprscan** will scan the classes found within +that jar file and report information about how those classes use +deprecated APIs. + +Given a class name, **jdeprscan** will search for that class on the +classpath, scan that class, and report information about how that +class uses deprecated APIs. The class name must use the fully +qualified binary name of the class, as described in the +[Java Language Specification, section 13.1][jls131]. This form uses +the '$' character instead of '.' as the separator for nested class names. +For example, the `Thread.State` enum would be specified using the string + + java.lang.Thread$State + +The `--class-path` and `-cp` options specify the classpath used for +class searching. The classpath is used for classes named on the +command line, as well as for dependencies of the classes in jar file +or directory hierarchy to be scanned. + +The `--for-removal` option limits output to uses of deprecated APIs +whose `@Deprecated` annotation includes the `forRemoval` element with +the value `true`. Note: the `forRemoval` attribute of the +`@Deprecated` annotation did not exist prior to Java SE 9, so this +option cannot be used with a release value of 6, 7, or 8. + +The `--release` option specifies the Java SE specification version +that determines the set of deprecated APIs for which scanning is +done. This is useful if a deprecation report is desired that lists +uses of deprecated APIs as of a particular release in the past. If no +`--release` option is given, the latest release is used. + +The `--list` and `-l` options will list the known set of deprecated +APIs instead of doing any scanning. Since no scanning is done, +no directory, jar, or class arguments should be provided. The set +of deprecated APIs listed is affected by the `--release` and the +`--for-removal` options. + + +**EXAMPLE OUTPUT** + +The output is a report that lists program elements that use deprecated +APIs. Output is subject to change. + +Consider the following declarations from Java SE 9: + + // java.lang.Boolean + + @Deprecated(since="9") + public Boolean(boolean value) + + // java.lang.Runtime + + @Deprecated(since="1.2", forRemoval=true) + public static void runFinalizersOnExit(boolean value) + +Running **jdeprscan** over a class that calls these methods will result +in output something like the following: + + class Example uses method java/lang/Boolean.(Z)V deprecated + class Example uses method java/lang/Runtime.runFinalizersOnExit(Z)V deprecated for removal + +Running **jdeprscan** with the `--list` option will result in output +including something like the following: + + ... + @Deprecated(since="9") java.lang.Boolean(boolean) + @Deprecated(since="1.2", forRemoval=true) void java.lang.Runtime.runFinalizersOnExit(boolean) + ... + +**NOTES** + +The **jdeprscan** tool operates by opening Java class files and +reading their structures directly, particularly the constant +pool. Because of this, **jdeprscan** can tell _that_ a deprecated API +is used, but it often cannot tell _where_ in the class that API is +used. + +The **jdeprscan** tool doesn't follow the same set of rules for +emitting warnings as specified for Java compilers in [JLS section +9.6.4.6][jls9646]. In particular, **jdeprscan** does not respond to +the `@SuppressWarnings` annotation, as that is significant only in +source code, not in class files. In addition, **jdeprscan** emits +warnings even if the usage is within the API element that is +deprecated and when the use and declaration are within the same +outermost class. + +[jls9646]: http://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.6.4.6 + +[jls131]: http://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1 diff --git a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/resources/jdeprscan.properties b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/resources/jdeprscan.properties new file mode 100644 index 00000000000..fd92fe813ee --- /dev/null +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/resources/jdeprscan.properties @@ -0,0 +1,96 @@ +main.usage=\ +Usage: jdeprscan [options] '{dir|jar|class}' ...\n\ +\n\ +options:\n\ +\ -cp --class-path PATH\n\ +\ --for-removal\n\ +\ --full-version\n\ +\ -h --help\n\ +\ -l --list\n\ +\ --release 6|7|8|9\n\ +\ -v --verbose\n\ +\ --version + +main.help=\ +Scans each argument for usages of deprecated APIs. An argument\n\ +may be a directory specifying the root of a package hierarchy,\n\ +a JAR file, or a class name. The class name must be specified\n\ +using a fully qualified class name using the $ separator character\n\ +for nested classes, for example,\n\ +\n\ +\ java.lang.Thread$State\n\ +\n\ +The --class-path (-cp) option provides a search path for resolution\n\ +of dependent classes.\n\ +\n\ +The --for-removal option limits scanning or listing to APIs that are\n\ +deprecated for removal. Cannot be used with a release value of 6, 7, or 8.\n\ +\n\ +The --full-version option prints out the full version string of the tool.\n\ +\n\ +The --help option prints out a full help message.\n\ +\n\ +The --list (-l) option prints out the set of deprecated APIs. No scanning is done,\n\ +so no directory, jar, or class arguments should be provided.\n\ +\n\ +The --release option specifies the Java SE release that provides the set\n\ +of deprecated APIs for scanning.\n\ +\n\ +The --verbose (-v) option enables additional message output during processing.\n\ +\n\ +The --version option prints out the abbreviated version string of the tool. + +main.xhelp=\ +Unsupported options:\n\ +\n\ +\ --Xload-class CLASS\n\ +\ Loads deprecation information from the named class.\n\ +\ --Xload-csv CSVFILE\n\ +\ Loads deprecation information from the named CSV file.\n\ +\ --Xload-dir DIR\n\ +\ Loads deprecation information from the class hierarchy\n\ +\ at the named directory.\n\ +\ --Xload-jar JARFILE\n\ +\ Loads deprecation information from the named JAR file.\n\ +\ --Xload-jdk9 JAVA_HOME\n\ +\ Loads deprecation information from the JDK located at\n\ +\ JAVA_HOME, which must be a modular JDK.\n\ +\ --Xload-old-jdk JAVA_HOME\n\ +\ Loads deprecation information from the JDK located at\n\ +\ JAVA_HOME, which must not be a modular JDK. Instead, the\n\ +\ named JDK must be a "classic" JDK with an rt.jar file.\n\ +\ --Xload-self\n\ +\ Loads deprecation information by traversing the jrt:\n\ +\ filesystem of the running JDK image.\n\ +\ --Xcompiler-arg ARG\n\ +\ Adds ARG to the list of compiler arguments.\n\ +\ --Xcsv-comment COMMENT\n\ +\ Adds COMMENT as a comment line to the output CSV file.\n\ +\ Only effective if -Xprint-csv is also supplied.\n\ +\ --Xhelp\n\ +\ Prints this message.\n\ +\ --Xprint-csv\n\ +\ Prints a CSV file containing the loaded deprecation information\n\ +\ instead of scanning any classes or JAR files. + +error.prefix=Error: + +scan.process.class=Processing class {0}... + +scan.dep.normal=deprecated +scan.dep.removal=deprecated FOR REMOVAL + +scan.out.extends={0} {1} extends class {2} {3} +scan.out.implements={0} {1} implements interface {2} {3} +scan.out.usestype={0} {1} uses type {2} {3} +scan.out.usesmethodintype={0} {1} uses method in type {2} {3} +scan.out.usesmethod={0} {1} uses method {2} {3} {4} {5} +scan.out.usesintfmethodintype={0} {1} uses interface method in type {2} {3} +scan.out.usesintfmethod={0} {1} uses interface method {2} {3} {4} {5} +scan.out.usesfieldintype={0} {1} uses field in type {2} {3} +scan.out.usesfield={0} {1} uses field {2} {3} {4} +scan.out.usesfieldoftype={0} {1} uses field of type {2} {3} {4} {5} +scan.out.hasfield={0} {1} has field {2} of type {3} {4} +scan.out.methodparmtype={0} {1} method {2} has parameter type {3} {4} +scan.out.methodrettype={0} {1} method {2} has return type {3} {4} +scan.out.methodoverride={0} {1} overrides method {2} {3} {4} {5} diff --git a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/CPEntries.java b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/CPEntries.java new file mode 100644 index 00000000000..8314a2b608a --- /dev/null +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/CPEntries.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.jdeprscan.scan; + +import java.util.ArrayList; +import java.util.Formatter; +import java.util.List; +import java.util.Locale; + +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPool; + +import static com.sun.tools.classfile.ConstantPool.CPInfo; + +/** + * A container for selected constant pool entries. There are currently + * lists that contain the following types of CP entries: + * + * - CONSTANT_Class_info + * - CONSTANT_Fieldref_info + * - CONSTANT_Methodref_info + * - CONSTANT_InterfaceMethodref_info + */ +class CPEntries { + final List classes = new ArrayList<>(); + final List fieldRefs = new ArrayList<>(); + final List methodRefs = new ArrayList<>(); + final List intfMethodRefs = new ArrayList<>(); + + public static CPEntries loadFrom(ClassFile cf) { + CPEntries entries = new CPEntries(); + for (CPInfo cpi : cf.constant_pool.entries()) { + cpi.accept(new CPSelector(), entries); + } + return entries; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + Formatter f = new Formatter(sb, Locale.getDefault()); + f.format("Classes:%n"); + f.format("%s%n", classes); + f.format("FieldRefs:%n"); + f.format("%s%n", fieldRefs); + f.format("MethodRefs:%n"); + f.format("%s%n", methodRefs); + f.format("InterfaceMethodRefs:%n"); + f.format("%s%n", intfMethodRefs); + f.flush(); + return sb.toString(); + } +} diff --git a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/CPSelector.java b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/CPSelector.java new file mode 100644 index 00000000000..a9d2afe4d2b --- /dev/null +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/CPSelector.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.jdeprscan.scan; + +import com.sun.tools.classfile.ConstantPool; + +/** + * A visitor that selects constant pool entries by type and adds + * them to the given CPEntries object. + */ +class CPSelector implements ConstantPool.Visitor { + @Override + public Void visitClass(ConstantPool.CONSTANT_Class_info info, CPEntries p) { + p.classes.add(info); + return null; + } + + @Override + public Void visitDouble(ConstantPool.CONSTANT_Double_info info, CPEntries p) { + return null; + } + + @Override + public Void visitFieldref(ConstantPool.CONSTANT_Fieldref_info info, CPEntries p) { + p.fieldRefs.add(info); + return null; + } + + @Override + public Void visitFloat(ConstantPool.CONSTANT_Float_info info, CPEntries p) { + return null; + } + + @Override + public Void visitInteger(ConstantPool.CONSTANT_Integer_info info, CPEntries p) { + return null; + } + + @Override + public Void visitInterfaceMethodref(ConstantPool.CONSTANT_InterfaceMethodref_info info, CPEntries p) { + p.intfMethodRefs.add(info); + return null; + } + + @Override + public Void visitInvokeDynamic(ConstantPool.CONSTANT_InvokeDynamic_info info, CPEntries p) { + return null; + } + + @Override + public Void visitLong(ConstantPool.CONSTANT_Long_info info, CPEntries p) { + return null; + } + + @Override + public Void visitNameAndType(ConstantPool.CONSTANT_NameAndType_info info, CPEntries p) { + return null; + } + + @Override + public Void visitMethodref(ConstantPool.CONSTANT_Methodref_info info, CPEntries p) { + p.methodRefs.add(info); + return null; + } + + @Override + public Void visitMethodHandle(ConstantPool.CONSTANT_MethodHandle_info info, CPEntries p) { + return null; + } + + @Override + public Void visitMethodType(ConstantPool.CONSTANT_MethodType_info info, CPEntries p) { + return null; + } + + @Override + public Void visitString(ConstantPool.CONSTANT_String_info info, CPEntries p) { + return null; + } + + @Override + public Void visitUtf8(ConstantPool.CONSTANT_Utf8_info info, CPEntries p) { + return null; + } +} diff --git a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/ClassFinder.java b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/ClassFinder.java new file mode 100644 index 00000000000..ebb847bbe99 --- /dev/null +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/ClassFinder.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.jdeprscan.scan; + +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPoolException; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.stream.Stream; + +/** + * A simple search path for classes. + */ +public class ClassFinder { + final List list = new ArrayList<>(); + final boolean verbose; + + public ClassFinder(boolean verbose) { + this.verbose = verbose; + } + + /** + * Adds a directory to this finder's search path, ignoring errors. + * + * @param dirName the directory to add + */ + public void addDir(String dirName) { + Path dir = Paths.get(dirName); + + if (Files.isDirectory(dir)) { + list.add(new DirPathEntry(dir)); + } + } + + /** + * Adds a jar file to this finder's search path, ignoring errors. + * + * @param jarName the jar file name to add + */ + public void addJar(String jarName) { + try { + list.add(new JarPathEntry(new JarFile(jarName))); + } catch (IOException ignore) { } + } + + /** + * Adds the JRT filesystem to this finder's search path. + */ + public void addJrt() { + list.add(new JrtPathEntry()); + } + + /** + * Searches the class path for a class with the given name, + * returning a ClassFile for it. Returns null if not found. + * + * @param className the class to search for + * @return a ClassFile instance, or null if not found + */ + public ClassFile find(String className) { + for (PathEntry pe : list) { + ClassFile cf = pe.find(className); + if (cf != null) { + return cf; + } + } + return null; + } + + /** + * An entry in this finder's class path. + */ + interface PathEntry { + /** + * Returns a ClassFile instance corresponding to this name, + * or null if it's not present in this entry. + * + * @param className the class to search for + * @return a ClassFile instance, or null if not found + */ + ClassFile find(String className); + } + + /** + * An entry that represents a jar file. + */ + class JarPathEntry implements PathEntry { + final JarFile jarFile; + + JarPathEntry(JarFile jf) { + jarFile = jf; + } + + @Override + public ClassFile find(String className) { + JarEntry entry = jarFile.getJarEntry(className + ".class"); + if (entry == null) { + return null; + } + try { + return ClassFile.read(jarFile.getInputStream(entry)); + } catch (IOException | ConstantPoolException ex) { + if (verbose) { + ex.printStackTrace(); + } + } + return null; + } + } + + /** + * An entry that represents a directory containing a class hierarchy. + */ + class DirPathEntry implements PathEntry { + final Path dir; + + DirPathEntry(Path dir) { + this.dir = dir; + } + + @Override + public ClassFile find(String className) { + Path classFileName = dir.resolve(className + ".class"); + try { + return ClassFile.read(classFileName); + } catch (NoSuchFileException nsfe) { + // not found, return silently + } catch (IOException | ConstantPoolException ex) { + if (verbose) { + ex.printStackTrace(); + } + } + return null; + } + } + + /** + * An entry that represents the JRT filesystem in the running image. + * + * JRT filesystem structure is: + * /packages// + * where modlink is a symbolic link to /modules/ which is + * the top of the usual package-class hierarchy + */ + class JrtPathEntry implements PathEntry { + final FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); + + @Override + public ClassFile find(String className) { + int end = className.lastIndexOf('/'); + if (end < 0) { + return null; + } + String pkg = "/packages/" + className.substring(0, end) + .replace('/', '.'); + try (Stream mods = Files.list(fs.getPath(pkg))) { + Optional opath = + mods.map(path -> path.resolve(className + ".class")) + .filter(Files::exists) + .findFirst(); + if (opath.isPresent()) { + return ClassFile.read(opath.get()); + } else { + return null; + } + } catch (NoSuchFileException nsfe) { + // not found, return silently + } catch (IOException | ConstantPoolException ex) { + if (verbose) { + ex.printStackTrace(); + } + } + return null; + } + } +} diff --git a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/MethodSig.java b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/MethodSig.java new file mode 100644 index 00000000000..723b489f727 --- /dev/null +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/MethodSig.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.jdeprscan.scan; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Represents a method's signature, that is, its parameter types + * and its return type. + */ +public class MethodSig { + final List parameters; + final String returnType; + + /** + * Parses the method descriptor and returns a MethodSig instance. + * + * @param desc the descriptor to parse + * @return the new MethodSig instance + */ + public static MethodSig fromDesc(String desc) { + return parse(desc, 0, desc.length()); + } + + /** + * Returns this method's return type. + * + * @return the return type + */ + public String getReturnType() { + return returnType; + } + + /** + * Returns a list of parameters of this method. + * + * @return the parameter list + */ + public List getParameters() { + return parameters; + } + + /** + * Returns a string describing this method. + * + * @return the string description + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("parameters"); + if (parameters.isEmpty()) { + sb.append(" none"); + } else { + int i = 0; + for (String p : parameters) { + sb.append(String.format(" %d=%s", i++, p)); + } + } + sb.append(String.format(" return %s", returnType)); + return sb.toString(); + } + + private MethodSig(List parameters, String returnType) { + this.parameters = Collections.unmodifiableList(parameters); + this.returnType = returnType; + } + + private static IllegalArgumentException ex(String desc, int pos) { + return new IllegalArgumentException(String.format( + "illegal descriptor \"%s\" at position %d", desc, pos)); + } + + private static MethodSig parse(String desc, int start, int end) + throws IllegalArgumentException { + int p = start; + int dims = 0; + boolean inReturnType = false; + String returnType = null; + List parameters = new ArrayList<>(); + + while (p < end) { + String type; + char ch; + switch (ch = desc.charAt(p)) { + case '(': + p++; + continue; + + case ')': + p++; + inReturnType = true; + continue; + + case '[': + p++; + dims++; + continue; + + case 'B': // byte + case 'C': // char + case 'D': // double + case 'F': // float + case 'I': // int + case 'J': // long + case 'S': // short + case 'Z': // boolean + case 'V': // void + type = Character.toString(ch); + p++; + break; + + case 'L': + int sep = desc.indexOf(';', p); + if (sep == -1 || sep >= end) + throw ex(desc, p); + type = desc.substring(p, ++sep); + p = sep; + break; + + default: + throw ex(desc, p); + } + + StringBuilder sb = new StringBuilder(); + for ( ; dims > 0; dims-- ) + sb.append("["); + sb.append(type); + if (inReturnType) { + returnType = sb.toString(); + } else { + parameters.add(sb.toString()); + } + } + + if (returnType == null) { + throw ex(desc, end); + } + + return new MethodSig(parameters, returnType); + } +} diff --git a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/Scan.java b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/Scan.java new file mode 100644 index 00000000000..4088e11841d --- /dev/null +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/Scan.java @@ -0,0 +1,614 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.jdeprscan.scan; + +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.sun.tools.classfile.*; +import com.sun.tools.jdeprscan.DeprData; +import com.sun.tools.jdeprscan.DeprDB; +import com.sun.tools.jdeprscan.Messages; + +import static com.sun.tools.classfile.AccessFlags.*; +import static com.sun.tools.classfile.ConstantPool.*; + +/** + * An object that represents the scanning phase of deprecation usage checking. + * Given a deprecation database, scans the targeted directory hierarchy, jar + * file, or individual class for uses of deprecated APIs. + */ +public class Scan { + final PrintStream out; + final PrintStream err; + final List classPath; + final DeprDB db; + final boolean verbose; + + final ClassFinder finder; + boolean error = false; + + public Scan(PrintStream out, + PrintStream err, + List classPath, + DeprDB db, + boolean verbose) { + this.out = out; + this.err = err; + this.classPath = classPath; + this.db = db; + this.verbose = verbose; + + ClassFinder f = new ClassFinder(verbose); + + // TODO: this isn't quite right. If we've specified a release other than the current + // one, we should instead add a reference to the symbol file for that release instead + // of the current image. The problems are a) it's unclear how to get from a release + // to paths that reference the symbol files, as this might be internal to the file + // manager; and b) the symbol file includes .sig files, not class files, which ClassFile + // might not be able to handle. + f.addJrt(); + + for (String name : classPath) { + if (name.endsWith(".jar")) { + f.addJar(name); + } else { + f.addDir(name); + } + } + + finder = f; + } + + Pattern typePattern = Pattern.compile("\\[*L(.*);"); + + // "flattens" an array type name to its component type + // and a reference type "Lpkg/pkg/pkg/name;" to its base name + // "pkg/pkg/pkg/name". + // TODO: deal with primitive types + String flatten(String typeName) { + Matcher matcher = typePattern.matcher(typeName); + if (matcher.matches()) { + return matcher.group(1); + } else { + return typeName; + } + } + + String typeKind(ClassFile cf) { + AccessFlags flags = cf.access_flags; + if (flags.is(ACC_ENUM)) { + return "enum"; + } else if (flags.is(ACC_ANNOTATION)) { + return "@interface"; + } else if (flags.is(ACC_INTERFACE)) { + return "interface"; + } else { + return "class"; + } + } + + void printType(String key, ClassFile cf, String cname, boolean forRemoval) + throws ConstantPoolException { + String dep = Messages.get(forRemoval ? "scan.dep.removal" : "scan.dep.normal"); + out.println(Messages.get(key, typeKind(cf), cf.getName(), cname, dep)); + } + + void printMethod(String key, ClassFile cf, String cname, String mname, String rtype, + boolean forRemoval) throws ConstantPoolException { + String dep = Messages.get(forRemoval ? "scan.dep.removal" : "scan.dep.normal"); + out.println(Messages.get(key, typeKind(cf), cf.getName(), cname, mname, rtype, dep)); + } + + void printField(String key, ClassFile cf, String cname, String fname, + boolean forRemoval) throws ConstantPoolException { + String dep = Messages.get(forRemoval ? "scan.dep.removal" : "scan.dep.normal"); + out.println(Messages.get(key, typeKind(cf), cf.getName(), cname, fname, dep)); + } + + void printFieldType(String key, ClassFile cf, String cname, String fname, String type, + boolean forRemoval) throws ConstantPoolException { + String dep = Messages.get(forRemoval ? "scan.dep.removal" : "scan.dep.normal"); + out.println(Messages.get(key, typeKind(cf), cf.getName(), cname, fname, type, dep)); + } + + void printHasField(ClassFile cf, String fname, String type, boolean forRemoval) + throws ConstantPoolException { + String dep = Messages.get(forRemoval ? "scan.dep.removal" : "scan.dep.normal"); + out.println(Messages.get("scan.out.hasfield", typeKind(cf), cf.getName(), fname, type, dep)); + } + + void printHasMethodParmType(ClassFile cf, String mname, String parmType, boolean forRemoval) + throws ConstantPoolException { + String dep = Messages.get(forRemoval ? "scan.dep.removal" : "scan.dep.normal"); + out.println(Messages.get("scan.out.methodparmtype", typeKind(cf), cf.getName(), mname, parmType, dep)); + } + + void printHasMethodRetType(ClassFile cf, String mname, String retType, boolean forRemoval) + throws ConstantPoolException { + String dep = Messages.get(forRemoval ? "scan.dep.removal" : "scan.dep.normal"); + out.println(Messages.get("scan.out.methodrettype", typeKind(cf), cf.getName(), mname, retType, dep)); + } + + void printHasOverriddenMethod(ClassFile cf, String overridden, String mname, String desc, boolean forRemoval) + throws ConstantPoolException { + String dep = Messages.get(forRemoval ? "scan.dep.removal" : "scan.dep.normal"); + out.println(Messages.get("scan.out.methodoverride", typeKind(cf), cf.getName(), overridden, + mname, desc, dep)); + } + + // format should not have a newline + void err(String format, Object... args) { + error = true; + err.print("error: "); + err.printf(format, args); + err.println(); + } + + void printException(Exception ex) { + err.print(Messages.get("error.prefix")); + err.print(" "); + if (verbose) { + ex.printStackTrace(err); + } else { + err.print(ex); + } + } + + /** + * Checks whether a member (method or field) is present in a class. + * The checkMethod parameter determines whether this checks for a method + * or for a field. + * + * @param targetClass the ClassFile of the class to search + * @param targetName the method or field's name + * @param targetDesc the methods descriptor (ignored if checkMethod is false) + * @param checkMethod true if checking for method, false if checking for field + * @return boolean indicating whether the member is present + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + boolean isMemberPresent(ClassFile targetClass, + String targetName, + String targetDesc, + boolean checkMethod) + throws ConstantPoolException { + if (checkMethod) { + for (Method m : targetClass.methods) { + String mname = m.getName(targetClass.constant_pool); + String mdesc = targetClass.constant_pool.getUTF8Value(m.descriptor.index); + if (targetName.equals(mname) && targetDesc.equals(mdesc)) { + return true; + } + } + } else { + for (Field f : targetClass.fields) { + String fname = f.getName(targetClass.constant_pool); + if (targetName.equals(fname)) { + return true; + } + } + } + return false; + } + + /** + * Adds all interfaces from this class to the deque of interfaces. + * + * @param intfs the deque of interfaces + * @param cf the ClassFile of this class + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + void addInterfaces(Deque intfs, ClassFile cf) + throws ConstantPoolException { + int count = cf.interfaces.length; + for (int i = 0; i < count; i++) { + intfs.addLast(cf.getInterfaceName(i)); + } + } + + /** + * Resolves a member by searching this class and all its superclasses and + * implemented interfaces. + * + * TODO: handles a few too many cases; needs cleanup. + * + * TODO: refine error handling + * + * @param cf the ClassFile of this class + * @param startClassName the name of the class at which to start searching + * @param findName the member name to search for + * @param findDesc the method descriptor to search for (ignored for fields) + * @param resolveMethod true if resolving a method, false if resolving a field + * @param checkStartClass true if the start class should be searched, false if + * it should be skipped + * @return the name of the class where the member resolved, or null + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + String resolveMember( + ClassFile cf, String startClassName, String findName, String findDesc, + boolean resolveMethod, boolean checkStartClass) + throws ConstantPoolException { + ClassFile startClass; + + if (cf.getName().equals(startClassName)) { + startClass = cf; + } else { + startClass = finder.find(startClassName); + if (startClass == null) { + err("can't find class %s", startClassName); + return startClassName; + } + } + + // follow super_class until it's 0, meaning we've reached Object + // accumulate interfaces of superclasses as we go along + + ClassFile curClass = startClass; + Deque intfs = new ArrayDeque<>(); + while (true) { + if ((checkStartClass || curClass != startClass) && + isMemberPresent(curClass, findName, findDesc, resolveMethod)) { + break; + } + + if (curClass.super_class == 0) { // reached Object + curClass = null; + break; + } + + String superName = curClass.getSuperclassName(); + curClass = finder.find(superName); + if (curClass == null) { + err("can't find class %s", superName); + break; + } + addInterfaces(intfs, curClass); + } + + // search interfaces: add all interfaces and superinterfaces to queue + // search until it's empty + + if (curClass == null) { + addInterfaces(intfs, startClass); + while (intfs.size() > 0) { + String intf = intfs.removeFirst(); + curClass = finder.find(intf); + if (curClass == null) { + err("can't find interface %s", intf); + break; + } + + if (isMemberPresent(curClass, findName, findDesc, resolveMethod)) { + break; + } + + addInterfaces(intfs, curClass); + } + } + + if (curClass == null) { + if (checkStartClass) { + err("can't resolve methodref %s %s %s", + startClassName, findName, findDesc); + return startClassName; + } else { + // TODO: refactor this + // checkStartClass == false means we're checking for overrides + // so not being able to resolve a method simply means there's + // no overriding, which isn't an error + return null; + } + } else { + String foundClassName = curClass.getName(); + return foundClassName; + } + } + + /** + * Checks the superclass of this class. + * + * @param cf the ClassFile of this class + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + void checkSuper(ClassFile cf) throws ConstantPoolException { + String sname = cf.getSuperclassName(); + DeprData dd = db.getTypeDeprecated(sname); + if (dd != null) { + printType("scan.out.extends", cf, sname, dd.isForRemoval()); + } + } + + /** + * Checks the interfaces of this class. + * + * @param cf the ClassFile of this class + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + void checkInterfaces(ClassFile cf) throws ConstantPoolException { + int ni = cf.interfaces.length; + for (int i = 0; i < ni; i++) { + String iname = cf.getInterfaceName(i); + DeprData dd = db.getTypeDeprecated(iname); + if (dd != null) { + printType("scan.out.implements", cf, iname, dd.isForRemoval()); + } + } + } + + /** + * Checks types referred to from the constant pool. + * + * @param cf the ClassFile of this class + * @param entries constant pool entries collected from this class + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + void checkTypes(ClassFile cf, CPEntries entries) throws ConstantPoolException { + for (ConstantPool.CONSTANT_Class_info ci : entries.classes) { + String typeName = ci.getName(); + DeprData dd = db.getTypeDeprecated(flatten(typeName)); + if (dd != null) { + printType("scan.out.usestype", cf, typeName, dd.isForRemoval()); + } + } + } + + /** + * Checks methods referred to from the constant pool. + * + * @param cf the ClassFile of this class + * @param nti the NameAndType_info from a MethodRef or InterfaceMethodRef entry + * @param clname the class name + * @param typeKey key for the type message + * @param methKey key for the method message + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + void checkMethodRef(ClassFile cf, + CONSTANT_NameAndType_info nti, + String clname, + String typeKey, + String methKey) throws ConstantPoolException { + DeprData dd = db.getTypeDeprecated(flatten(clname)); + if (dd != null) { + printType(typeKey, cf, clname, dd.isForRemoval()); + } + + String name = nti.getName(); + String type = nti.getType(); + clname = resolveMember(cf, flatten(clname), name, type, true, true); + dd = db.getMethodDeprecated(clname, name, type); + if (dd != null) { + printMethod(methKey, cf, clname, name, type, dd.isForRemoval()); + } + } + + /** + * Checks fields referred to from the constant pool. + * + * @param cf the ClassFile of this class + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + void checkFieldRef(ClassFile cf, + ConstantPool.CONSTANT_Fieldref_info fri) throws ConstantPoolException { + CONSTANT_NameAndType_info nti = fri.getNameAndTypeInfo(); + String clname = fri.getClassName(); + String name = nti.getName(); + String type = nti.getType(); + DeprData dd = db.getTypeDeprecated(clname); + + if (dd != null) { + printType("scan.out.usesfieldintype", cf, clname, dd.isForRemoval()); + } + + clname = resolveMember(cf, flatten(clname), name, type, false, true); + dd = db.getFieldDeprecated(clname, name); + if (dd != null) { + printField("scan.out.usesfield", cf, clname, name, dd.isForRemoval()); + } + + dd = db.getTypeDeprecated(flatten(type)); + if (dd != null) { + printFieldType("scan.out.usesfieldoftype", cf, clname, name, type, dd.isForRemoval()); + } + } + + /** + * Checks the fields declared in this class. + * + * @param cf the ClassFile of this class + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + void checkFields(ClassFile cf) throws ConstantPoolException { + for (Field f : cf.fields) { + String type = cf.constant_pool.getUTF8Value(f.descriptor.index); + DeprData dd = db.getTypeDeprecated(flatten(type)); + if (dd != null) { + printHasField(cf, f.getName(cf.constant_pool), type, dd.isForRemoval()); + } + } + } + + /** + * Checks the methods declared in this class. + * + * @param cf the ClassFile object of this class + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + void checkMethods(ClassFile cf) throws ConstantPoolException { + for (Method m : cf.methods) { + String mname = m.getName(cf.constant_pool); + String desc = cf.constant_pool.getUTF8Value(m.descriptor.index); + MethodSig sig = MethodSig.fromDesc(desc); + DeprData dd; + + for (String parm : sig.getParameters()) { + dd = db.getTypeDeprecated(flatten(parm)); + if (dd != null) { + printHasMethodParmType(cf, mname, parm, dd.isForRemoval()); + } + } + + String ret = sig.getReturnType(); + dd = db.getTypeDeprecated(flatten(ret)); + if (dd != null) { + printHasMethodRetType(cf, mname, ret, dd.isForRemoval()); + } + + // check overrides + String overridden = resolveMember(cf, cf.getName(), mname, desc, true, false); + if (overridden != null) { + dd = db.getMethodDeprecated(overridden, mname, desc); + if (dd != null) { + printHasOverriddenMethod(cf, overridden, mname, desc, dd.isForRemoval()); + } + } + } + } + + /** + * Processes a single class file. + * + * @param cf the ClassFile of the class + * @throws ConstantPoolException if a constant pool entry cannot be found + */ + void processClass(ClassFile cf) throws ConstantPoolException { + if (verbose) { + out.println(Messages.get("scan.process.class", cf.getName())); + } + + CPEntries entries = CPEntries.loadFrom(cf); + + checkSuper(cf); + checkInterfaces(cf); + checkTypes(cf, entries); + + for (ConstantPool.CONSTANT_Methodref_info mri : entries.methodRefs) { + CONSTANT_NameAndType_info nti = mri.getNameAndTypeInfo(); + String clname = mri.getClassName(); + checkMethodRef(cf, nti, clname, "scan.out.usesmethodintype", "scan.out.usesmethod"); + } + + for (ConstantPool.CONSTANT_InterfaceMethodref_info imri : entries.intfMethodRefs) { + CONSTANT_NameAndType_info nti = imri.getNameAndTypeInfo(); + String clname = imri.getClassName(); + checkMethodRef(cf, nti, clname, "scan.out.usesintfmethodintype", "scan.out.usesintfmethod"); + } + + for (ConstantPool.CONSTANT_Fieldref_info fri : entries.fieldRefs) { + checkFieldRef(cf, fri); + } + + checkFields(cf); + checkMethods(cf); + } + + /** + * Scans a jar file for uses of deprecated APIs. + * + * @param jarname the jar file to process + * @return true on success, false on failure + */ + public boolean scanJar(String jarname) { + try (JarFile jf = new JarFile(jarname)) { + finder.addJar(jarname); + Enumeration entries = jf.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String name = entry.getName(); + if (name.endsWith(".class") + && !name.endsWith("package-info.class") + && !name.endsWith("module-info.class")) { + processClass(ClassFile.read(jf.getInputStream(entry))); + } + } + return true; + } catch (IOException | ConstantPoolException ex) { + printException(ex); + return false; + } + } + + /** + * Scans class files in the named directory hierarchy for uses of deprecated APIs. + * + * @param dirname the directory hierarchy to process + * @return true on success, false on failure + */ + public boolean scanDir(String dirname) { + Path base = Paths.get(dirname); + int baseCount = base.getNameCount(); + finder.addDir(dirname); + try (Stream paths = Files.walk(Paths.get(dirname))) { + List classes = + paths.filter(p -> p.getNameCount() > baseCount) + .filter(path -> path.toString().endsWith(".class")) + .filter(path -> !path.toString().endsWith("package-info.class")) + .filter(path -> !path.toString().endsWith("module-info.class")) + .collect(Collectors.toList()); + for (Path p : classes) { + processClass(ClassFile.read(p)); + } + return true; + } catch (IOException | ConstantPoolException ex) { + printException(ex); + return false; + } + } + + /** + * Scans the named class for uses of deprecated APIs. + * + * @param className the class to scan + * @return true on success, false on failure + */ + public boolean processClassName(String className) { + try { + ClassFile cf = finder.find(className); + if (cf == null) { + err("can't find class %s", className); + return false; + } else { + processClass(cf); + return true; + } + } catch (ConstantPoolException ex) { + printException(ex); + return false; + } + } +} diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java index a77a95acca2..e725f9cd161 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java @@ -34,6 +34,7 @@ import java.nio.file.Path; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.util.Arrays; +import java.util.Scanner; import java.util.function.Consumer; import java.util.stream.Collectors; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; @@ -46,17 +47,22 @@ import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; public class ExternalEditor { private final Consumer errorHandler; private final Consumer saveHandler; + private final Consumer printHandler; private final IOContext input; + private final boolean wait; private WatchService watcher; private Thread watchedThread; private Path dir; private Path tmpfile; - ExternalEditor(Consumer errorHandler, Consumer saveHandler, IOContext input) { + ExternalEditor(Consumer errorHandler, Consumer saveHandler, + IOContext input, boolean wait, Consumer printHandler) { this.errorHandler = errorHandler; this.saveHandler = saveHandler; + this.printHandler = printHandler; this.input = input; + this.wait = wait; } private void edit(String[] cmd, String initialText) { @@ -121,7 +127,16 @@ public class ExternalEditor { try { input.suspend(); Process process = pb.start(); - process.waitFor(); + // wait to exit edit mode in one of these ways... + if (wait) { + // -wait option -- ignore process exit, wait for carriage-return + Scanner scanner = new Scanner(System.in); + printHandler.accept("jshell.msg.press.return.to.leave.edit.mode"); + scanner.nextLine(); + } else { + // wait for process to exit + process.waitFor(); + } } catch (IOException ex) { errorHandler.accept("process IO failure: " + ex.getMessage()); } catch (InterruptedException ex) { @@ -148,8 +163,8 @@ public class ExternalEditor { } static void edit(String[] cmd, Consumer errorHandler, String initialText, - Consumer saveHandler, IOContext input) { - ExternalEditor ed = new ExternalEditor(errorHandler, saveHandler, input); + Consumer saveHandler, IOContext input, boolean wait, Consumer printHandler) { + ExternalEditor ed = new ExternalEditor(errorHandler, saveHandler, input, wait, printHandler); ed.edit(cmd, initialText); } } diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java index eedceff6fb2..7f78c2f9962 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java @@ -147,17 +147,17 @@ class Feedback { } { - for (FormatCase e : EnumSet.allOf(FormatCase.class)) + for (FormatCase e : FormatCase.all) selectorMap.put(e.name().toLowerCase(Locale.US), e); - for (FormatAction e : EnumSet.allOf(FormatAction.class)) + for (FormatAction e : FormatAction.all) selectorMap.put(e.name().toLowerCase(Locale.US), e); - for (FormatResolve e : EnumSet.allOf(FormatResolve.class)) + for (FormatResolve e : FormatResolve.all) selectorMap.put(e.name().toLowerCase(Locale.US), e); - for (FormatUnresolved e : EnumSet.allOf(FormatUnresolved.class)) + for (FormatUnresolved e : FormatUnresolved.all) selectorMap.put(e.name().toLowerCase(Locale.US), e); - for (FormatErrors e : EnumSet.allOf(FormatErrors.class)) + for (FormatErrors e : FormatErrors.all) selectorMap.put(e.name().toLowerCase(Locale.US), e); - for (FormatWhen e : EnumSet.allOf(FormatWhen.class)) + for (FormatWhen e : FormatWhen.all) selectorMap.put(e.name().toLowerCase(Locale.US), e); } diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java index 0d65fef1455..fa83c0fd40e 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java @@ -94,12 +94,16 @@ import java.util.ResourceBundle; import java.util.Spliterators; import java.util.function.Function; import java.util.function.Supplier; +import jdk.internal.joptsimple.*; import jdk.internal.jshell.tool.Feedback.FormatAction; import jdk.internal.jshell.tool.Feedback.FormatCase; import jdk.internal.jshell.tool.Feedback.FormatErrors; import jdk.internal.jshell.tool.Feedback.FormatResolve; import jdk.internal.jshell.tool.Feedback.FormatUnresolved; import jdk.internal.jshell.tool.Feedback.FormatWhen; +import static java.util.Arrays.asList; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; import static jdk.jshell.Snippet.SubKind.VAR_VALUE_SUBKIND; import static java.util.stream.Collectors.toMap; @@ -181,6 +185,7 @@ public class JShellTool implements MessageHandler { private String cmdlineClasspath = null; private String startup = null; private String[] editor = null; + private boolean editorWait = false; // Commands and snippets which should be replayed private List replayableHistory; @@ -477,6 +482,11 @@ public class JShellTool implements MessageHandler { if (editorString == null || editorString.isEmpty()) { editor = null; } else { + char waitMarker = editorString.charAt(0); + if (waitMarker == '-' || waitMarker == '*') { + editorWait = waitMarker == '-'; + editorString = editorString.substring(1); + } editor = editorString.split(RECORD_SEPARATOR); } @@ -515,82 +525,91 @@ public class JShellTool implements MessageHandler { * @return the list of files to be loaded */ private List processCommandArgs(String[] args) { - List loadList = new ArrayList<>(); - Iterator ai = Arrays.asList(args).iterator(); - while (ai.hasNext()) { - String arg = ai.next(); - if (arg.startsWith("-")) { - switch (arg) { - case "-classpath": - case "-cp": - if (cmdlineClasspath != null) { - startmsg("jshell.err.opt.classpath.conflict"); - return null; - } - if (ai.hasNext()) { - cmdlineClasspath = ai.next(); - } else { - startmsg("jshell.err.opt.classpath.arg"); - return null; - } - break; - case "-help": - printUsage(); - return null; - case "-version": - cmdout.printf("jshell %s\n", version()); - return null; - case "-fullversion": - cmdout.printf("jshell %s\n", fullVersion()); - return null; - case "-feedback": - if (ai.hasNext()) { - commandLineFeedbackMode = ai.next(); - } else { - startmsg("jshell.err.opt.feedback.arg"); - return null; - } - break; - case "-q": - commandLineFeedbackMode = "concise"; - break; - case "-qq": - commandLineFeedbackMode = "silent"; - break; - case "-v": - commandLineFeedbackMode = "verbose"; - break; - case "-startup": - if (startup != null) { - startmsg("jshell.err.opt.startup.one"); - return null; - } - startup = readFile(ai.hasNext()? ai.next() : null, "-startup"); - if (startup == null) { - return null; - } - break; - case "-nostartup": - if (startup != null) { - startmsg("jshell.err.opt.startup.one"); - return null; - } - startup = ""; - break; - default: - if (arg.startsWith("-R")) { - remoteVMOptions.add(arg.substring(2)); - break; - } - startmsg("jshell.err.opt.unknown", arg); - printUsage(); - return null; - } + OptionParser parser = new OptionParser(); + OptionSpec cp = parser.accepts("class-path").withRequiredArg(); + OptionSpec st = parser.accepts("startup").withRequiredArg(); + parser.acceptsAll(asList("n", "no-startup")); + OptionSpec fb = parser.accepts("feedback").withRequiredArg(); + parser.accepts("q"); + parser.accepts("s"); + parser.accepts("v"); + OptionSpec r = parser.accepts("R").withRequiredArg(); + parser.acceptsAll(asList("h", "help")); + parser.accepts("version"); + parser.accepts("full-version"); + NonOptionArgumentSpec loadFileSpec = parser.nonOptions(); + + OptionSet options; + try { + options = parser.parse(args); + } catch (OptionException ex) { + if (ex.options().isEmpty()) { + startmsg("jshell.err.opt.invalid", stream(args).collect(joining(", "))); } else { - loadList.add(arg); + boolean isKnown = parser.recognizedOptions().containsKey(ex.options().iterator().next()); + startmsg(isKnown + ? "jshell.err.opt.arg" + : "jshell.err.opt.unknown", + ex.options() + .stream() + .collect(joining(", "))); } + return null; } - return loadList; + + if (options.has("help")) { + printUsage(); + return null; + } + if (options.has("version")) { + cmdout.printf("jshell %s\n", version()); + return null; + } + if (options.has("full-version")) { + cmdout.printf("jshell %s\n", fullVersion()); + return null; + } + if (options.has(cp)) { + List cps = options.valuesOf(cp); + if (cps.size() > 1) { + startmsg("jshell.err.opt.one", "--class-path"); + return null; + } + cmdlineClasspath = cps.get(0); + } + if (options.has(st)) { + List sts = options.valuesOf(st); + if (sts.size() != 1 || options.has("no-startup")) { + startmsg("jshell.err.opt.startup.one"); + return null; + } + startup = readFile(sts.get(0), "--startup"); + if (startup == null) { + return null; + } + } else if (options.has("no-startup")) { + startup = ""; + } + if ((options.valuesOf(fb).size() + + (options.has("q") ? 1 : 0) + + (options.has("s") ? 1 : 0) + + (options.has("v") ? 1 : 0)) > 1) { + startmsg("jshell.err.opt.feedback.one"); + return null; + } else if (options.has(fb)) { + commandLineFeedbackMode = options.valueOf(fb); + } else if (options.has("q")) { + commandLineFeedbackMode = "concise"; + } else if (options.has("s")) { + commandLineFeedbackMode = "silent"; + } else if (options.has("v")) { + commandLineFeedbackMode = "verbose"; + } + if (options.has(r)) { + remoteVMOptions = options.valuesOf(r); + } + + return options.valuesOf(loadFileSpec); } private void printUsage() { @@ -686,7 +705,7 @@ public class JShellTool implements MessageHandler { } if (commandLineFeedbackMode != null) { // The feedback mode to use was specified on the command line, use it - if (!feedback.setFeedback(initmh, new ArgTokenizer("-feedback", commandLineFeedbackMode))) { + if (!feedback.setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) { regenerateOnDeath = false; } commandLineFeedbackMode = null; @@ -1247,7 +1266,7 @@ public class JShellTool implements MessageHandler { // retain editor setting prefs.put(EDITOR_KEY, (editor == null) ? "" - : String.join(RECORD_SEPARATOR, editor)); + : (editorWait? "-" : "*") + String.join(RECORD_SEPARATOR, editor)); return true; case "start": { if (!setStart(cmd, at, false)) { @@ -1302,7 +1321,7 @@ public class JShellTool implements MessageHandler { // The sub-command: /set editor > boolean setEditor(ArgTokenizer at, boolean argsRequired) { - at.allowedOptions("-default"); + at.allowedOptions("-default", "-wait"); String prog = at.next(); List ed = new ArrayList<>(); while (at.val() != null) { @@ -1313,14 +1332,20 @@ public class JShellTool implements MessageHandler { return false; } boolean defaultOption = at.hasOption("-default"); + boolean waitOption = at.hasOption("-wait"); if (prog != null) { if (defaultOption) { errormsg("jshell.err.default.option.or.program", at.whole()); return false; } editor = ed.toArray(new String[ed.size()]); + editorWait = waitOption; fluffmsg("jshell.msg.set.editor.set", prog); } else if (defaultOption) { + if (waitOption) { + errormsg("jshell.err.wait.applies.to.external.editor", at.whole()); + return false; + } editor = null; } else if (argsRequired) { errormsg("jshell.err.set.editor.arg"); @@ -1707,7 +1732,8 @@ public class JShellTool implements MessageHandler { return false; } } else { - ExternalEditor.edit(editor, errorHandler, src, saveHandler, input); + ExternalEditor.edit(editor, errorHandler, src, saveHandler, input, + editorWait, this::hardrb); } return true; } diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties index da44d078219..7f7f12c0433 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties @@ -26,10 +26,11 @@ jshell.msg.welcome =\ Welcome to JShell -- Version {0}\n\ For an introduction type: /help intro\n -jshell.err.opt.classpath.conflict = Conflicting -classpath option. -jshell.err.opt.classpath.arg = Argument to -classpath missing. -jshell.err.opt.feedback.arg = Argument to -feedback missing. Mode required. -jshell.err.opt.startup.one = Only one -startup or -nostartup option may be used. +jshell.err.opt.arg = Argument to {0} missing. +jshell.err.opt.invalid = Invalid options: {0}. +jshell.err.opt.one = Only one {0} option may be used. +jshell.err.opt.startup.one = Only one --startup or --no-startup option may be used. +jshell.err.opt.feedback.one = Only one feedback option (--feedback, -q, -s, or -v) may be used. jshell.err.opt.unknown = Unknown option: {0} jshell.msg.terminated =\ @@ -55,6 +56,8 @@ jshell.err.set.editor.arg = The ''/set editor'' command requires a path argument jshell.msg.set.editor.set = Editor set to: {0} jshell.err.cant.launch.editor = Cannot launch editor -- unexpected exception: {0} jshell.msg.try.set.editor = Try /set editor to use external editor. +jshell.msg.press.return.to.leave.edit.mode = Press return to leave edit mode. +jshell.err.wait.applies.to.external.editor = -wait applies to external editors, cannot be used with -default jshell.msg.try.command.without.args = Try ''{0}'' without arguments. jshell.msg.no.active = There are no active definitions. @@ -148,22 +151,21 @@ jshell.console.incomplete = \nResults may be incomplete; try again later for com help.usage = \ Usage: jshell \n\ where possible options include:\n\ -\ -classpath Specify where to find user class files\n\ -\ -cp Specify where to find user class files\n\ -\ -startup One run replacement for the start-up definitions\n\ -\ -nostartup Do not run the start-up definitions\n\ -\ -feedback Specify the initial feedback mode. The mode may be\n\ -\ predefined (silent, concise, normal, or verbose) or\n\ -\ previously user-defined\n\ -\ -q Quiet feedback. Same as: -feedback concise\n\ -\ -qq Really quiet feedback. Same as: -feedback silent\n\ -\ -v Verbose feedback. Same as: -feedback verbose\n\ -\ -J Pass directly to the runtime system.\n\ -\ Use one -J for each runtime flag or flag argument\n\ -\ -R Pass to the remote runtime system.\n\ -\ Use one -R for each remote flag or flag argument\n\ -\ -help Print this synopsis of standard options\n\ -\ -version Version information\n +\ --class-path Specify where to find user class files\n\ +\ --startup One run replacement for the start-up definitions\n\ +\ --no-startup Do not run the start-up definitions\n\ +\ --feedback Specify the initial feedback mode. The mode may be\n\ +\ predefined (silent, concise, normal, or verbose) or\n\ +\ previously user-defined\n\ +\ -q Quiet feedback. Same as: --feedback concise\n\ +\ -s Really quiet feedback. Same as: --feedback silent\n\ +\ -v Verbose feedback. Same as: --feedback verbose\n\ +\ -J Pass directly to the runtime system.\n\ +\ Use one -J for each runtime flag or flag argument\n\ +\ -R Pass to the remote runtime system.\n\ +\ Use one -R for each remote flag or flag argument\n\ +\ --help Print this synopsis of standard options\n\ +\ --version Version information\n help.list.summary = list the source you have typed help.list.args = [|-all|-start] @@ -358,7 +360,7 @@ Set jshell configuration information, including:\n\ the external editor to use, the start-up definitions to use, a new feedback mode,\n\ the command prompt, the feedback mode to use, or the format of output.\n\ \n\ -/set editor ...\n\t\ +/set editor [-wait] ...\n\t\ Specify the command to launch for the /edit command.\n\t\ The is an operating system dependent string.\n\n\ /set start \n\t\ @@ -602,12 +604,19 @@ The continuation-prompt is used on the second and subsequent lines of a multi-li help.set.editor =\ Specify the command to launch for the /edit command.\n\ \n\t\ -/set editor |-default\n\ +/set editor [-wait] |-default\n\ \n\ The is an operating system dependent string.\n\ -The may include space-separated arguments (such as flags)\n\ -When /edit is used, the temporary file to edit will be appended as the last argument.\n\ -If instead the -default option is specified, the built-in default editor will be used. +The may include space-separated arguments (such as flags)\n\n\ +If the -default option is specified, the built-in default editor will be used.\n\n\ +Otherwise an external editor should be specified in . When \n\ +is used, the temporary file to edit will be appended as the last argument.\n\ +Normally, edit mode will last until the external editor exits. Some external editors\n\ +will exit immediately (for example, if the edit window exists) either external editor\n\ +flags should be used to prevent immediate exit, or the -wait option should be used to\n\ +prompt the user to indicate when edit mode should end.\n\n\ +Note: while in edit mode no command inputs are seen. After leaving edit mode changes\n\ +to the edited snippets are not seen. help.set.start =\ Set the start-up configuration -- a sequence of snippets and commands read at start-up.\n\ diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java index 26f43fc5c15..3655b64aad4 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java @@ -52,8 +52,6 @@ import javax.tools.SimpleJavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; -import com.sun.tools.javac.util.DefinedBy; -import com.sun.tools.javac.util.DefinedBy.Api; import static jdk.internal.jshell.debug.InternalDebugControl.DBG_FMGR; @@ -71,8 +69,6 @@ class MemoryFileManager implements JavaFileManager { private ClassFileCreationListener classListener = null; - private final ClassLoader loader = new REPLClassLoader(); - private final JShell proc; // Upcoming Jigsaw @@ -105,7 +101,7 @@ class MemoryFileManager implements JavaFileManager { return origin; } - @Override @DefinedBy(Api.COMPILER) + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) { return src; } @@ -148,7 +144,7 @@ class MemoryFileManager implements JavaFileManager { } } - @Override @DefinedBy(Api.COMPILER) + @Override public String getName() { return className; } @@ -157,32 +153,17 @@ class MemoryFileManager implements JavaFileManager { * Will provide the compiler with an output stream that leads to our * byte array. */ - @Override @DefinedBy(Api.COMPILER) + @Override public OutputStream openOutputStream() throws IOException { return bos; } - @Override @DefinedBy(Api.COMPILER) + @Override public InputStream openInputStream() throws IOException { return new ByteArrayInputStream(getBytes()); } } - // For restoring process-local execution support - class REPLClassLoader extends ClassLoader { - - @Override - protected Class findClass(String name) throws ClassNotFoundException { - OutputMemoryJavaFileObject fo = classObjects.get(name); - proc.debug(DBG_FMGR, "findClass %s = %s\n", name, fo); - if (fo == null) { - throw new ClassNotFoundException("Not ours"); - } - byte[] b = fo.getBytes(); - return super.defineClass(name, b, 0, b.length, null); - } - } - public MemoryFileManager(StandardJavaFileManager standardManager, JShell proc) { this.stdFileManager = standardManager; this.proc = proc; @@ -199,39 +180,11 @@ class MemoryFileManager implements JavaFileManager { } } - // For restoring process-local execution support - public Class findGeneratedClass(String genClassFullName) throws ClassNotFoundException { - for (OutputMemoryJavaFileObject co : generatedClasses()) { - if (co.className.equals(genClassFullName)) { - Class klass = loadClass(co.className); - proc.debug(DBG_FMGR, "Loaded %s\n", klass); - return klass; - } - } - return null; - } - - // For restoring process-local execution support - public byte[] findGeneratedBytes(String genClassFullName) throws ClassNotFoundException { - for (OutputMemoryJavaFileObject co : generatedClasses()) { - if (co.className.equals(genClassFullName)) { - return co.getBytes(); - } - } - return null; - } - - // For restoring process-local execution support - public Class loadClass(String name) throws ClassNotFoundException { - return getClassLoader(null).loadClass(name); - } - public JavaFileObject createSourceFileObject(Object origin, String name, String code) { return new SourceMemoryJavaFileObject(origin, name, code); } // Make compatible with Jigsaw - @DefinedBy(Api.COMPILER) public String inferModuleName(Location location) { try { if (inferModuleNameMethod == null) { @@ -250,7 +203,6 @@ class MemoryFileManager implements JavaFileManager { } // Make compatible with Jigsaw - @DefinedBy(Api.COMPILER) public Iterable> listModuleLocations(Location location) throws IOException { try { if (listModuleLocationsMethod == null) { @@ -285,10 +237,10 @@ class MemoryFileManager implements JavaFileManager { * @throws IllegalStateException if {@link #close} has been called * and this file manager cannot be reopened */ - @Override @DefinedBy(Api.COMPILER) + @Override public ClassLoader getClassLoader(JavaFileManager.Location location) { proc.debug(DBG_FMGR, "getClassLoader: location\n", location); - return loader; + return stdFileManager.getClassLoader(location); } /** @@ -311,7 +263,7 @@ class MemoryFileManager implements JavaFileManager { * @throws IllegalStateException if {@link #close} has been called * and this file manager cannot be reopened */ - @Override @DefinedBy(Api.COMPILER) + @Override public Iterable list(JavaFileManager.Location location, String packageName, Set kinds, @@ -368,7 +320,7 @@ class MemoryFileManager implements JavaFileManager { * @throws IllegalStateException if {@link #close} has been called * and this file manager cannot be reopened */ - @Override @DefinedBy(Api.COMPILER) + @Override public String inferBinaryName(JavaFileManager.Location location, JavaFileObject file) { if (file instanceof OutputMemoryJavaFileObject) { OutputMemoryJavaFileObject ofo = (OutputMemoryJavaFileObject) file; @@ -392,7 +344,7 @@ class MemoryFileManager implements JavaFileManager { * were created with another file manager and this file manager * does not support foreign file objects */ - @Override @DefinedBy(Api.COMPILER) + @Override public boolean isSameFile(FileObject a, FileObject b) { return stdFileManager.isSameFile(b, b); } @@ -405,7 +357,7 @@ class MemoryFileManager implements JavaFileManager { * @return the number of arguments the given option takes or -1 if * the option is not supported */ - @Override @DefinedBy(Api.COMPILER) + @Override public int isSupportedOption(String option) { proc.debug(DBG_FMGR, "isSupportedOption: %s\n", option); return stdFileManager.isSupportedOption(option); @@ -425,7 +377,7 @@ class MemoryFileManager implements JavaFileManager { * @throws IllegalStateException if {@link #close} has been called * and this file manager cannot be reopened */ - @Override @DefinedBy(Api.COMPILER) + @Override public boolean handleOption(String current, Iterator remaining) { proc.debug(DBG_FMGR, "handleOption: current: %s\n", current + ", remaining: " + remaining); @@ -438,7 +390,7 @@ class MemoryFileManager implements JavaFileManager { * @param location a location * @return true if the location is known */ - @Override @DefinedBy(Api.COMPILER) + @Override public boolean hasLocation(JavaFileManager.Location location) { proc.debug(DBG_FMGR, "hasLocation: location: %s\n", location); return stdFileManager.hasLocation(location); @@ -474,7 +426,7 @@ class MemoryFileManager implements JavaFileManager { * @throws IllegalStateException if {@link #close} has been called * and this file manager cannot be reopened */ - @Override @DefinedBy(Api.COMPILER) + @Override public JavaFileObject getJavaFileForInput(JavaFileManager.Location location, String className, JavaFileObject.Kind kind) @@ -514,7 +466,7 @@ class MemoryFileManager implements JavaFileManager { * @throws IllegalStateException {@link #close} has been called * and this file manager cannot be reopened */ - @Override @DefinedBy(Api.COMPILER) + @Override public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location, String className, Kind kind, FileObject sibling) throws IOException { @@ -567,7 +519,7 @@ class MemoryFileManager implements JavaFileManager { * @throws IllegalStateException if {@link #close} has been called * and this file manager cannot be reopened */ - @Override @DefinedBy(Api.COMPILER) + @Override public FileObject getFileForInput(JavaFileManager.Location location, String packageName, String relativeName) @@ -616,7 +568,7 @@ class MemoryFileManager implements JavaFileManager { * @throws IllegalStateException if {@link #close} has been called * and this file manager cannot be reopened */ - @Override @DefinedBy(Api.COMPILER) + @Override public FileObject getFileForOutput(JavaFileManager.Location location, String packageName, String relativeName, @@ -636,7 +588,7 @@ class MemoryFileManager implements JavaFileManager { * @throws IOException if an I/O error occurred * @see #close */ - @Override @DefinedBy(Api.COMPILER) + @Override public void flush() throws IOException { // Nothing to flush } @@ -652,7 +604,7 @@ class MemoryFileManager implements JavaFileManager { * @throws IOException if an I/O error occurred * @see #flush */ - @Override @DefinedBy(Api.COMPILER) + @Override public void close() throws IOException { // Nothing to close } diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java index 0c2d85d0d69..090bfb6d969 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java @@ -55,8 +55,6 @@ import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type.ClassType; -import com.sun.tools.javac.util.DefinedBy; -import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Pair; @@ -534,7 +532,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { TreePath[] deepest = new TreePath[1]; new TreePathScanner() { - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void scan(Tree tree, Void p) { if (tree == null) return null; @@ -552,7 +550,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { return null; } - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void visitErroneous(ErroneousTree node, Void p) { return scan(node.getErrorTrees(), null); } @@ -1250,7 +1248,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { Trees trees = Trees.instance(source.fst); new TreePathScanner() { - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void visitMethod(MethodTree node, Void p) { Element currentMethod = trees.getElement(getCurrentPath()); diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDependencyScanner.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDependencyScanner.java index 5c5840ff080..5dc9e6663c6 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDependencyScanner.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDependencyScanner.java @@ -34,8 +34,6 @@ import com.sun.source.tree.PackageTree; import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; import com.sun.source.util.TreeScanner; -import com.sun.tools.javac.util.DefinedBy; -import com.sun.tools.javac.util.DefinedBy.Api; import java.util.Collection; import java.util.HashSet; import java.util.Set; @@ -67,7 +65,7 @@ class TreeDependencyScanner extends TreeScanner> { // -- Differentiate declaration references from body references --- - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void visitClass(ClassTree node, Set p) { scan(node.getModifiers(), p); scan(node.getTypeParameters(), p); @@ -77,7 +75,7 @@ class TreeDependencyScanner extends TreeScanner> { return null; } - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void visitMethod(MethodTree node, Set p) { scan(node.getModifiers(), p); scan(node.getReturnType(), p); @@ -90,7 +88,7 @@ class TreeDependencyScanner extends TreeScanner> { return null; } - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void visitVariable(VariableTree node, Set p) { scan(node.getModifiers(), p); scan(node.getType(), p); @@ -101,12 +99,12 @@ class TreeDependencyScanner extends TreeScanner> { // --- Ignore these --- - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void visitPackage(PackageTree node, Set p) { return null; } - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void visitImport(ImportTree node, Set p) { return null; } @@ -114,13 +112,13 @@ class TreeDependencyScanner extends TreeScanner> { // -- Actual Symbol names --- - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void visitMemberSelect(MemberSelectTree node, Set p) { add(p, node.getIdentifier()); return super.visitMemberSelect(node, p); } - @Override @DefinedBy(Api.COMPILER_TREE) + @Override public Void visitIdentifier(IdentifierTree node, Set p) { add(p, node.getName()); return super.visitIdentifier(node, p); diff --git a/langtools/src/jdk.jshell/share/classes/module-info.java b/langtools/src/jdk.jshell/share/classes/module-info.java index b6c1b522bbc..b9c6e5e2b26 100644 --- a/langtools/src/jdk.jshell/share/classes/module-info.java +++ b/langtools/src/jdk.jshell/share/classes/module-info.java @@ -34,6 +34,7 @@ module jdk.jshell { requires java.prefs; requires jdk.compiler; requires jdk.internal.le; + requires jdk.internal.opt; requires jdk.jdi; exports jdk.jshell; diff --git a/langtools/test/ProblemList.txt b/langtools/test/ProblemList.txt index 9a85f8b3d9e..a90395e8734 100644 --- a/langtools/test/ProblemList.txt +++ b/langtools/test/ProblemList.txt @@ -30,6 +30,7 @@ jdk/javadoc/tool/VerifyLocale.java jdk/javadoc/tool/enum/docComments/Main.java 8152313 generic-all convert to doclet test framework jdk/javadoc/tool/enum/enumType/Main.java 8152313 generic-all convert to doclet test framework jdk/javadoc/tool/varArgs/Main.java 8152313 generic-all convert to doclet test framework +jdk/javadoc/doclet/testIOException/TestIOException.java 8164597 windows-all ########################################################################### # @@ -77,3 +78,9 @@ tools/sjavac/ClasspathDependencies.java 8158002 generic-all Requires i # # jdeps +########################################################################### +# +# jdeprscan + +tools/jdeprscan/tests/jdk/jdeprscan/TestLoad.java 8164837 windows-all probably line breaks or encoding +tools/jdeprscan/tests/jdk/jdeprscan/TestScan.java 8164837 windows-all probably line breaks or encoding diff --git a/langtools/test/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java b/langtools/test/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java new file mode 100644 index 00000000000..1bc03c87bb4 --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8157349 + * @summary test copy of doc-files + * @library ../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build JavadocTester + * @run main TestCopyFiles + */ + +public class TestCopyFiles extends JavadocTester { + + public static void main(String... args) throws Exception { + TestCopyFiles tester = new TestCopyFiles(); + tester.runTests(); + } + + @Test + void testDocFilesInModules() { + javadoc("-d", "modules-out", + "--module-source-path", testSrc("modules"), + "--module", "acme.mdle"); + checkExit(Exit.OK); + checkOutput("p/doc-files/inpackage.html", true, + "In a named module and named package" + ); + } + + @Test + void testDocFilesInPackages() { + javadoc("-d", "packages-out", + "-sourcepath", testSrc("packages"), + "p1"); + checkExit(Exit.OK); + checkOutput("p1/doc-files/inpackage.html", true, + "A named package in an unnamed module" + ); + } + + @Test + void testDocFilesInUnnamedPackages() { + javadoc("-d", "unnamed-out", + "-sourcepath", testSrc("unnamed"), + testSrc("unnamed/Foo.java") + ); + checkExit(Exit.OK); + checkOutput("doc-files/inpackage.html", true, + "In an unnamed package" + ); + } + + @Test + void testDocFilesInPackagesSource7() { + javadoc("-d", "packages-out-src7", + "-source", "7", + "-sourcepath", testSrc("packages"), + "p1"); + checkExit(Exit.OK); + checkOutput("p1/doc-files/inpackage.html", true, + "A named package in an unnamed module" + ); + } + + @Test + void testDocFilesInPackagesSource7UsingClassPath() { + javadoc("-d", "packages-out-src7-cp", + "-source", "7", + "-classpath", testSrc("packages"), + "p1"); + checkExit(Exit.OK); + checkOutput("p1/doc-files/inpackage.html", true, + "A named package in an unnamed module" + ); + } +} diff --git a/langtools/test/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/module-info.java b/langtools/test/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/module-info.java new file mode 100644 index 00000000000..3b24d984582 --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/module-info.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /** + * A test module. + */ +module acme.mdle { + exports p; +} diff --git a/langtools/test/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/Foo.java b/langtools/test/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/Foo.java new file mode 100644 index 00000000000..e12c8d27504 --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/Foo.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package p; + +/** + * A test class. + */ +public class Foo {} diff --git a/langtools/test/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/doc-files/inpackage.html b/langtools/test/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/doc-files/inpackage.html new file mode 100644 index 00000000000..c5a0ddb575f --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/doc-files/inpackage.html @@ -0,0 +1,33 @@ + + + + + "Hello World" + + + In a named module and named package + + diff --git a/langtools/test/jdk/javadoc/doclet/testCopyFiles/packages/p1/Foo.java b/langtools/test/jdk/javadoc/doclet/testCopyFiles/packages/p1/Foo.java new file mode 100644 index 00000000000..8e1960b5788 --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testCopyFiles/packages/p1/Foo.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /** + * A test class. + */ +package p1; + +/** + * A test class. + */ +public class Foo {} diff --git a/langtools/test/jdk/javadoc/doclet/testCopyFiles/packages/p1/doc-files/inpackage.html b/langtools/test/jdk/javadoc/doclet/testCopyFiles/packages/p1/doc-files/inpackage.html new file mode 100644 index 00000000000..4879d78d5a4 --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testCopyFiles/packages/p1/doc-files/inpackage.html @@ -0,0 +1,33 @@ + + + + + "Hello World" + + + A named package in an unnamed module. + + diff --git a/langtools/test/jdk/javadoc/doclet/testCopyFiles/unnamed/Foo.java b/langtools/test/jdk/javadoc/doclet/testCopyFiles/unnamed/Foo.java new file mode 100644 index 00000000000..48210d11a77 --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testCopyFiles/unnamed/Foo.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /** + * A test class. + */ + +/** + * A test class. + */ +public class Foo {} diff --git a/langtools/test/jdk/javadoc/doclet/testCopyFiles/unnamed/doc-files/inpackage.html b/langtools/test/jdk/javadoc/doclet/testCopyFiles/unnamed/doc-files/inpackage.html new file mode 100644 index 00000000000..5321e80d86b --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testCopyFiles/unnamed/doc-files/inpackage.html @@ -0,0 +1,33 @@ + + + + + "Hello World" + + + In an unnamed package + + diff --git a/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java b/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java index c9a6f1aa5b2..bb3fee6849e 100644 --- a/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java +++ b/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8162353 + * @bug 8162353 8164747 * @summary javadoc should provide a way to disable use of frames * @library /tools/lib ../lib * @modules @@ -204,7 +204,7 @@ public class TestFramesNoFrames extends JavadocTester { @Test void testModules(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException { javadoc(base, fKind, oKind, hKind, - "-modulesourcepath", gensrcModules.toString(), + "--module-source-path", gensrcModules.toString(), "--module", "m1,m2,m3"); new Checker(fKind, oKind, hKind) @@ -283,6 +283,19 @@ public class TestFramesNoFrames extends JavadocTester { // this file is only generated when not in frames mode checkFiles(!frames, "allclasses.html"); + + if (frames) { + checkOutput("allclasses-frame.html", true, + classes.stream() + .map(c -> "title=\"class in " + packagePart(c) + "\" target=\"classFrame\">" + classPart(c) + "") + .toArray(String[]::new)); + checkOutput("allclasses-noframe.html", false, + "target=\"classFrame\">"); + } else { + checkOutput("allclasses.html", false, + "target=\"classFrame\">"); + + } } private void checkFrameFiles() { @@ -367,6 +380,11 @@ public class TestFramesNoFrames extends JavadocTester { .count(); } + private String classPart(String className) { + int lastDot = className.lastIndexOf("."); + return className.substring(lastDot + 1); + } + private String packagePart(String className) { int slash = className.indexOf("/"); int lastDot = className.lastIndexOf("."); diff --git a/langtools/test/jdk/javadoc/doclet/testIOException/TestIOException.java b/langtools/test/jdk/javadoc/doclet/testIOException/TestIOException.java new file mode 100644 index 00000000000..792baa0627c --- /dev/null +++ b/langtools/test/jdk/javadoc/doclet/testIOException/TestIOException.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8164130 + * @summary test IOException handling + * @library ../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build JavadocTester + * @run main TestIOException + */ + +import java.io.File; +import java.io.FileWriter; + +public class TestIOException extends JavadocTester { + + public static void main(String... args) throws Exception { + TestIOException tester = new TestIOException(); + tester.runTests(); + } + + @Test + void testReadOnlyDirectory() { + File outDir = new File("out1"); + if (!outDir.mkdir()) { + throw new Error("Cannot create directory"); + } + if (!outDir.setReadOnly()) { + throw new Error("could not set directory read-only"); + } + if (outDir.canWrite()) { + throw new Error("directory is writable"); + } + + try { + javadoc("-d", outDir.toString(), + new File(testSrc, "TestIOException.java").getPath()); + checkExit(Exit.FAILED); + checkOutput(Output.OUT, true, + "Destination directory not writable: " + outDir); + } finally { + outDir.setWritable(true); + } + } + + @Test + void testReadOnlyFile() throws Exception { + File outDir = new File("out2"); + if (!outDir.mkdir()) { + throw new Error("Cannot create directory"); + } + File index = new File(outDir, "index.html"); + try (FileWriter fw = new FileWriter(index)) { } + if (!index.setReadOnly()) { + throw new Error("could not set index read-only"); + } + if (index.canWrite()) { + throw new Error("index is writable"); + } + + try { + setOutputDirectoryCheck(DirectoryCheck.NONE); + javadoc("-d", outDir.toString(), + new File(testSrc, "TestIOException.java").getPath()); + + checkExit(Exit.FAILED); + checkOutput(Output.OUT, true, + "Error writing file: " + index); + } finally { + setOutputDirectoryCheck(DirectoryCheck.EMPTY); + index.setWritable(true); + } + } + + @Test + void testReadOnlySubdirectory() throws Exception { + // init source file + File srcDir = new File("src4"); + File src_p = new File(srcDir, "p"); + src_p.mkdirs(); + File src_p_C = new File(src_p, "C.java"); + try (FileWriter fw = new FileWriter(src_p_C)) { + fw.write("package p; public class C { }"); + } + + // create an unwritable package output directory + File outDir = new File("out3"); + File pkgOutDir = new File(outDir, "p"); + if (!pkgOutDir.mkdirs()) { + throw new Error("Cannot create directory"); + } + if (!pkgOutDir.setReadOnly()) { + throw new Error("could not set directory read-only"); + } + if (pkgOutDir.canWrite()) { + throw new Error("directory is writable"); + } + + // run javadoc and check results + try { + setOutputDirectoryCheck(DirectoryCheck.NONE); + javadoc("-d", outDir.toString(), + src_p_C.getPath()); + checkExit(Exit.FAILED); + checkOutput(Output.OUT, true, + "Error writing file: " + new File(pkgOutDir, "C.html")); + } finally { + setOutputDirectoryCheck(DirectoryCheck.EMPTY); + pkgOutDir.setWritable(true); + } + } + + @Test + void testReadOnlyDocFilesDir() throws Exception { + // init source files + File srcDir = new File("src4"); + File src_p = new File(srcDir, "p"); + src_p.mkdirs(); + File src_p_C = new File(src_p, "C.java"); + try (FileWriter fw = new FileWriter(src_p_C)) { + fw.write("package p; public class C { }"); + } + File src_p_docfiles = new File(src_p, "doc-files"); + src_p_docfiles.mkdir(); + try (FileWriter fw = new FileWriter(new File(src_p_docfiles, "info.txt"))) { + fw.write("info"); + } + + // create an unwritable doc-files output directory + File outDir = new File("out4"); + File pkgOutDir = new File(outDir, "p"); + File docFilesOutDir = new File(pkgOutDir, "doc-files"); + if (!docFilesOutDir.mkdirs()) { + throw new Error("Cannot create directory"); + } + if (!docFilesOutDir.setReadOnly()) { + throw new Error("could not set directory read-only"); + } + if (docFilesOutDir.canWrite()) { + throw new Error("directory is writable"); + } + + try { + setOutputDirectoryCheck(DirectoryCheck.NONE); + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.getPath(), + "p"); + checkExit(Exit.FAILED); + checkOutput(Output.OUT, true, + "Error writing file: " + new File(docFilesOutDir, "info.txt")); + } finally { + setOutputDirectoryCheck(DirectoryCheck.EMPTY); + docFilesOutDir.setWritable(true); + } + } +} + diff --git a/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java b/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java index 5498f5154d1..79e166c9b8f 100644 --- a/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java +++ b/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java @@ -160,8 +160,8 @@ public class TestModules extends JavadocTester { @Test void testModuleSummary() { javadoc("-d", "out-moduleSummary", "-use", - "-modulesourcepath", testSrc, - "-addmods", "module1,module2", + "--module-source-path", testSrc, + "--add-modules", "module1,module2", "testpkgmdl1", "testpkgmdl2", "module2/testpkg2mdl2"); checkExit(Exit.OK); checkModuleSummary(); @@ -174,8 +174,8 @@ public class TestModules extends JavadocTester { @Test void testModuleFilesAndLinks() { javadoc("-d", "out-modulelinks", - "-modulesourcepath", testSrc, - "-addmods", "module1", + "--module-source-path", testSrc, + "--add-modules", "module1", "testpkgmdl1"); checkExit(Exit.OK); checkModuleFilesAndLinks(true); diff --git a/langtools/test/jdk/javadoc/doclet/testTypeAnnotations/typeannos/RepeatedAnnotations.java b/langtools/test/jdk/javadoc/doclet/testTypeAnnotations/typeannos/RepeatedAnnotations.java index 75bedba621e..b7c432ee3ac 100644 --- a/langtools/test/jdk/javadoc/doclet/testTypeAnnotations/typeannos/RepeatedAnnotations.java +++ b/langtools/test/jdk/javadoc/doclet/testTypeAnnotations/typeannos/RepeatedAnnotations.java @@ -8,7 +8,7 @@ * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR RepeatingA PARTICULAR PURPOSE. See the GNU General Public License + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * diff --git a/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java b/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java index 0962c12a5a8..28e01da29c8 100644 --- a/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java +++ b/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java @@ -27,7 +27,6 @@ * @summary Tests elements filtering options * @modules * jdk.javadoc/jdk.javadoc.internal.api - * jdk.javadoc/jdk.javadoc.internal.doclets.standard * jdk.javadoc/jdk.javadoc.internal.tool * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -60,7 +59,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testDefault(Path base) throws Exception { - execTask("-modulesourcepath", src, "--module", "m1"); + execTask("--module-source-path", src, "--module", "m1"); checkModulesSpecified("m1"); checkModulesIncluded("m1"); @@ -70,7 +69,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testModuleModeApi(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-module-contents:api"); checkModuleMode("API"); @@ -78,7 +77,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testModuleModeAll(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-module-contents:all"); checkModuleMode("ALL"); @@ -86,7 +85,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowPackagesExported(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-packages:exported"); // default @@ -98,7 +97,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowPackagesAll(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-packages:all"); checkModulesSpecified("m1"); @@ -111,7 +110,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowTypesPrivate(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-types:private"); @@ -128,7 +127,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowTypesPackage(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-types:package"); @@ -144,7 +143,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowTypesProtected(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-types:protected"); @@ -161,7 +160,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowTypesPublic(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-types:public"); @@ -178,7 +177,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowMembersPrivate(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-members:private"); @@ -187,7 +186,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowMembersPackage(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-members:package"); @@ -196,7 +195,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowMembersProtected(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-members:protected"); @@ -205,7 +204,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testShowMembersPublic(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "--show-members:public"); @@ -214,7 +213,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testLegacyPublic(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "-public"); @@ -229,7 +228,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testLegacyDefault(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1"); checkModuleMode("API"); @@ -243,7 +242,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testLegacyProtected(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "-protected"); @@ -258,7 +257,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testLegacyPackage(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "-package"); @@ -277,7 +276,7 @@ public class FilterOptions extends ModuleTestBase { @Test public void testLegacyPrivate(Path base) throws Exception { - execTask("-modulesourcepath", src, + execTask("--module-source-path", src, "--module", "m1", "-private"); diff --git a/langtools/test/jdk/javadoc/tool/modules/Modules.java b/langtools/test/jdk/javadoc/tool/modules/Modules.java index 5339933967a..496a8e2c3cb 100644 --- a/langtools/test/jdk/javadoc/tool/modules/Modules.java +++ b/langtools/test/jdk/javadoc/tool/modules/Modules.java @@ -27,7 +27,6 @@ * @summary Tests primarily the module graph computations. * @modules * jdk.javadoc/jdk.javadoc.internal.api - * jdk.javadoc/jdk.javadoc.internal.doclets.standard * jdk.javadoc/jdk.javadoc.internal.tool * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -58,7 +57,7 @@ public class Modules extends ModuleTestBase { .classes("package pub; /** Klass A */ public class A {}") .classes("package pro; /** Klass B */ public class B {}") .write(src); - execTask("-modulesourcepath", src.toString(), + execTask("--module-source-path", src.toString(), "--module", "m1"); checkModulesSpecified("m1"); checkPackagesIncluded("pub"); @@ -83,7 +82,7 @@ public class Modules extends ModuleTestBase { .classes("package m2pub; /** Klass A */ public class A {}") .classes("package m2pro; /** Klass B */ public class B {}") .write(src); - execTask("-modulesourcepath", src.toString(), + execTask("--module-source-path", src.toString(), "--module", "m1,m2"); checkModulesSpecified("m1", "m2"); checkPackagesIncluded("m1pub", "m2pub"); @@ -109,7 +108,7 @@ public class Modules extends ModuleTestBase { .classes("package m2pub; /** Klass A */ public class A {}") .classes("package m2pro; /** Klass B */ public class B {}") .write(src); - execTask("-modulesourcepath", src.toString(), + execTask("--module-source-path", src.toString(), "--module", "m1", "--module", "m2"); checkModulesSpecified("m1", "m2"); @@ -152,7 +151,7 @@ public class Modules extends ModuleTestBase { .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") .write(src); - execTask("-modulesourcepath", src.toString(), + execTask("--module-source-path", src.toString(), "--module", "M"); checkModulesSpecified("M"); @@ -176,7 +175,7 @@ public class Modules extends ModuleTestBase { .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") .write(src); - execTask("-modulesourcepath", src.toString(), + execTask("--module-source-path", src.toString(), "--module", "M", "--expand-requires:public"); @@ -201,7 +200,7 @@ public class Modules extends ModuleTestBase { .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") .write(src); - execTask("-modulesourcepath", src.toString(), + execTask("--module-source-path", src.toString(), "--module", "M", "--expand-requires:all"); @@ -229,7 +228,7 @@ public class Modules extends ModuleTestBase { .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") .write(src); - execNegativeTask("-modulesourcepath", src.toString(), + execNegativeTask("--module-source-path", src.toString(), "--module", "MIA", "--expand-requires:all"); @@ -251,7 +250,7 @@ public class Modules extends ModuleTestBase { .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }") .write(src); - execNegativeTask("-modulesourcepath", src.toString(), + execNegativeTask("--module-source-path", src.toString(), "--module", "M,N,L,MIA,O,P", "--expand-requires:all"); diff --git a/langtools/test/jdk/javadoc/tool/modules/PackageOptions.java b/langtools/test/jdk/javadoc/tool/modules/PackageOptions.java index fe7ca40cec3..6335418aff5 100644 --- a/langtools/test/jdk/javadoc/tool/modules/PackageOptions.java +++ b/langtools/test/jdk/javadoc/tool/modules/PackageOptions.java @@ -27,7 +27,6 @@ * @summary Test modules with packages and subpackages filtering * @modules * jdk.javadoc/jdk.javadoc.internal.api - * jdk.javadoc/jdk.javadoc.internal.doclets.standard * jdk.javadoc/jdk.javadoc.internal.tool * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -52,8 +51,8 @@ public class PackageOptions extends ModuleTestBase { @Test public void testExportedNonQualifiedPackagesLegacyMode(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src")), - "-addmods", "m1", + execTask("--module-source-path", createSources(base.resolve("src")), + "--add-modules", "m1", "m1pub"); checkModulesNotSpecified("m1"); @@ -64,8 +63,8 @@ public class PackageOptions extends ModuleTestBase { @Test public void testExportedQualifiedPackagesLegacyMode(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src")), - "-addmods", "m1", + execTask("--module-source-path", createSources(base.resolve("src")), + "--add-modules", "m1", "m1/m1pub"); checkModulesNotSpecified("m1"); @@ -76,8 +75,8 @@ public class PackageOptions extends ModuleTestBase { @Test public void testNonExportedQualifedPackagesLegacyMode(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src")), - "-addmods", "m1", + execTask("--module-source-path", createSources(base.resolve("src")), + "--add-modules", "m1", "m1/m1pro.pro1" /* not exported, therefore qualify with module */); checkModulesNotSpecified("m1"); @@ -92,8 +91,8 @@ public class PackageOptions extends ModuleTestBase { public void testTypesLegacyMode(Path base) throws Exception { Path srcPath = base.resolve("src"); Path typPath = srcPath.resolve("m1/m1pub/A.java"); - execTask("-modulesourcepath", createSources(srcPath), - "-addmods", "m1", + execTask("--module-source-path", createSources(srcPath), + "--add-modules", "m1", typPath.toString()); checkModulesNotSpecified("m1"); checkModulesIncluded("m1"); @@ -109,8 +108,8 @@ public class PackageOptions extends ModuleTestBase { public void testSubclassedTypesLegacyMode(Path base) throws Exception { Path srcPath = base.resolve("src"); Path typPath = srcPath.resolve("m1/m1pub/B.java"); - execTask("-modulesourcepath", createSources(srcPath), - "-addmods", "m1", + execTask("--module-source-path", createSources(srcPath), + "--add-modules", "m1", typPath.toString()); checkModulesNotSpecified("m1"); checkModulesIncluded("m1"); @@ -124,7 +123,7 @@ public class PackageOptions extends ModuleTestBase { @Test public void testDefaultPackages(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src")), + execTask("--module-source-path", createSources(base.resolve("src")), "--module", "m1"); checkModulesSpecified("m1"); @@ -149,20 +148,20 @@ public class PackageOptions extends ModuleTestBase { // I/O error encounted during the iteration throw ex.getCause(); } - execTask("-modulesourcepath", src.toString(), + execTask("--module-source-path", src.toString(), "-subpackages", "m1/m1pro"); checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2"); // empty package directory should cause an error - execNegativeTask("-modulesourcepath", src.toString(), + execNegativeTask("--module-source-path", src.toString(), "m1/m1pro"); } @Test public void testExportedQualifiedSubpackageWithMultipleModules(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src"), 2), + execTask("--module-source-path", createSources(base.resolve("src"), 2), "--module", "m1", "-subpackages", "m1/m1pro.pro1:m1/m1pro.pro2:m2/m2pub.pub1"); @@ -177,7 +176,7 @@ public class PackageOptions extends ModuleTestBase { @Test public void testUnexportedUnqualifiedSubpackages(Path base) throws Exception { - execNegativeTask("-modulesourcepath", createSources(base.resolve("src")), + execNegativeTask("--module-source-path", createSources(base.resolve("src")), "--module", "m1", "-subpackages", "m1pub.pub1:pro"); @@ -186,7 +185,7 @@ public class PackageOptions extends ModuleTestBase { @Test public void testUnexportedQualifiedPackage(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src")), + execTask("--module-source-path", createSources(base.resolve("src")), "--module", "m1", "m1/m1pro"); @@ -201,7 +200,7 @@ public class PackageOptions extends ModuleTestBase { @Test public void testUnexportedQualifiedSubpackage(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src")), + execTask("--module-source-path", createSources(base.resolve("src")), "--module", "m1", "-subpackages", "m1/m1pro"); @@ -216,7 +215,7 @@ public class PackageOptions extends ModuleTestBase { @Test public void testUnexportedQualifiedSubpackageExcludeQualified(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src")), + execTask("--module-source-path", createSources(base.resolve("src")), "--module", "m1", "-subpackages", "m1/m1pro", "-exclude", "m1/m1pro.pro1.pro11:m1/m1pro.pro2.pro21"); @@ -233,7 +232,7 @@ public class PackageOptions extends ModuleTestBase { @Test public void testUnexportedQualifiedSubpackageExcludeUnqualified(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src")), + execTask("--module-source-path", createSources(base.resolve("src")), "--module", "m1", "-subpackages", "m1/m1pro", "-exclude", "m1pro.pro1.pro11:m1pro.pro2.pro21"); @@ -250,7 +249,7 @@ public class PackageOptions extends ModuleTestBase { @Test public void testUnexportedQualifiedSubpackages(Path base) throws Exception { - execTask("-modulesourcepath", createSources(base.resolve("src")), + execTask("--module-source-path", createSources(base.resolve("src")), "--module", "m1", "-subpackages", "m1/m1pro.pro1:m1/m1pro.pro2"); diff --git a/langtools/test/jdk/jshell/CommandCompletionTest.java b/langtools/test/jdk/jshell/CommandCompletionTest.java index 0a986a621c1..6544084a133 100644 --- a/langtools/test/jdk/jshell/CommandCompletionTest.java +++ b/langtools/test/jdk/jshell/CommandCompletionTest.java @@ -58,7 +58,7 @@ public class CommandCompletionTest extends ReplToolTesting { } public void testList() { - test(false, new String[] {"-nostartup"}, + test(false, new String[] {"--no-startup"}, a -> assertCompletion(a, "/l|", false, "/list "), a -> assertCompletion(a, "/list |", false, "-all ", "-history ", "-start "), a -> assertCompletion(a, "/list -h|", false, "-history "), @@ -70,7 +70,7 @@ public class CommandCompletionTest extends ReplToolTesting { } public void testDrop() { - test(false, new String[] {"-nostartup"}, + test(false, new String[] {"--no-startup"}, a -> assertCompletion(a, "/d|", false, "/drop "), a -> assertClass(a, "class cTest {}", "class", "cTest"), a -> assertMethod(a, "int mTest() { return 0; }", "()I", "mTest"), @@ -81,7 +81,7 @@ public class CommandCompletionTest extends ReplToolTesting { } public void testEdit() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, a -> assertCompletion(a, "/e|", false, "/edit ", "/exit "), a -> assertCompletion(a, "/ed|", false, "/edit "), a -> assertClass(a, "class cTest {}", "class", "cTest"), diff --git a/langtools/test/jdk/jshell/EditorTestBase.java b/langtools/test/jdk/jshell/EditorTestBase.java index 067bbb9da99..18b6dae4557 100644 --- a/langtools/test/jdk/jshell/EditorTestBase.java +++ b/langtools/test/jdk/jshell/EditorTestBase.java @@ -42,7 +42,7 @@ public abstract class EditorTestBase extends ReplToolTesting { public abstract void shutdownEditor(); public void testEditor(ReplTest... tests) { - testEditor(false, new String[]{"-nostartup"}, tests); + testEditor(false, new String[]{"--no-startup"}, tests); } public void testEditor(boolean defaultStartup, String[] args, ReplTest... tests) { @@ -71,7 +71,7 @@ public abstract class EditorTestBase extends ReplToolTesting { @Test public void testEditNegative() { for (String edit : new String[] {"/ed", "/edit"}) { - test(new String[]{"-nostartup"}, + test(new String[]{"--no-startup"}, a -> assertCommandOutputStartsWith(a, edit + " 1", "| No such snippet: 1"), a -> assertCommandOutputStartsWith(a, edit + " unknown", diff --git a/langtools/test/jdk/jshell/ExternalEditorTest.java b/langtools/test/jdk/jshell/ExternalEditorTest.java index cd3d70f442b..21c731866e5 100644 --- a/langtools/test/jdk/jshell/ExternalEditorTest.java +++ b/langtools/test/jdk/jshell/ExternalEditorTest.java @@ -203,7 +203,7 @@ public class ExternalEditorTest extends EditorTestBase { @Test(enabled = false) // TODO 8159229 public void testRemoveTempFile() { - test(new String[]{"-nostartup"}, + test(new String[]{"--no-startup"}, a -> assertCommandCheckOutput(a, "/set editor " + executionScript, assertStartsWith("| Editor set to: " + executionScript)), a -> assertVariable(a, "int", "a", "0", "0"), diff --git a/langtools/test/jdk/jshell/StartOptionTest.java b/langtools/test/jdk/jshell/StartOptionTest.java index e3326597934..5ca48854341 100644 --- a/langtools/test/jdk/jshell/StartOptionTest.java +++ b/langtools/test/jdk/jshell/StartOptionTest.java @@ -22,7 +22,7 @@ */ /* - * @test 8151754 8080883 + * @test 8151754 8080883 8160089 * @summary Testing start-up options. * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -106,53 +106,68 @@ public class StartOptionTest { @Test public void testUsage() throws Exception { - start(s -> { - assertTrue(s.split("\n").length >= 7, "Not enough usage lines: " + s); - assertTrue(s.startsWith("Usage: jshell "), "Unexpect usage start: " + s); - }, null, "-help"); + for (String opt : new String[]{"-h", "--help"}) { + start(s -> { + assertTrue(s.split("\n").length >= 7, "Not enough usage lines: " + s); + assertTrue(s.startsWith("Usage: jshell "), "Unexpect usage start: " + s); + }, null, opt); + } } @Test public void testUnknown() throws Exception { - start(s -> { - assertTrue(s.split("\n").length >= 7, "Not enough usage lines (unknown): " + s); - assertTrue(s.startsWith("Usage: jshell "), "Unexpect usage start (unknown): " + s); - }, s -> assertEquals(s.trim(), "Unknown option: -unknown"), "-unknown"); + start(s -> { }, + s -> assertEquals(s.trim(), "Unknown option: u"), "-unknown"); + start(s -> { }, + s -> assertEquals(s.trim(), "Unknown option: unknown"), "--unknown"); } public void testStartup() throws Exception { Compiler compiler = new Compiler(); Path p = compiler.getPath("file.txt"); compiler.writeToFile(p); - start("", "'-startup' requires a filename argument.", "-startup"); - start("", "Only one -startup or -nostartup option may be used.", "-startup", p.toString(), "-startup", p.toString()); - start("", "Only one -startup or -nostartup option may be used.", "-nostartup", "-startup", p.toString()); - start("", "Only one -startup or -nostartup option may be used.", "-startup", p.toString(), "-nostartup"); - start("", "Only one -startup or -nostartup option may be used.", "-nostartup", "-nostartup"); - start("", "Only one -startup or -nostartup option may be used.", "-nostartup", "-startup"); + start("", "Argument to startup missing.", "--startup"); + start("", "Only one --startup or --no-startup option may be used.", "--startup", p.toString(), "--startup", p.toString()); + start("", "Only one --startup or --no-startup option may be used.", "--no-startup", "--startup", p.toString()); + start("", "Only one --startup or --no-startup option may be used.", "--startup", p.toString(), "--no-startup"); + start("", "Argument to startup missing.", "--no-startup", "--startup"); } public void testStartupUnknown() throws Exception { - start("", "File 'UNKNOWN' for '-startup' is not found.", "-startup", "UNKNOWN"); + start("", "File 'UNKNOWN' for '--startup' is not found.", "--startup", "UNKNOWN"); } @Test public void testClasspath() throws Exception { - for (String cp : new String[] {"-cp", "-classpath"}) { - start("", "Conflicting -classpath option.", cp, ".", "-classpath", "."); - start("", "Argument to -classpath missing.", cp); + for (String cp : new String[] {"--class-path"}) { + start("", "Only one --class-path option may be used.", cp, ".", "--class-path", "."); + start("", "Argument to class-path missing.", cp); } } + @Test + public void testFeedbackOptionConflict() throws Exception { + start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", + "--feedback", "concise", "--feedback", "verbose"); + start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "--feedback", "concise", "-s"); + start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "--feedback", "verbose", "-q"); + start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "--feedback", "concise", "-v"); + start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-v", "--feedback", "concise"); + start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-q", "-v"); + start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-s", "-v"); + start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-v", "-q"); + start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-q", "-s"); + } + @Test public void testNegFeedbackOption() throws Exception { - start("", "Argument to -feedback missing. Mode required.", "-feedback"); - start("", "Does not match any current feedback mode: blorp -- -feedback blorp", "-feedback", "blorp"); + start("", "Argument to feedback missing.", "--feedback"); + start("", "Does not match any current feedback mode: blorp -- --feedback blorp", "--feedback", "blorp"); } @Test public void testVersion() throws Exception { - start(s -> assertTrue(s.startsWith("jshell"), "unexpected version: " + s), null, "-version"); + start(s -> assertTrue(s.startsWith("jshell"), "unexpected version: " + s), null, "--version"); } @AfterMethod diff --git a/langtools/test/jdk/jshell/ToolBasicTest.java b/langtools/test/jdk/jshell/ToolBasicTest.java index 0c5bf1dfab9..7ccf529fb2d 100644 --- a/langtools/test/jdk/jshell/ToolBasicTest.java +++ b/langtools/test/jdk/jshell/ToolBasicTest.java @@ -97,7 +97,7 @@ public class ToolBasicTest extends ReplToolTesting { public void testInterrupt() { ReplTest interrupt = (a) -> assertCommand(a, "\u0003", ""); for (String s : new String[] { "", "\u0003" }) { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, (a) -> assertCommand(a, "int a = 2 +" + s, ""), interrupt, (a) -> assertCommand(a, "int a\u0003", ""), @@ -190,7 +190,7 @@ public class ToolBasicTest extends ReplToolTesting { } public void testRerun() { - test(false, new String[] {"-nostartup"}, + test(false, new String[] {"--no-startup"}, (a) -> assertCommand(a, "/0", "| No such command or snippet id: /0\n| Type /help for help."), (a) -> assertCommand(a, "/5", "| No such command or snippet id: /5\n| Type /help for help.") ); @@ -226,7 +226,7 @@ public class ToolBasicTest extends ReplToolTesting { tests.add((a) -> assertCommandCheckOutput(a, "/-" + (2 * finalI + 1), check)); } tests.add((a) -> assertCommandCheckOutput(a, "/!", assertStartsWith("int a = 0;"))); - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, tests.toArray(new ReplTest[tests.size()])); } @@ -243,7 +243,7 @@ public class ToolBasicTest extends ReplToolTesting { Path startup = compiler.getPath("StartupFileOption/startup.txt"); compiler.writeToFile(startup, "int assertionCount = 0;\n" + // id: s1 "void add(int n) { assertionCount += n; }"); - test(new String[]{"-startup", startup.toString()}, + test(new String[]{"--startup", startup.toString()}, (a) -> assertCommand(a, "add(1)", ""), // id: 1 (a) -> assertCommandCheckOutput(a, "add(ONE)", s -> assertEquals(s.split("\n")[0], "| Error:")), // id: e1 (a) -> assertVariable(a, "int", "ONE", "1", "1"), @@ -252,7 +252,7 @@ public class ToolBasicTest extends ReplToolTesting { assertRerun.apply("/s1").apply("int assertionCount = 0;", 0), assertVariables ); - test(false, new String[] {"-nostartup"}, + test(false, new String[] {"--no-startup"}, (a) -> assertCommand(a, "/s1", "| No such command or snippet id: /s1\n| Type /help for help."), (a) -> assertCommand(a, "/1", "| No such command or snippet id: /1\n| Type /help for help."), (a) -> assertCommand(a, "/e1", "| No such command or snippet id: /e1\n| Type /help for help.") @@ -268,10 +268,7 @@ public class ToolBasicTest extends ReplToolTesting { (a) -> assertCommand(a, "/classpath " + classpath, String.format("| Path '%s' added to classpath", classpath)), (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") ); - test(new String[] { "-cp", classpath.toString() }, - (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") - ); - test(new String[] { "-classpath", classpath.toString() }, + test(new String[] { "--class-path", classpath.toString() }, (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") ); } @@ -287,10 +284,7 @@ public class ToolBasicTest extends ReplToolTesting { (a) -> assertCommand(a, "/classpath " + jarPath, String.format("| Path '%s' added to classpath", jarPath)), (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") ); - test(new String[] { "-cp", jarPath.toString() }, - (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") - ); - test(new String[] { "-classpath", jarPath.toString() }, + test(new String[] { "--class-path", jarPath.toString() }, (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") ); } @@ -300,10 +294,10 @@ public class ToolBasicTest extends ReplToolTesting { Compiler compiler = new Compiler(); Path startup = compiler.getPath("StartupFileOption/startup.txt"); compiler.writeToFile(startup, "class A { public String toString() { return \"A\"; } }"); - test(new String[]{"-startup", startup.toString()}, + test(new String[]{"--startup", startup.toString()}, (a) -> evaluateExpression(a, "A", "new A()", "A") ); - test(new String[]{"-nostartup"}, + test(new String[]{"--no-startup"}, (a) -> assertCommandCheckOutput(a, "printf(\"\")", assertStartsWith("| Error:\n| cannot find symbol")) ); test( @@ -550,7 +544,7 @@ public class ToolBasicTest extends ReplToolTesting { } public void testHistoryReference() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, a -> assertCommand(a, "System.err.println(1)", "", "", null, "", "1\n"), a -> assertCommand(a, "System.err.println(2)", "", "", null, "", "2\n"), a -> assertCommand(a, "/-2", "System.err.println(1)", "", null, "", "1\n"), diff --git a/langtools/test/jdk/jshell/ToolCommandOptionTest.java b/langtools/test/jdk/jshell/ToolCommandOptionTest.java index 030d016a89e..96efdb01368 100644 --- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java +++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8157395 8157393 8157517 + * @bug 8157395 8157393 8157517 8158738 * @summary Tests of jshell comand options, and undoing operations * @modules jdk.jshell/jdk.internal.jshell.tool * @build ToolCommandOptionTest ReplToolTesting @@ -88,7 +88,7 @@ public class ToolCommandOptionTest extends ReplToolTesting { } public void dropTest() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, (a) -> assertCommand(a, "int x = 5;", "x ==> 5"), (a) -> assertCommand(a, "x", @@ -148,6 +148,8 @@ public class ToolCommandOptionTest extends ReplToolTesting { "| Unknown option: -furball -mattress -- /retain editor -furball -mattress"), (a) -> assertCommand(a, "/retain editor -default prog", "| Specify -default option or program, not both -- /retain editor -default prog"), + (a) -> assertCommand(a, "/retain editor -default -wait", + "| -wait applies to external editors, cannot be used with -default"), (a) -> assertCommand(a, "/retain editor prog", "| Editor set to: prog"), (a) -> assertCommand(a, "/retain editor prog -default", diff --git a/langtools/test/jdk/jshell/ToolLocaleMessageTest.java b/langtools/test/jdk/jshell/ToolLocaleMessageTest.java index b2125d7c3dc..d52c4ed9633 100644 --- a/langtools/test/jdk/jshell/ToolLocaleMessageTest.java +++ b/langtools/test/jdk/jshell/ToolLocaleMessageTest.java @@ -44,7 +44,7 @@ import static org.testng.Assert.assertTrue; public class ToolLocaleMessageTest extends ReplToolTesting { void testLocale(ReplTest... tests) { - test(Locale.getDefault(), false, new String[]{"-nostartup"}, "", tests); + test(Locale.getDefault(), false, new String[]{"--no-startup"}, "", tests); } void assertCommandOK(boolean after, String cmd, String... contains) { diff --git a/langtools/test/jdk/jshell/ToolReloadTest.java b/langtools/test/jdk/jshell/ToolReloadTest.java index 0faf3e668dc..ed4c15b013b 100644 --- a/langtools/test/jdk/jshell/ToolReloadTest.java +++ b/langtools/test/jdk/jshell/ToolReloadTest.java @@ -90,7 +90,7 @@ public class ToolReloadTest extends ReplToolTesting { } public void testReloadDrop() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, a -> assertVariable(a, "int", "a"), a -> dropVariable(a, "/dr 1", "int a = 0", "| dropped variable a"), a -> assertMethod(a, "int b() { return 0; }", "()I", "b"), @@ -113,7 +113,7 @@ public class ToolReloadTest extends ReplToolTesting { } public void testReloadQuiet() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, a -> assertVariable(a, "int", "a"), a -> dropVariable(a, "/dr 1", "int a = 0", "| dropped variable a"), a -> assertMethod(a, "int b() { return 0; }", "()I", "b"), @@ -130,7 +130,7 @@ public class ToolReloadTest extends ReplToolTesting { } public void testReloadRepeat() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, (a) -> assertVariable(a, "int", "c", "7", "7"), (a) -> assertCommand(a, "++c", null), (a) -> assertCommand(a, "/!", null), @@ -150,7 +150,7 @@ public class ToolReloadTest extends ReplToolTesting { } public void testReloadIgnore() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, (a) -> assertCommand(a, "(-)", null), (a) -> assertCommand(a, "/list", null), (a) -> assertCommand(a, "/history", null), @@ -201,13 +201,13 @@ public class ToolReloadTest extends ReplToolTesting { } public void testReloadExitRestore() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, (a) -> assertVariable(a, "int", "x", "5", "5"), (a) -> assertMethod(a, "int m(int z) { return z * z; }", "(int)int", "m"), (a) -> evaluateExpression(a, "int", "m(x)", "25") ); - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, (a) -> assertCommand(a, "/reload -restore", "| Restarting and restoring from previous state.\n" + "-: int x = 5;\n" + diff --git a/langtools/test/jdk/jshell/ToolSimpleTest.java b/langtools/test/jdk/jshell/ToolSimpleTest.java index 96f9e69eef8..1b0f77de77e 100644 --- a/langtools/test/jdk/jshell/ToolSimpleTest.java +++ b/langtools/test/jdk/jshell/ToolSimpleTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 + * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 * @summary Simple jshell tool tests * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -157,7 +157,6 @@ public class ToolSimpleTest extends ReplToolTesting { ); } - @Test(enabled = false) // TODO 8153897 public void defineUnresolvedVar() { test( (a) -> assertCommand(a, "undefined x", @@ -209,7 +208,7 @@ public class ToolSimpleTest extends ReplToolTesting { } public void testDrop() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, a -> assertVariable(a, "int", "a"), a -> dropVariable(a, "/drop 1", "int a = 0", "| dropped variable a"), a -> assertMethod(a, "int b() { return 0; }", "()I", "b"), @@ -223,7 +222,7 @@ public class ToolSimpleTest extends ReplToolTesting { a -> assertCommandCheckOutput(a, "/types", assertClasses()), a -> assertCommandCheckOutput(a, "/imports", assertImports()) ); - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, a -> assertVariable(a, "int", "a"), a -> dropVariable(a, "/drop a", "int a = 0", "| dropped variable a"), a -> assertMethod(a, "int b() { return 0; }", "()I", "b"), @@ -238,7 +237,7 @@ public class ToolSimpleTest extends ReplToolTesting { } public void testDropNegative() { - test(false, new String[]{"-nostartup"}, + test(false, new String[]{"--no-startup"}, a -> assertCommandOutputStartsWith(a, "/drop 0", "| No such snippet: 0"), a -> assertCommandOutputStartsWith(a, "/drop a", "| No such snippet: a"), a -> assertCommandCheckOutput(a, "/drop", @@ -462,20 +461,20 @@ public class ToolSimpleTest extends ReplToolTesting { } public void testOptionQ() { - test(new String[]{"-q", "-nostartup"}, + test(new String[]{"-q", "--no-startup"}, (a) -> assertCommand(a, "1+1", "$1 ==> 2"), (a) -> assertCommand(a, "int x = 5", "") ); } - public void testOptionQq() { - test(new String[]{"-qq", "-nostartup"}, + public void testOptionS() { + test(new String[]{"-s", "--no-startup"}, (a) -> assertCommand(a, "1+1", "") ); } public void testOptionV() { - test(new String[]{"-v", "-nostartup"}, + test(new String[]{"-v", "--no-startup"}, (a) -> assertCommand(a, "1+1", "$1 ==> 2\n" + "| created scratch variable $1 : int") @@ -483,14 +482,36 @@ public class ToolSimpleTest extends ReplToolTesting { } public void testOptionFeedback() { - test(new String[]{"-feedback", "concise", "-nostartup"}, + test(new String[]{"--feedback", "concise", "--no-startup"}, (a) -> assertCommand(a, "1+1", "$1 ==> 2"), (a) -> assertCommand(a, "int x = 5", "") ); } + public void testCompoundOptions() { + Consumer confirmNoStartup = s -> { + assertEquals(0, Stream.of(s.split("\n")) + .filter(l -> !l.isEmpty()) + .count(), "Expected no lines: " + s); + }; + test(new String[]{"-nq"}, + (a) -> assertCommandCheckOutput(a, "/list -all", confirmNoStartup), + (a) -> assertCommand(a, "1+1", "$1 ==> 2"), + (a) -> assertCommand(a, "int x = 5", "") + ); + test(new String[]{"-qn"}, + (a) -> assertCommandCheckOutput(a, "/list -all", confirmNoStartup), + (a) -> assertCommand(a, "1+1", "$1 ==> 2"), + (a) -> assertCommand(a, "int x = 5", "") + ); + test(new String[]{"-ns"}, + (a) -> assertCommandCheckOutput(a, "/list -all", confirmNoStartup), + (a) -> assertCommand(a, "1+1", "") + ); + } + public void testOptionR() { - test(new String[]{"-R-Dthe.sound=blorp", "-nostartup"}, + test(new String[]{"-R-Dthe.sound=blorp", "--no-startup"}, (a) -> assertCommand(a, "System.getProperty(\"the.sound\")", "$1 ==> \"blorp\"") ); diff --git a/langtools/test/tools/javac/InnerClassesAttribute/Test.java b/langtools/test/tools/javac/InnerClassesAttribute/Test.java index f2357ada27c..69bbaa35d50 100644 --- a/langtools/test/tools/javac/InnerClassesAttribute/Test.java +++ b/langtools/test/tools/javac/InnerClassesAttribute/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/langtools/test/tools/javac/T8047338/FilterNonMembersToObtainFunctionDescriptorTest.java b/langtools/test/tools/javac/T8047338/FilterNonMembersToObtainFunctionDescriptorTest.java new file mode 100644 index 00000000000..501d01b4561 --- /dev/null +++ b/langtools/test/tools/javac/T8047338/FilterNonMembersToObtainFunctionDescriptorTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8047338 + * @summary javac is not correctly filtering non-members methods to obtain the function descriptor + * @compile FilterNonMembersToObtainFunctionDescriptorTest.java + */ + +public class FilterNonMembersToObtainFunctionDescriptorTest { + V fails(CallableFail callable) throws E { + return null; + } + + V failsSub(CallableFailSub callable) throws E { + return null; + } + + void m() throws Exception { + fails((String s) -> 2); + failsSub((String s) -> 2); + } + + interface Callable { + V callFail(String s) throws Exception; + } + + interface CallableFail extends Callable { + @Override + V callFail(String s) throws E; + } + + interface CallableFailSub extends CallableFail {} +} diff --git a/langtools/test/tools/javac/VersionOpt.java b/langtools/test/tools/javac/VersionOpt.java index 0d92962c07d..fe8224e946b 100644 --- a/langtools/test/tools/javac/VersionOpt.java +++ b/langtools/test/tools/javac/VersionOpt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ public class VersionOpt { // Test functions by comparing the version string from javac against // a "golden" version generated automatically from the underlying JVM. // As such, it is only effective in testing the "standard" compiler, - // and not any development version being tested via -Xpatch. + // and not any development version being tested via --patch-modules. // Check the version of the compiler being used, and let the test pass // automatically if is is a development version. Class javacClass = com.sun.tools.javac.Main.class; diff --git a/langtools/test/tools/javac/diags/examples/DirPathElementNotDirectory/modulesourcepath b/langtools/test/tools/javac/diags/examples/DirPathElementNotDirectory/modulesourcepath index 42c5a0cf3a1..35cffd6ae95 100644 --- a/langtools/test/tools/javac/diags/examples/DirPathElementNotDirectory/modulesourcepath +++ b/langtools/test/tools/javac/diags/examples/DirPathElementNotDirectory/modulesourcepath @@ -21,5 +21,5 @@ * questions. */ -// a file to be passed in where a directory is expected (-modulesourcepath option) +// a file to be passed in where a directory is expected (--module-source-path option) // to trigger an error deliberately. diff --git a/langtools/test/tools/javac/diags/examples/ModuleNotFoundInModuleSourcePath/ModuleNotFoundInModuleSourcePath.java b/langtools/test/tools/javac/diags/examples/ModuleNotFoundInModuleSourcePath/ModuleNotFoundInModuleSourcePath.java index 71d1df029d1..9c812ca11f7 100644 --- a/langtools/test/tools/javac/diags/examples/ModuleNotFoundInModuleSourcePath/ModuleNotFoundInModuleSourcePath.java +++ b/langtools/test/tools/javac/diags/examples/ModuleNotFoundInModuleSourcePath/ModuleNotFoundInModuleSourcePath.java @@ -22,6 +22,6 @@ */ // key: compiler.err.module.not.found.in.module.source.path -// options: -m m1 -modulesourcepath src +// options: -m m1 --module-source-path src class ModuleNotFoundInModuleSourcePath {} diff --git a/langtools/test/tools/javac/diags/examples/XModuleWithModulePath/XModuleWithModulePath.java b/langtools/test/tools/javac/diags/examples/XModuleWithModulePath/XModuleWithModulePath.java index a378792e520..eaffab89d3e 100644 --- a/langtools/test/tools/javac/diags/examples/XModuleWithModulePath/XModuleWithModulePath.java +++ b/langtools/test/tools/javac/diags/examples/XModuleWithModulePath/XModuleWithModulePath.java @@ -22,6 +22,6 @@ */ // key: compiler.err.xmodule.no.module.sourcepath -// options: -Xmodule:java.compiler -modulesourcepath src +// options: -Xmodule:java.compiler --module-source-path src class XModuleWithModulePath {} diff --git a/langtools/test/tools/javac/file/LimitedImage.java b/langtools/test/tools/javac/file/LimitedImage.java index a04169eaf6e..44bc82e8964 100644 --- a/langtools/test/tools/javac/file/LimitedImage.java +++ b/langtools/test/tools/javac/file/LimitedImage.java @@ -28,7 +28,7 @@ * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * @run main/othervm -limitmods jdk.compiler LimitedImage + * @run main/othervm --limit-modules jdk.compiler LimitedImage */ import java.io.IOException; @@ -133,4 +133,4 @@ public class LimitedImage { } } -} \ No newline at end of file +} diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocletAbortException.java b/langtools/test/tools/javac/generics/inference/8164399/T8164399.java similarity index 64% rename from langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocletAbortException.java rename to langtools/test/tools/javac/generics/inference/8164399/T8164399.java index 7cf32a85d6b..a069edc2516 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocletAbortException.java +++ b/langtools/test/tools/javac/generics/inference/8164399/T8164399.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,22 +23,27 @@ * questions. */ -package jdk.javadoc.internal.doclets.toolkit.util; - -/** - *

    This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own risk. - * This code and its internal interfaces are subject to change or - * deletion without notice. +/* + * @test + * @bug 8164399 + * @summary inference of thrown variable does not work correctly + * @compile T8164399.java */ -public class DocletAbortException extends RuntimeException { - private static final long serialVersionUID = -9131058909576418984L; - public DocletAbortException(String message) { - super(message); +abstract class T8164399 { + + interface ThrowableRunnable { + void compute() throws E; } - public DocletAbortException(Throwable cause) { - super(cause); + public abstract < E extends Exception> void computeException(ThrowableRunnable process) throws E; + + + public static T compute(ThrowableRunnable action) throws E { + return null; + } + + { + computeException(() -> compute(() -> {})); } } diff --git a/langtools/test/tools/javac/generics/inference/8164399/T8164399b.java b/langtools/test/tools/javac/generics/inference/8164399/T8164399b.java new file mode 100644 index 00000000000..ea2a8d1fb00 --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/8164399/T8164399b.java @@ -0,0 +1,21 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8164399 + * @summary inference of thrown variable does not work correctly + * @compile/fail/ref=T8164399b.out -XDrawDiagnostics T8164399b.java + */ +class T8164399b { + void m(Class arg) throws T {} + void g() throws T {} + + void test() { + m(RuntimeException.class); // ok + m(Exception.class); // error + m(Throwable.class); // ok + m(java.io.Serializable.class); // error + m(Object.class); // error + m(Runnable.class); // error + T8164399b x = null; + x.g(); // expected: ok; actual: error + } +} diff --git a/langtools/test/tools/javac/generics/inference/8164399/T8164399b.out b/langtools/test/tools/javac/generics/inference/8164399/T8164399b.out new file mode 100644 index 00000000000..6091fbb27f6 --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/8164399/T8164399b.out @@ -0,0 +1,2 @@ +T8164399b.java:17:10: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable&java.lang.Runnable +1 error diff --git a/langtools/test/tools/javac/modules/GraphsTest.java b/langtools/test/tools/javac/modules/GraphsTest.java index 8cfce2ad0c9..26118fff60b 100644 --- a/langtools/test/tools/javac/modules/GraphsTest.java +++ b/langtools/test/tools/javac/modules/GraphsTest.java @@ -194,7 +194,7 @@ public class GraphsTest extends ModuleTestBase { .write(modSrc); String log = new JavacTask(tb) .options("-XDrawDiagnostics", - "-modulesourcepath", modSrc.toString()) + "--module-source-path", modSrc.toString()) .outdir(Files.createDirectories(base.resolve("negative"))) .files(findJavaFiles(modSrc)) .run(Task.Expect.FAIL) diff --git a/langtools/test/tools/javac/modules/ModuleSourcePathTest.java b/langtools/test/tools/javac/modules/ModuleSourcePathTest.java index 8202ae52b7a..07deb3b9c17 100644 --- a/langtools/test/tools/javac/modules/ModuleSourcePathTest.java +++ b/langtools/test/tools/javac/modules/ModuleSourcePathTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary tests for -modulesourcepath + * @summary tests for --module-source-path * @library /tools/lib * @modules * jdk.compiler/com.sun.tools.javac.api diff --git a/langtools/test/tools/javac/modules/NPEEmptyFileTest.java b/langtools/test/tools/javac/modules/NPEEmptyFileTest.java index a1ebebfec54..7260160143e 100644 --- a/langtools/test/tools/javac/modules/NPEEmptyFileTest.java +++ b/langtools/test/tools/javac/modules/NPEEmptyFileTest.java @@ -23,7 +23,7 @@ /** * @test - * @summary NPE while compiling empty javafile with -modulesourcepath option + * @summary NPE while compiling empty source file with --module-source-path option * @library /tools/lib * @modules * jdk.compiler/com.sun.tools.javac.api diff --git a/langtools/test/tools/javac/modules/SingleModuleModeTest.java b/langtools/test/tools/javac/modules/SingleModuleModeTest.java index e453d3bf8e4..17aa42c93f1 100644 --- a/langtools/test/tools/javac/modules/SingleModuleModeTest.java +++ b/langtools/test/tools/javac/modules/SingleModuleModeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/langtools/test/tools/javac/modules/T8161501/EmptyClass.java b/langtools/test/tools/javac/modules/T8161501/EmptyClass.java new file mode 100644 index 00000000000..3d9a88eff43 --- /dev/null +++ b/langtools/test/tools/javac/modules/T8161501/EmptyClass.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +class EmptyClass {} diff --git a/langtools/test/tools/javac/modules/T8161501/UnnamedModuleUnnamedPackageTest.java b/langtools/test/tools/javac/modules/T8161501/UnnamedModuleUnnamedPackageTest.java new file mode 100644 index 00000000000..a8533698249 --- /dev/null +++ b/langtools/test/tools/javac/modules/T8161501/UnnamedModuleUnnamedPackageTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8161501 + * @summary JSR269 jigsaw update: javax.lang.model.element.ModuleElement.getEnclosedElements() on unnamed module with unnamed package + * @compile UnnamedModuleUnnamedPackageTest.java + * @compile -processor UnnamedModuleUnnamedPackageTest UnnamedModuleUnnamedPackageTest.java EmptyClass.java + */ + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.*; + +import java.util.*; +import java.util.stream.Collectors; + +@SupportedAnnotationTypes("*") +public class UnnamedModuleUnnamedPackageTest extends AbstractProcessor { + static final Set expected = new HashSet<>(Arrays.asList("unnamed package", "pkg1")); + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + for (Element e: roundEnv.getRootElements()) { + Element m = e.getEnclosingElement(); + while (!(m instanceof ModuleElement)) { + m = m.getEnclosingElement(); + } + Set found = m.getEnclosedElements().stream() + .map(p -> ((PackageElement)p).isUnnamed() ? + "unnamed package" : + ((PackageElement)p).getQualifiedName().toString()) + .collect(Collectors.toSet()); + if (!Objects.equals(expected, found)) { + System.err.println("expected: " + expected); + System.err.println("found: " + found); + throw new AssertionError("unexpected packages found"); + } + } + return false; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } +} diff --git a/langtools/test/tools/javac/redefineObject/Object1-test.java b/langtools/test/tools/javac/redefineObject/Object1-test.java index 86827f5ddae..a654ecee5d5 100644 --- a/langtools/test/tools/javac/redefineObject/Object1-test.java +++ b/langtools/test/tools/javac/redefineObject/Object1-test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997,2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/langtools/test/tools/javac/redefineObject/Object2-test.java b/langtools/test/tools/javac/redefineObject/Object2-test.java index 34a40554c35..59eb4b670df 100644 --- a/langtools/test/tools/javac/redefineObject/Object2-test.java +++ b/langtools/test/tools/javac/redefineObject/Object2-test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997,2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleAnnotation.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleAnnotation.java new file mode 100644 index 00000000000..c0cf8e9da2c --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleAnnotation.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.members; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +@Retention(value=RetentionPolicy.RUNTIME) +@Target({TYPE, METHOD, FIELD}) +public @interface ExampleAnnotation { + String file(); + @Deprecated String name() default ""; +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleClass.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleClass.java new file mode 100644 index 00000000000..0205afefcfb --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleClass.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.members; + +public class ExampleClass { + public ExampleClass() { } + + @Deprecated + public ExampleClass(boolean deprecatedConstructor) { } + + @Deprecated + public void method1() { } + + @Deprecated + public void method2() { } + + @Deprecated + public int field1 = 0; + + @Deprecated + public int field2 = 0; + + @Deprecated + public static void staticmethod1() { } + + @Deprecated + public static int staticfield3 = 0; +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleElements.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleElements.java new file mode 100644 index 00000000000..f7fb1c6463d --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleElements.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.members; + +public class ExampleElements { + @Deprecated + Object emptyFalse; + + @Deprecated(since="xyzzy") + Object sinceFalse; + + @Deprecated(forRemoval=true) + Object emptyTrue; + + @Deprecated(since="plugh", forRemoval=true) + Object sinceTrue; + + @Deprecated(since="123,456") + Object sinceWithComma; + + @Deprecated(since="7.9 \"pre-beta\" snapshot") + Object sinceWithQuote; +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleEnum.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleEnum.java new file mode 100644 index 00000000000..d0f7541817f --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleEnum.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.members; + +public enum ExampleEnum { + ONE, + TWO { + @Override + public void deprMethod1() { } + @Override @Deprecated + public void deprMethod2() { } + }, + @Deprecated THREE, + FOUR, + @Deprecated FIVE; + + @Deprecated + public void deprMethod1() { } + + public void deprMethod2() { } +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleInterface.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleInterface.java new file mode 100644 index 00000000000..972bb470255 --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleInterface.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.members; + +public interface ExampleInterface { + @Deprecated + static final int DEP_FIELD1 = 1; + + @Deprecated + static final int DEP_FIELD2 = 2; + + @Deprecated + void interfaceMethod1(); + + @Deprecated + void interfaceMethod2(); + + @Deprecated + default void defaultMethod() { } + + @Deprecated + static void staticmethod2() { } +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleSubclass.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleSubclass.java new file mode 100644 index 00000000000..4cfdaa07f32 --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/members/ExampleSubclass.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.members; + +public abstract class ExampleSubclass extends ExampleClass implements ExampleInterface { + @Override + public void method1() { } + + // hides ExampleClass.field1 + public Object field1 = null; + + @Override + public void interfaceMethod2() { + } + + // hides ExampleInterface.DEP_FIELD1 + public Object DEP_FIELD1 = null; +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedAnnotation.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedAnnotation.java new file mode 100644 index 00000000000..b11206caa56 --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedAnnotation.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.types; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +@Retention(value=RetentionPolicy.RUNTIME) +@Target({TYPE, METHOD, FIELD}) +@Deprecated +public @interface DeprecatedAnnotation { + String file() default "x"; + String value() default "y"; +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedClass.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedClass.java new file mode 100644 index 00000000000..3f81060c063 --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedClass.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.types; + +@Deprecated +public class DeprecatedClass { +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedEnum.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedEnum.java new file mode 100644 index 00000000000..b1d05e2759e --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedEnum.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.types; + +@Deprecated +public enum DeprecatedEnum { + FIRST, + SECOND, + THIRD +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedException.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedException.java new file mode 100644 index 00000000000..a956da80ac7 --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedException.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.types; + +@Deprecated +public class DeprecatedException extends RuntimeException { + private static final long serialVersionUID = 0L; +} diff --git a/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedInterface.java b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedInterface.java new file mode 100644 index 00000000000..e54b51b7d4d --- /dev/null +++ b/langtools/test/tools/jdeprscan/cases/jdk/deprcases/types/DeprecatedInterface.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.deprcases.types; + +@Deprecated +public interface DeprecatedInterface { +} diff --git a/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestCSV.java b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestCSV.java new file mode 100644 index 00000000000..c4f6a4ba279 --- /dev/null +++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestCSV.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Basic tests CSV printing and parsing + * @modules jdk.jdeps/com.sun.tools.jdeprscan + * @build TestCSV + * @run testng jdk.jdeprscan.TestCSV + */ + +package jdk.jdeprscan; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.List; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import com.sun.tools.jdeprscan.CSV; +import com.sun.tools.jdeprscan.CSVParseException; + +@Test +public class TestCSV { + static String NL = System.lineSeparator(); + ByteArrayOutputStream baos; + PrintStream out; + + @BeforeMethod + public void setup() throws UnsupportedEncodingException { + baos = new ByteArrayOutputStream(); + out = new PrintStream(baos, true, "UTF-8"); + } + + String result() { + out.flush(); + return new String(baos.toByteArray(), java.nio.charset.StandardCharsets.UTF_8); + } + + /** + * Asserts string equality after checking for and removing a trailing line separator. + * + * @param expected expected result + */ + void checkString(String expected) { + String actual = result(); + assertTrue(actual.endsWith(NL)); + assertEquals(actual.substring(0, actual.length() - NL.length()), expected); + } + + @DataProvider(name = "csvdata") + public Object[][] getCSVData() { + return new Object[][] { + { "", List.of("") }, + { "a", List.of("a") }, + { "a,b", List.of("a", "b") }, + { "a,b,c", List.of("a", "b", "c") }, + { ",a,b", List.of("", "a", "b") }, + { "a,b,", List.of("a", "b", "") }, + { ",a,b,", List.of("", "a", "b", "") }, + { ",a,,b,", List.of("", "a", "", "b", "") }, + { ",", List.of("", "") }, + { ",,", List.of("", "", "") }, + { ",,,", List.of("", "", "", "") }, + { " a , b ", List.of(" a ", " b ") }, + { "a,\",\",b", List.of("a", ",", "b") }, + { "a,\"b\"\"c\",d", List.of("a", "b\"c", "d") }, + { "a,\"b,c\",d", List.of("a", "b,c", "d") }, + + // from https://en.wikipedia.org/wiki/Comma-separated_values + // slightly modified to enable round-tripping + + { "Year,Make,Model,Description,Price", + List.of("Year", "Make", "Model", "Description", "Price") }, + { "1997,Ford,E350,\"ac, abs, moon\",3000.00", + List.of("1997", "Ford", "E350", "ac, abs, moon", "3000.00") }, + { "1999,Chevy,\"Venture \"\"Extended Edition\"\"\",,4900.00", + List.of("1999", "Chevy", "Venture \"Extended Edition\"", "", "4900.00") }, + { "1999,Chevy,\"Venture \"\"Extended Edition, Very Large\"\"\",,5000.00", + List.of("1999", "Chevy", "Venture \"Extended Edition, Very Large\"", "", "5000.00") }, + { "1996,Jeep,Grand Cherokee,\"MUST SELL!\nair, moon roof, loaded\",4799.00", + List.of("1996", "Jeep", "Grand Cherokee", "MUST SELL!\nair, moon roof, loaded", "4799.00") } + }; + } + + @Test(dataProvider = "csvdata") + public void roundTrip(String input, List parsed) { + List actual = CSV.split(input); + assertEquals(actual, parsed); + CSV.write(out, actual.toArray()); + checkString(input); + } + + // won't round-trip + public void testExtraQuote() { + assertEquals(CSV.split("a,\"b\",c"), List.of("a", "b", "c")); + } + + // won't round-trip + public void testEmptyQuote() { + assertEquals(CSV.split("a,\"\",b"), List.of("a", "", "b")); + } + + @Test(expectedExceptions=CSVParseException.class) + public void errorUnexpectedQuote() { + CSV.split("ab\"cd"); + } + + @Test(expectedExceptions=CSVParseException.class) + public void errorCharacterAfterQuote() { + CSV.split("a,\"b\"c,d"); + } + + @Test(expectedExceptions=CSVParseException.class) + public void errorUnclosedQuote() { + CSV.split("a,\"b"); + } +} diff --git a/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestLoad.java b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestLoad.java new file mode 100644 index 00000000000..cc0e3c5eba3 --- /dev/null +++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestLoad.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Test of jdeprscan tool loading and printing to aCSV file. + * @modules jdk.jdeps/com.sun.tools.jdeprscan + * @library ../../../cases + * @build jdk.deprcases.members.* jdk.deprcases.types.* + * @build jdk.jdeprscan.TestLoad + * @run testng jdk.jdeprscan.TestLoad + */ + +package jdk.jdeprscan; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import com.sun.tools.jdeprscan.Main; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertEquals; + + +public class TestLoad { + static final String UTF8 = "UTF-8"; + static final String EXPECTED = "TestLoadExpected.csv"; + + @Test + public void test1() throws IOException, UnsupportedEncodingException { + String testclasses = System.getProperty("test.classes"); + String deprcases = testclasses + "/../../../cases"; + boolean rval; + + System.out.println("test.src = " + System.getProperty("test.src")); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + ByteArrayOutputStream berr = new ByteArrayOutputStream(); + + try (PrintStream prout = new PrintStream(bout, true, UTF8); + PrintStream prerr = new PrintStream(berr, true, UTF8)) { + System.out.println("Calling JDeprScan --Xprint-csv --Xload-dir " + deprcases); + rval = Main.call(prout, prerr, "--Xprint-csv", "--Xload-dir", deprcases); + System.out.println("JDeprScan returns " + rval); + } + + System.out.println("----- stdout"); + new ByteArrayInputStream(bout.toByteArray()).transferTo(System.out); + System.out.println("----- end stdout"); + System.out.println("----- stderr"); + new ByteArrayInputStream(berr.toByteArray()).transferTo(System.out); + System.out.println("----- end stderr"); + + List actualList; + try (ByteArrayInputStream bais = new ByteArrayInputStream(bout.toByteArray()); + InputStreamReader isr = new InputStreamReader(bais); + BufferedReader br = new BufferedReader(isr)) { + actualList = br.lines().collect(Collectors.toList()); + } + + Path expfile = Paths.get(System.getProperty("test.src"), EXPECTED); + List expectedList = Files.readAllLines(expfile); + + Set actual = new HashSet<>(actualList.subList(1, actualList.size())); + Set expected = new HashSet<>(expectedList.subList(1, expectedList.size())); + + Set diff1 = new HashSet<>(actual); + diff1.removeAll(expected); + Set diff2 = new HashSet<>(expected); + diff2.removeAll(actual); + if (diff1.size() > 0) { + System.out.println("Extra lines in output:"); + diff1.forEach(System.out::println); + } + + if (diff2.size() > 0) { + System.out.println("Lines missing from output:"); + diff2.forEach(System.out::println); + } + + assertTrue(rval); + assertEquals(berr.toByteArray().length, 0); + assertEquals(actual.size(), actualList.size() - 1); + assertEquals(diff1.size(), 0); + assertEquals(diff2.size(), 0); + } +} diff --git a/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestLoadExpected.csv b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestLoadExpected.csv new file mode 100644 index 00000000000..dd58eacd90c --- /dev/null +++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestLoadExpected.csv @@ -0,0 +1,30 @@ +#jdepr 1 +METHOD,jdk/deprcases/members/ExampleAnnotation,name()Ljava/lang/String;,,false +FIELD,jdk/deprcases/members/ExampleClass,field1,,false +FIELD,jdk/deprcases/members/ExampleClass,field2,,false +FIELD,jdk/deprcases/members/ExampleClass,staticfield3,,false +CONSTRUCTOR,jdk/deprcases/members/ExampleClass,(Z)V,,false +METHOD,jdk/deprcases/members/ExampleClass,method1()V,,false +METHOD,jdk/deprcases/members/ExampleClass,method2()V,,false +METHOD,jdk/deprcases/members/ExampleClass,staticmethod1()V,,false +METHOD,jdk/deprcases/members/ExampleEnum$1,deprMethod2()V,,false +ENUM_CONSTANT,jdk/deprcases/members/ExampleEnum,THREE,,false +ENUM_CONSTANT,jdk/deprcases/members/ExampleEnum,FIVE,,false +METHOD,jdk/deprcases/members/ExampleEnum,deprMethod1()V,,false +FIELD,jdk/deprcases/members/ExampleInterface,DEP_FIELD1,,false +FIELD,jdk/deprcases/members/ExampleInterface,DEP_FIELD2,,false +METHOD,jdk/deprcases/members/ExampleInterface,interfaceMethod1()V,,false +METHOD,jdk/deprcases/members/ExampleInterface,interfaceMethod2()V,,false +METHOD,jdk/deprcases/members/ExampleInterface,defaultMethod()V,,false +METHOD,jdk/deprcases/members/ExampleInterface,staticmethod2()V,,false +ANNOTATION_TYPE,jdk/deprcases/types/DeprecatedAnnotation,,,false +CLASS,jdk/deprcases/types/DeprecatedClass,,,false +ENUM,jdk/deprcases/types/DeprecatedEnum,,,false +CLASS,jdk/deprcases/types/DeprecatedException,,,false +INTERFACE,jdk/deprcases/types/DeprecatedInterface,,,false +FIELD,jdk/deprcases/members/ExampleElements,emptyFalse,,false +FIELD,jdk/deprcases/members/ExampleElements,sinceFalse,xyzzy,false +FIELD,jdk/deprcases/members/ExampleElements,emptyTrue,,true +FIELD,jdk/deprcases/members/ExampleElements,sinceTrue,plugh,true +FIELD,jdk/deprcases/members/ExampleElements,sinceWithComma,"123,456",false +FIELD,jdk/deprcases/members/ExampleElements,sinceWithQuote,"7.9 ""pre-beta"" snapshot",false diff --git a/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestMethodSig.java b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestMethodSig.java new file mode 100644 index 00000000000..e44b8b2e133 --- /dev/null +++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestMethodSig.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Simple tests for method signature parsing + * @modules jdk.jdeps/com.sun.tools.jdeprscan.scan + * @build TestMethodSig + * @run testng jdk.jdeprscan.TestMethodSig + */ + +package jdk.jdeprscan; + +import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; +import static com.sun.tools.jdeprscan.scan.MethodSig.fromDesc; + +public class TestMethodSig { + @Test + public void testSimple() { + assertEquals(fromDesc("(Ljava/rmi/RMISecurityManager;)Ljava/lang/Object;").toString(), + "parameters 0=Ljava/rmi/RMISecurityManager; return Ljava/lang/Object;"); + } + + @Test + public void testMultParamVoidReturn() { + assertEquals(fromDesc("([[IZLjava/lang/String;B[J)V").toString(), + "parameters 0=[[I 1=Z 2=Ljava/lang/String; 3=B 4=[J return V"); + } + + @Test + public void testNoParams() { + assertEquals(fromDesc("()J").toString(), + "parameters none return J"); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testMissingReturnType() { + fromDesc("(ISJZ)"); + } +} diff --git a/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestScan.java b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestScan.java new file mode 100644 index 00000000000..bf18cd96122 --- /dev/null +++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestScan.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Basic test of jdeprscan's scanning phase. + * @modules jdk.jdeps/com.sun.tools.jdeprscan + * @library ../../../cases + * @library ../../../usage + * @build jdk.deprcases.members.* jdk.deprcases.types.* + * @build jdk.deprusage.* + * @build jdk.jdeprscan.TestScan + * @run testng jdk.jdeprscan.TestScan + */ + +package jdk.jdeprscan; + +import com.sun.tools.jdeprscan.Main; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import org.testng.Assert; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertTrue; + + +public class TestScan { + Set loadExpected() throws IOException { + Path expFile = Paths.get(System.getProperty("test.src"), "TestScanExpected.txt"); + return new HashSet<>(Files.readAllLines(expFile, StandardCharsets.UTF_8)); + } + + @Test + public void testScanAgainstReferenceFile() throws IOException { + String testclasses = System.getProperty("test.classes"); + String deprcases = testclasses + "/../../../cases"; + String deprusage = testclasses + "/../../../usage"; + + Set expected = loadExpected(); + System.out.println("expected = " + expected); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (PrintStream out = new PrintStream(baos, false, "UTF-8")) { + boolean r = Main.call(out, System.err, + "-cp", deprcases, "--Xload-dir", deprcases, deprusage); + assertTrue(r); + } + byte[] bytes = baos.toByteArray(); + + System.out.println("--- output ---"); + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + bais.transferTo(System.out); + System.out.println("--- end output ---"); + + Set actual = + new BufferedReader( + new InputStreamReader( + new ByteArrayInputStream(bytes), StandardCharsets.UTF_8)) + .lines() + .map(line -> line.split(" +")) + .map(array -> array[1]) + .collect(Collectors.toSet()); + System.out.println("actual = " + actual); + + Set diff1 = new HashSet<>(expected); + diff1.removeAll(actual); + Set diff2 = new HashSet<>(actual); + diff2.removeAll(expected); + + if (diff1.size() > 0 || diff2.size() > 0) { + System.out.println("missing items: " + diff1); + System.out.println("extra items: " + diff2); + } + + Assert.assertEquals(diff1.size(), 0); + Assert.assertEquals(diff2.size(), 0); + } +} diff --git a/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestScanExpected.txt b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestScanExpected.txt new file mode 100644 index 00000000000..73568034673 --- /dev/null +++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestScanExpected.txt @@ -0,0 +1,47 @@ +jdk/jdeprusage/UseClass$ArrayCreation +jdk/jdeprusage/UseClass$ArrayFieldUsage +jdk/jdeprusage/UseClass$ArrayMethodCall +jdk/jdeprusage/UseClass$Cast +jdk/jdeprusage/UseClass$ClassLiteral +jdk/jdeprusage/UseClass$Construct +jdk/jdeprusage/UseClass$Extends +jdk/jdeprusage/UseClass$FieldType +jdk/jdeprusage/UseClass$InstanceOf +jdk/jdeprusage/UseClass$MethodParameter +jdk/jdeprusage/UseClass$MethodReturn +jdk/jdeprusage/UseEnum$ClassObject +jdk/jdeprusage/UseEnum$EnumConstant +jdk/jdeprusage/UseEnum$FieldType +jdk/jdeprusage/UseEnum$MethodParameter +jdk/jdeprusage/UseEnum$ReturnValue +jdk/jdeprusage/UseEnum$ValueOfMethod +jdk/jdeprusage/UseEnum$ValuesMethod +jdk/jdeprusage/UseEnumMembers$1 +jdk/jdeprusage/UseEnumMembers$MethodInEnum1 +jdk/jdeprusage/UseEnumMembers$MethodOnConstant1 +jdk/jdeprusage/UseEnumMembers$ReturnValue +jdk/jdeprusage/UseException$Catch +jdk/jdeprusage/UseException$Throws +jdk/jdeprusage/UseField$Direct +jdk/jdeprusage/UseField$FromSubclass +jdk/jdeprusage/UseField$Inherited +jdk/jdeprusage/UseField$StaticField +jdk/jdeprusage/UseField$SuperFromSubclass +jdk/jdeprusage/UseInterface$ClassImplements +jdk/jdeprusage/UseInterface$InterfaceExtends +jdk/jdeprusage/UseMethod$ClassStatic +jdk/jdeprusage/UseMethod$Constructor +jdk/jdeprusage/UseMethod$ConstructorFromSubclass +jdk/jdeprusage/UseMethod$Direct +jdk/jdeprusage/UseMethod$Inherited +jdk/jdeprusage/UseMethod$InheritedDefault +jdk/jdeprusage/UseMethod$InheritedFromSubclass +jdk/jdeprusage/UseMethod$InheritedInterface +jdk/jdeprusage/UseMethod$InheritedInterfaceDefault +jdk/jdeprusage/UseMethod$InterfaceDefault +jdk/jdeprusage/UseMethod$InterfaceDirect +jdk/jdeprusage/UseMethod$InterfaceStatic +jdk/jdeprusage/UseMethod$OverrideClassMethod +jdk/jdeprusage/UseMethod$OverrideDefaultMethod +jdk/jdeprusage/UseMethod$OverrideInterfaceMethod +jdk/jdeprusage/UseMethod$SuperFromSubclass diff --git a/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseAnnotation.java b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseAnnotation.java new file mode 100644 index 00000000000..71ac29f4ef0 --- /dev/null +++ b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseAnnotation.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jdeprusage; + +import jdk.deprcases.types.DeprecatedAnnotation; + +public class UseAnnotation { + @DeprecatedAnnotation + static class AnnotatedClass { } + + static class AnnotatedMethod { + @DeprecatedAnnotation + void foo() { } + } + + static class AnnotatedField { + @DeprecatedAnnotation + int foo = 1; + } +} diff --git a/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseClass.java b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseClass.java new file mode 100644 index 00000000000..b56accd828a --- /dev/null +++ b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseClass.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jdeprusage; + +import jdk.deprcases.types.DeprecatedClass; + +public class UseClass { + static class Extends extends DeprecatedClass { + } + + static class ClassLiteral { + Class clazz = DeprecatedClass.class; + } + + static class FieldType { + DeprecatedClass obj = null; + } + + static class MethodParameter { + void foo(DeprecatedClass x) { } + } + + static class MethodReturn { + DeprecatedClass foo() { return null; } + } + + static class ArrayCreation { + Object foo() { + return new DeprecatedClass[1]; + } + } + + static class ArrayFieldUsage { + int foo(Object o) { + return ((DeprecatedClass[])o).length; + } + } + + static class ArrayMethodCall { + Object foo(Object o) { + return ((DeprecatedClass[])o).clone(); + } + } + + static class InstanceOf { + boolean foo(Object o) { + return o instanceof DeprecatedClass; + } + } + + static class Cast { + Object foo(Object o) { + return (DeprecatedClass)o; + } + } + + static class Generic { + static void g() { } + } + + static class ClassTypeArg extends Generic { } + + static class MethodTypeArg { + void foo() { + Generic.g(); + } + } + + static class ConstructorTypeArg { + Object foo() { + return new Generic(); + } + } + + static class Construct { + Object foo() { + return new DeprecatedClass(); + } + } + + static class Local { + void foo() { + DeprecatedClass obj = null; + } + } +} diff --git a/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseEnum.java b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseEnum.java new file mode 100644 index 00000000000..aa1c2106f48 --- /dev/null +++ b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseEnum.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jdeprusage; + +import jdk.deprcases.types.DeprecatedEnum; + +public class UseEnum { + static class ReturnValue { + static DeprecatedEnum returnValue() { return null; } + } + + static class MethodParameter { + static void methodParameterType(DeprecatedEnum e) { } + } + + static class FieldType { + static DeprecatedEnum field; + } + + static class EnumConstant { + static Object field2 = DeprecatedEnum.FIRST; + } + + static class ValuesMethod { + static Object[] valuesMethod() { + return DeprecatedEnum.values(); + } + } + + static class ValueOfMethod { + static Object valueOfMethod(String s) { + return DeprecatedEnum.valueOf(s); + } + } + + static class ClassObject { + static Object classObject() { + return DeprecatedEnum.class; + } + } +} diff --git a/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseEnumMembers.java b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseEnumMembers.java new file mode 100644 index 00000000000..7b4916bfca3 --- /dev/null +++ b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseEnumMembers.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jdeprusage; + +import jdk.deprcases.members.ExampleEnum; + +public class UseEnumMembers { + static class ReturnValue { + static ExampleEnum returnValue() { + return ExampleEnum.FIVE; + } + } + + static class UseInSwitch { + // enum switch generates inner class UseEnumMembers$UseInSwitch$1 + static void useInSwitch(ExampleEnum e) { + switch (e) { + case ONE: + case TWO: + case FOUR: + // no deprecation + break; + case THREE: + // deprecated + break; + } + } + } + + static class MethodInEnum1 { + static void methodInEnum1(ExampleEnum e) { + e.deprMethod1(); + } + } + + static class MethodOnConstant1 { + static void methodOnConstant1() { + // surprising that there is a warning here; + // the method deprMethod1 is overridden in TWO + ExampleEnum.TWO.deprMethod1(); + } + } + + static void methodInEnum2(ExampleEnum e) { + e.deprMethod2(); + } + + static void methodOnConstant2() { + // surprising there is no warning here; + // the method is deprecated in TWO + ExampleEnum.TWO.deprMethod2(); + } +} diff --git a/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseException.java b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseException.java new file mode 100644 index 00000000000..87f8a241eaf --- /dev/null +++ b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseException.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jdeprusage; + +import jdk.deprcases.types.DeprecatedException; + +public class UseException { + static class Throws { + static void foo() throws DeprecatedException { } + } + + static class Catch { + void foo() { + try { + Throws.foo(); + } catch (DeprecatedException de) { } + } + } +} diff --git a/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseField.java b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseField.java new file mode 100644 index 00000000000..ed940c4f0ea --- /dev/null +++ b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseField.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jdeprusage; + +import jdk.deprcases.members.ExampleClass; +import jdk.deprcases.members.ExampleInterface; +import jdk.deprcases.members.ExampleSubclass; + +public class UseField { + static class Direct { + int f(ExampleClass ec) { + return ec.field1; + } + } + + static class Inherited { + int f(ExampleSubclass esc) { + return esc.field2; + } + } + + static class InterfaceInherited { + int f(ExampleSubclass esc) { + return esc.DEP_FIELD2; + } + } + + static class InterfaceDirect { + int f(ExampleInterface ei) { + return ei.DEP_FIELD1; + } + } + + static class FromSubclass extends ExampleClass { + int f() { + return field1; + } + } + + static class SuperFromSubclass extends ExampleClass { + int f() { + return super.field1; + } + } + + static class StaticField { + int f() { + return ExampleClass.staticfield3; + } + } +} diff --git a/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseInterface.java b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseInterface.java new file mode 100644 index 00000000000..2368a915eb5 --- /dev/null +++ b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseInterface.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jdeprusage; + +import jdk.deprcases.types.DeprecatedInterface; + +public class UseInterface { + static class ClassImplements implements DeprecatedInterface { + + } + + interface InterfaceExtends extends DeprecatedInterface { + + } +} diff --git a/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseMethod.java b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseMethod.java new file mode 100644 index 00000000000..79aa91ab5b7 --- /dev/null +++ b/langtools/test/tools/jdeprscan/usage/jdk/deprusage/UseMethod.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jdeprusage; + +import jdk.deprcases.members.ExampleClass; +import jdk.deprcases.members.ExampleInterface; +import jdk.deprcases.members.ExampleSubclass; + +public class UseMethod { + static class Direct { + void m(ExampleClass ec) { + ec.method1(); + } + } + + static class Inherited { + void m(ExampleSubclass esc) { + esc.method2(); + } + } + + static class InheritedDefault { + void m(ExampleSubclass esc) { + esc.defaultMethod(); + } + } + + static class InterfaceDirect { + void m(ExampleInterface ei) { + ei.interfaceMethod1(); + } + } + + static class InterfaceDefault { + void m(ExampleInterface ei) { + ei.defaultMethod(); + } + } + + static class ClassStatic { + void m() { + ExampleClass.staticmethod1(); + } + } + + static class InterfaceStatic { + void m() { + ExampleInterface.staticmethod2(); + } + } + + static class SuperFromSubclass extends ExampleClass { + void m() { + super.method1(); + } + } + + static class InheritedFromSubclass extends ExampleClass { + void m() { + method1(); + } + } + + static class Constructor { + Object m() { + return new ExampleClass(true); + } + } + + static class ConstructorFromSubclass extends ExampleClass { + public ConstructorFromSubclass() { + super(true); + } + } + + abstract static class InheritedInterfaceDefault extends ExampleSubclass { + void m() { + defaultMethod(); + } + } + + abstract static class InheritedInterface extends ExampleSubclass { + void m() { + interfaceMethod1(); + } + } + + static class OverrideClassMethod extends ExampleClass { + @Override + public void method1() { } + } + + abstract static class OverrideInterfaceMethod implements ExampleInterface { + @Override + public void interfaceMethod1() { } + } + + abstract static class OverrideDefaultMethod implements ExampleInterface { + @Override + public void defaultMethod() { } + } +} diff --git a/langtools/test/tools/jdeps/jdkinternals/RemovedJDKInternals.java b/langtools/test/tools/jdeps/jdkinternals/RemovedJDKInternals.java index 68822f8d71c..272fb717251 100644 --- a/langtools/test/tools/jdeps/jdkinternals/RemovedJDKInternals.java +++ b/langtools/test/tools/jdeps/jdkinternals/RemovedJDKInternals.java @@ -73,7 +73,7 @@ public class RemovedJDKInternals { // patch jdk.unsupported and set -cp to codec types assertTrue(CompilerUtils.compile(Paths.get(TEST_SRC, "src", "p"), CLASSES_DIR, - "-Xpatch:jdk.unsupported=" + patchDir, + "--patch-module", "jdk.unsupported=" + patchDir, "-cp", codecDest.toString())); } diff --git a/langtools/test/tools/jdeps/lib/CompilerUtils.java b/langtools/test/tools/jdeps/lib/CompilerUtils.java index be2a0ff66b2..35c0543137f 100644 --- a/langtools/test/tools/jdeps/lib/CompilerUtils.java +++ b/langtools/test/tools/jdeps/lib/CompilerUtils.java @@ -100,7 +100,7 @@ public final class CompilerUtils { } Stream opts = Arrays.stream(new String[] { - "-modulesourcepath", source.toString(), "-m", moduleName + "--module-source-path", source.toString(), "-m", moduleName }); List javacOpts = Stream.concat(opts, Arrays.stream(options)) .collect(Collectors.toList()); diff --git a/nashorn/.hgtags b/nashorn/.hgtags index aa139484a6f..f68987a568a 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -366,3 +366,4 @@ ff07be6106fa56b72c163244f45a3ecb4c995564 jdk-9+127 0de67a63e2c73781ecf5979a2f3aa9619a445c37 jdk-9+130 ee77c6b3713ab293e027ac3ea1cc16f86dac535f jdk-9+131 55a75af751dfe44039baef2b762ee7347021025b jdk-9+132 +3a924b820d02b108cf57b51e145b5150d1eedcca jdk-9+133 diff --git a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java index 418bce95c85..d792738cfa4 100644 --- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java +++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java @@ -172,7 +172,7 @@ public final class Main extends Shell { final Consumer evaluator = str -> { // could be called from different thread (GUI), we need to handle Context set/reset final Global _oldGlobal = Context.getGlobal(); - final boolean _globalChanged = (oldGlobal != global); + final boolean _globalChanged = (_oldGlobal != global); if (_globalChanged) { Context.setGlobal(global); } diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesCalculator.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesCalculator.java index ac05a5f77ca..a026f2d2c57 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesCalculator.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesCalculator.java @@ -79,7 +79,7 @@ final class OptimisticTypesCalculator extends SimpleNodeVisitor { @Override public boolean enterPropertyNode(final PropertyNode propertyNode) { - if(propertyNode.getKeyName().equals(ScriptObject.PROTO_PROPERTY_NAME)) { + if(ScriptObject.PROTO_PROPERTY_NAME.equals(propertyNode.getKeyName())) { tagNeverOptimistic(propertyNode.getValue()); } return super.enterPropertyNode(propertyNode); diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties index 718f6cb07ef..d259e7528b5 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties @@ -173,3 +173,20 @@ String.prototype.toUpperCase=returns a new string representing the calling strin String.prototype.toLocaleUpperCase=returns a new string representing the calling string value converted to upper case according to any locale specific case mappings String.prototype.trim=returns a new string representing the calling string with white space removed from both ends + +Boolean.prototype.toString=returns string representation of specified Boolean object + +Boolean.prototype.valueOf=returns the primitive value of the specified Boolean object + +Number.prototype.toString=returns string representation of specified object in the specified radix + +Number.prototype.toLocaleString=returns a string with a language sensitive representation of this number + +Number.prototype.valueOf=returns the primitive value of the specified object + +Number.prototype.toFixed=returns a string representing the number in decimal fixed-point notation + +Number.prototype.toExponential=returns a string representing the number in decimal exponential notation + +Number.prototype.toPrecision=returns a string representing the number to a specified precision in fixed-point or exponential notation +