Merge
This commit is contained in:
commit
74d720c7b5
@ -48,7 +48,6 @@ FILES_c = \
|
||||
Proxy.c \
|
||||
RandomAccessFile.c \
|
||||
RandomAccessFile_md.c \
|
||||
ResourceBundle.c \
|
||||
Runtime.c \
|
||||
SecurityManager.c \
|
||||
Shutdown.c \
|
||||
|
@ -134,7 +134,6 @@ SUNWprivate_1.1 {
|
||||
Java_java_lang_ClassLoader_00024NativeLibrary_load;
|
||||
Java_java_lang_ClassLoader_00024NativeLibrary_unload;
|
||||
Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib;
|
||||
Java_java_lang_ClassLoader_getCaller;
|
||||
Java_java_lang_ClassLoader_registerNatives;
|
||||
Java_java_lang_Compiler_registerNatives;
|
||||
Java_java_lang_Double_longBitsToDouble;
|
||||
@ -233,7 +232,6 @@ SUNWprivate_1.1 {
|
||||
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2;
|
||||
Java_java_security_AccessController_getStackAccessControlContext;
|
||||
Java_java_security_AccessController_getInheritedAccessControlContext;
|
||||
Java_java_util_ResourceBundle_getClassContext;
|
||||
Java_java_util_TimeZone_getSystemTimeZoneID;
|
||||
Java_java_util_TimeZone_getSystemGMTOffsetID;
|
||||
Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8;
|
||||
|
@ -73,7 +73,6 @@ text: .text%writeBytes;
|
||||
# Test Sleep
|
||||
# Test IntToString
|
||||
# Test LoadToolkit
|
||||
text: .text%Java_java_util_ResourceBundle_getClassContext;
|
||||
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
|
||||
text: .text%JNU_GetEnv;
|
||||
text: .text%Java_java_io_UnixFileSystem_checkAccess;
|
||||
|
@ -78,7 +78,6 @@ text: .text%writeBytes;
|
||||
# Test Sleep
|
||||
# Test IntToString
|
||||
# Test LoadToolkit
|
||||
text: .text%Java_java_util_ResourceBundle_getClassContext;
|
||||
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
|
||||
text: .text%JNU_GetEnv;
|
||||
text: .text%Java_java_io_UnixFileSystem_checkAccess;
|
||||
|
@ -74,7 +74,6 @@ text: .text%writeBytes;
|
||||
# Test Sleep
|
||||
# Test IntToString
|
||||
# Test LoadToolkit
|
||||
text: .text%Java_java_util_ResourceBundle_getClassContext;
|
||||
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
|
||||
text: .text%JNU_GetEnv;
|
||||
text: .text%Java_java_io_UnixFileSystem_checkAccess;
|
||||
|
@ -106,7 +106,21 @@ FILES_cpp_shared = \
|
||||
OpenTypeLayoutEngine.cpp \
|
||||
ThaiLayoutEngine.cpp \
|
||||
ScriptAndLanguageTags.cpp \
|
||||
FontInstanceAdapter.cpp
|
||||
FontInstanceAdapter.cpp \
|
||||
ContextualGlyphInsertionProc2.cpp \
|
||||
ContextualGlyphSubstProc2.cpp \
|
||||
GXLayoutEngine2.cpp \
|
||||
IndicRearrangementProcessor2.cpp \
|
||||
LigatureSubstProc2.cpp \
|
||||
MorphTables2.cpp \
|
||||
NonContextualGlyphSubstProc2.cpp \
|
||||
SegmentArrayProcessor2.cpp \
|
||||
SegmentSingleProcessor2.cpp \
|
||||
SimpleArrayProcessor2.cpp \
|
||||
SingleTableProcessor2.cpp \
|
||||
StateTableProcessor2.cpp \
|
||||
SubtableProcessor2.cpp \
|
||||
TrimmedArrayProcessor2.cpp
|
||||
|
||||
|
||||
ifeq ($(PLATFORM),windows)
|
||||
|
@ -134,7 +134,6 @@ SUNWprivate_1.1 {
|
||||
Java_java_lang_ClassLoader_00024NativeLibrary_load;
|
||||
Java_java_lang_ClassLoader_00024NativeLibrary_unload;
|
||||
Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib;
|
||||
Java_java_lang_ClassLoader_getCaller;
|
||||
Java_java_lang_ClassLoader_registerNatives;
|
||||
Java_java_lang_Compiler_registerNatives;
|
||||
Java_java_lang_Double_longBitsToDouble;
|
||||
@ -233,7 +232,6 @@ SUNWprivate_1.1 {
|
||||
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2;
|
||||
Java_java_security_AccessController_getStackAccessControlContext;
|
||||
Java_java_security_AccessController_getInheritedAccessControlContext;
|
||||
Java_java_util_ResourceBundle_getClassContext;
|
||||
Java_java_util_TimeZone_getSystemTimeZoneID;
|
||||
Java_java_util_TimeZone_getSystemGMTOffsetID;
|
||||
Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8;
|
||||
|
@ -78,7 +78,6 @@ text: .text%writeBytes;
|
||||
# Test Sleep
|
||||
# Test IntToString
|
||||
# Test LoadToolkit
|
||||
text: .text%Java_java_util_ResourceBundle_getClassContext;
|
||||
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
|
||||
text: .text%JNU_GetEnv;
|
||||
text: .text%Java_java_io_UnixFileSystem_checkAccess;
|
||||
|
@ -74,7 +74,6 @@ text: .text%writeBytes;
|
||||
# Test Sleep
|
||||
# Test IntToString
|
||||
# Test LoadToolkit
|
||||
text: .text%Java_java_util_ResourceBundle_getClassContext;
|
||||
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
|
||||
text: .text%JNU_GetEnv;
|
||||
text: .text%Java_java_io_UnixFileSystem_checkAccess;
|
||||
|
@ -73,7 +73,6 @@ text: .text%writeBytes;
|
||||
# Test Sleep
|
||||
# Test IntToString
|
||||
# Test LoadToolkit
|
||||
text: .text%Java_java_util_ResourceBundle_getClassContext;
|
||||
text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
|
||||
text: .text%JNU_GetEnv;
|
||||
text: .text%Java_java_io_UnixFileSystem_checkAccess;
|
||||
|
@ -170,7 +170,7 @@ public class LWWindowPeer
|
||||
setTitle(((Dialog) getTarget()).getTitle());
|
||||
}
|
||||
|
||||
setAlwaysOnTop(getTarget().isAlwaysOnTop());
|
||||
updateAlwaysOnTopState();
|
||||
updateMinimumSize();
|
||||
|
||||
final Shape shape = getTarget().getShape();
|
||||
@ -357,8 +357,8 @@ public class LWWindowPeer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlwaysOnTop(boolean value) {
|
||||
platformWindow.setAlwaysOnTop(value);
|
||||
public void updateAlwaysOnTopState() {
|
||||
platformWindow.setAlwaysOnTop(getTarget().isAlwaysOnTop());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2013, 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
|
||||
@ -180,7 +180,7 @@ class CFileDialog implements FileDialogPeer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlwaysOnTop(boolean alwaysOnTop) {
|
||||
public void updateAlwaysOnTopState() {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2013, 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
|
||||
@ -87,7 +87,7 @@ public class CPrinterDialogPeer extends LWWindowPeer {
|
||||
}
|
||||
|
||||
// 1.6 peer method
|
||||
public void setAlwaysOnTop(boolean value) {
|
||||
public void updateAlwaysOnTopState() {
|
||||
// no-op, since we just show the native print dialog
|
||||
}
|
||||
|
||||
|
@ -243,12 +243,17 @@ public class JPEGImageReader extends ImageReader {
|
||||
* sending warnings to listeners.
|
||||
*/
|
||||
protected void warningOccurred(int code) {
|
||||
cbLock.lock();
|
||||
try {
|
||||
if ((code < 0) || (code > MAX_WARNING)){
|
||||
throw new InternalError("Invalid warning index");
|
||||
}
|
||||
processWarningOccurred
|
||||
("com.sun.imageio.plugins.jpeg.JPEGImageReaderResources",
|
||||
Integer.toString(code));
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -265,7 +270,12 @@ public class JPEGImageReader extends ImageReader {
|
||||
* library warnings from being printed to stderr.
|
||||
*/
|
||||
protected void warningWithMessage(String msg) {
|
||||
cbLock.lock();
|
||||
try {
|
||||
processWarningOccurred(msg);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setInput(Object input,
|
||||
@ -274,18 +284,55 @@ public class JPEGImageReader extends ImageReader {
|
||||
{
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
super.setInput(input, seekForwardOnly, ignoreMetadata);
|
||||
this.ignoreMetadata = ignoreMetadata;
|
||||
resetInternalState();
|
||||
iis = (ImageInputStream) input; // Always works
|
||||
setSource(structPointer, iis);
|
||||
setSource(structPointer);
|
||||
} finally {
|
||||
clearThreadLock();
|
||||
}
|
||||
}
|
||||
|
||||
private native void setSource(long structPointer,
|
||||
ImageInputStream source);
|
||||
/**
|
||||
* This method is called from native code in order to fill
|
||||
* native input buffer.
|
||||
*
|
||||
* We block any attempt to change the reading state during this
|
||||
* method, in order to prevent a corruption of the native decoder
|
||||
* state.
|
||||
*
|
||||
* @return number of bytes read from the stream.
|
||||
*/
|
||||
private int readInputData(byte[] buf, int off, int len) throws IOException {
|
||||
cbLock.lock();
|
||||
try {
|
||||
return iis.read(buf, off, len);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from the native code in order to
|
||||
* skip requested number of bytes in the input stream.
|
||||
*
|
||||
* @param n
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private long skipInputBytes(long n) throws IOException {
|
||||
cbLock.lock();
|
||||
try {
|
||||
return iis.skipBytes(n);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private native void setSource(long structPointer);
|
||||
|
||||
private void checkTablesOnly() throws IOException {
|
||||
if (debug) {
|
||||
@ -337,6 +384,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
public int getNumImages(boolean allowSearch) throws IOException {
|
||||
setThreadLock();
|
||||
try { // locked thread
|
||||
cbLock.check();
|
||||
|
||||
return getNumImagesOnThread(allowSearch);
|
||||
} finally {
|
||||
clearThreadLock();
|
||||
@ -536,8 +585,13 @@ public class JPEGImageReader extends ImageReader {
|
||||
if (debug) {
|
||||
System.out.println("pushing back " + num + " bytes");
|
||||
}
|
||||
cbLock.lock();
|
||||
try {
|
||||
iis.seek(iis.getStreamPosition()-num);
|
||||
// The buffer is clear after this, so no need to set haveSeeked.
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -644,7 +698,12 @@ public class JPEGImageReader extends ImageReader {
|
||||
* Ignore this profile.
|
||||
*/
|
||||
iccCS = null;
|
||||
cbLock.lock();
|
||||
try {
|
||||
warningOccurred(WARNING_IGNORE_INVALID_ICC);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -653,6 +712,7 @@ public class JPEGImageReader extends ImageReader {
|
||||
setThreadLock();
|
||||
try {
|
||||
if (currentImage != imageIndex) {
|
||||
cbLock.check();
|
||||
readHeader(imageIndex, true);
|
||||
}
|
||||
return width;
|
||||
@ -665,6 +725,7 @@ public class JPEGImageReader extends ImageReader {
|
||||
setThreadLock();
|
||||
try {
|
||||
if (currentImage != imageIndex) {
|
||||
cbLock.check();
|
||||
readHeader(imageIndex, true);
|
||||
}
|
||||
return height;
|
||||
@ -693,6 +754,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
setThreadLock();
|
||||
try {
|
||||
if (currentImage != imageIndex) {
|
||||
cbLock.check();
|
||||
|
||||
readHeader(imageIndex, true);
|
||||
}
|
||||
|
||||
@ -716,6 +779,7 @@ public class JPEGImageReader extends ImageReader {
|
||||
private Iterator getImageTypesOnThread(int imageIndex)
|
||||
throws IOException {
|
||||
if (currentImage != imageIndex) {
|
||||
cbLock.check();
|
||||
readHeader(imageIndex, true);
|
||||
}
|
||||
|
||||
@ -931,6 +995,7 @@ public class JPEGImageReader extends ImageReader {
|
||||
setThreadLock();
|
||||
try {
|
||||
if (!tablesOnlyChecked) {
|
||||
cbLock.check();
|
||||
checkTablesOnly();
|
||||
}
|
||||
return streamMetadata;
|
||||
@ -951,6 +1016,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
return imageMetadata;
|
||||
}
|
||||
|
||||
cbLock.check();
|
||||
|
||||
gotoImage(imageIndex);
|
||||
|
||||
imageMetadata = new JPEGMetadata(false, false, iis, this);
|
||||
@ -967,6 +1034,7 @@ public class JPEGImageReader extends ImageReader {
|
||||
throws IOException {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
try {
|
||||
readInternal(imageIndex, param, false);
|
||||
} catch (RuntimeException e) {
|
||||
@ -1196,6 +1264,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
}
|
||||
target.setRect(destROI.x, destROI.y + y, raster);
|
||||
|
||||
cbLock.lock();
|
||||
try {
|
||||
processImageUpdate(image,
|
||||
destROI.x, destROI.y+y,
|
||||
raster.getWidth(), 1,
|
||||
@ -1249,6 +1319,9 @@ public class JPEGImageReader extends ImageReader {
|
||||
processImageProgress(percentOfPass * 100.0F);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void initProgressData() {
|
||||
@ -1260,6 +1333,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
}
|
||||
|
||||
private void passStarted (int pass) {
|
||||
cbLock.lock();
|
||||
try {
|
||||
this.pass = pass;
|
||||
previousPassPercentage = percentToDate;
|
||||
processPassStarted(image,
|
||||
@ -1269,24 +1344,47 @@ public class JPEGImageReader extends ImageReader {
|
||||
0, 0,
|
||||
1,1,
|
||||
destinationBands);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void passComplete () {
|
||||
cbLock.lock();
|
||||
try {
|
||||
processPassComplete(image);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void thumbnailStarted(int thumbnailIndex) {
|
||||
cbLock.lock();
|
||||
try {
|
||||
processThumbnailStarted(currentImage, thumbnailIndex);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Provide access to protected superclass method
|
||||
void thumbnailProgress(float percentageDone) {
|
||||
cbLock.lock();
|
||||
try {
|
||||
processThumbnailProgress(percentageDone);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Provide access to protected superclass method
|
||||
void thumbnailComplete() {
|
||||
cbLock.lock();
|
||||
try {
|
||||
processThumbnailComplete();
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1310,6 +1408,11 @@ public class JPEGImageReader extends ImageReader {
|
||||
public void abort() {
|
||||
setThreadLock();
|
||||
try {
|
||||
/**
|
||||
* NB: we do not check the call back lock here,
|
||||
* we allow to abort the reader any time.
|
||||
*/
|
||||
|
||||
super.abort();
|
||||
abortRead(structPointer);
|
||||
} finally {
|
||||
@ -1332,6 +1435,7 @@ public class JPEGImageReader extends ImageReader {
|
||||
setThreadLock();
|
||||
Raster retval = null;
|
||||
try {
|
||||
cbLock.check();
|
||||
/*
|
||||
* This could be further optimized by not resetting the dest.
|
||||
* offset and creating a translated raster in readInternal()
|
||||
@ -1371,6 +1475,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
public int getNumThumbnails(int imageIndex) throws IOException {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
getImageMetadata(imageIndex); // checks iis state for us
|
||||
// Now check the jfif segments
|
||||
JFIFMarkerSegment jfif =
|
||||
@ -1391,6 +1497,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
throws IOException {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
if ((thumbnailIndex < 0)
|
||||
|| (thumbnailIndex >= getNumThumbnails(imageIndex))) {
|
||||
throw new IndexOutOfBoundsException("No such thumbnail");
|
||||
@ -1409,6 +1517,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
throws IOException {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
if ((thumbnailIndex < 0)
|
||||
|| (thumbnailIndex >= getNumThumbnails(imageIndex))) {
|
||||
throw new IndexOutOfBoundsException("No such thumbnail");
|
||||
@ -1428,6 +1538,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
throws IOException {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
if ((thumbnailIndex < 0)
|
||||
|| (thumbnailIndex >= getNumThumbnails(imageIndex))) {
|
||||
throw new IndexOutOfBoundsException("No such thumbnail");
|
||||
@ -1468,6 +1580,7 @@ public class JPEGImageReader extends ImageReader {
|
||||
public void reset() {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
super.reset();
|
||||
} finally {
|
||||
clearThreadLock();
|
||||
@ -1479,6 +1592,8 @@ public class JPEGImageReader extends ImageReader {
|
||||
public void dispose() {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
if (structPointer != 0) {
|
||||
disposerRecord.dispose();
|
||||
structPointer = 0;
|
||||
@ -1540,6 +1655,36 @@ public class JPEGImageReader extends ImageReader {
|
||||
theThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
private CallBackLock cbLock = new CallBackLock();
|
||||
|
||||
private static class CallBackLock {
|
||||
|
||||
private State lockState;
|
||||
|
||||
CallBackLock() {
|
||||
lockState = State.Unlocked;
|
||||
}
|
||||
|
||||
void check() {
|
||||
if (lockState != State.Unlocked) {
|
||||
throw new IllegalStateException("Access to the reader is not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
private void lock() {
|
||||
lockState = State.Locked;
|
||||
}
|
||||
|
||||
private void unlock() {
|
||||
lockState = State.Unlocked;
|
||||
}
|
||||
|
||||
private static enum State {
|
||||
Unlocked,
|
||||
Locked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,8 +183,7 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
initWriterIDs(ImageOutputStream.class,
|
||||
JPEGQTable.class,
|
||||
initWriterIDs(JPEGQTable.class,
|
||||
JPEGHuffmanTable.class);
|
||||
}
|
||||
|
||||
@ -200,11 +199,13 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
public void setOutput(Object output) {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
super.setOutput(output); // validates output
|
||||
resetInternalState();
|
||||
ios = (ImageOutputStream) output; // so this will always work
|
||||
// Set the native destination
|
||||
setDest(structPointer, ios);
|
||||
setDest(structPointer);
|
||||
} finally {
|
||||
clearThreadLock();
|
||||
}
|
||||
@ -359,6 +360,8 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
ImageWriteParam param) throws IOException {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
writeOnThread(streamMetadata, image, param);
|
||||
} finally {
|
||||
clearThreadLock();
|
||||
@ -1082,6 +1085,8 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
haveMetadata,
|
||||
restartInterval);
|
||||
|
||||
cbLock.lock();
|
||||
try {
|
||||
if (aborted) {
|
||||
processWriteAborted();
|
||||
} else {
|
||||
@ -1089,6 +1094,9 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
}
|
||||
|
||||
ios.flush();
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
currentImage++; // After a successful write
|
||||
}
|
||||
|
||||
@ -1096,6 +1104,8 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
throws IOException {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
prepareWriteSequenceOnThread(streamMetadata);
|
||||
} finally {
|
||||
clearThreadLock();
|
||||
@ -1175,6 +1185,8 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
throws IOException {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
if (sequencePrepared == false) {
|
||||
throw new IllegalStateException("sequencePrepared not called!");
|
||||
}
|
||||
@ -1188,6 +1200,8 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
public void endWriteSequence() throws IOException {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
if (sequencePrepared == false) {
|
||||
throw new IllegalStateException("sequencePrepared not called!");
|
||||
}
|
||||
@ -1200,6 +1214,10 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
public synchronized void abort() {
|
||||
setThreadLock();
|
||||
try {
|
||||
/**
|
||||
* NB: we do not check the call back lock here, we allow to abort
|
||||
* the reader any time.
|
||||
*/
|
||||
super.abort();
|
||||
abortWrite(structPointer);
|
||||
} finally {
|
||||
@ -1223,6 +1241,8 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
public void reset() {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
super.reset();
|
||||
} finally {
|
||||
clearThreadLock();
|
||||
@ -1232,6 +1252,8 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
public void dispose() {
|
||||
setThreadLock();
|
||||
try {
|
||||
cbLock.check();
|
||||
|
||||
if (structPointer != 0) {
|
||||
disposerRecord.dispose();
|
||||
structPointer = 0;
|
||||
@ -1251,6 +1273,8 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
* sending warnings to listeners.
|
||||
*/
|
||||
void warningOccurred(int code) {
|
||||
cbLock.lock();
|
||||
try {
|
||||
if ((code < 0) || (code > MAX_WARNING)){
|
||||
throw new InternalError("Invalid warning index");
|
||||
}
|
||||
@ -1258,6 +1282,9 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
(currentImage,
|
||||
"com.sun.imageio.plugins.jpeg.JPEGImageWriterResources",
|
||||
Integer.toString(code));
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1274,21 +1301,41 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
* library warnings from being printed to stderr.
|
||||
*/
|
||||
void warningWithMessage(String msg) {
|
||||
cbLock.lock();
|
||||
try {
|
||||
processWarningOccurred(currentImage, msg);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void thumbnailStarted(int thumbnailIndex) {
|
||||
cbLock.lock();
|
||||
try {
|
||||
processThumbnailStarted(currentImage, thumbnailIndex);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Provide access to protected superclass method
|
||||
void thumbnailProgress(float percentageDone) {
|
||||
cbLock.lock();
|
||||
try {
|
||||
processThumbnailProgress(percentageDone);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Provide access to protected superclass method
|
||||
void thumbnailComplete() {
|
||||
cbLock.lock();
|
||||
try {
|
||||
processThumbnailComplete();
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
///////// End of Package-access API
|
||||
@ -1615,16 +1662,14 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
////////////// Native methods and callbacks
|
||||
|
||||
/** Sets up static native structures. */
|
||||
private static native void initWriterIDs(Class iosClass,
|
||||
Class qTableClass,
|
||||
private static native void initWriterIDs(Class qTableClass,
|
||||
Class huffClass);
|
||||
|
||||
/** Sets up per-writer native structure and returns a pointer to it. */
|
||||
private native long initJPEGImageWriter();
|
||||
|
||||
/** Sets up native structures for output stream */
|
||||
private native void setDest(long structPointer,
|
||||
ImageOutputStream ios);
|
||||
private native void setDest(long structPointer);
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the write was aborted.
|
||||
@ -1749,7 +1794,12 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
}
|
||||
raster.setRect(sourceLine);
|
||||
if ((y > 7) && (y%8 == 0)) { // Every 8 scanlines
|
||||
cbLock.lock();
|
||||
try {
|
||||
processImageProgress((float) y / (float) sourceHeight * 100.0F);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1777,6 +1827,25 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from native code in order to write encoder
|
||||
* output to the destination.
|
||||
*
|
||||
* We block any attempt to change the writer state during this
|
||||
* method, in order to prevent a corruption of the native encoder
|
||||
* state.
|
||||
*/
|
||||
private void writeOutputData(byte[] data, int offset, int len)
|
||||
throws IOException
|
||||
{
|
||||
cbLock.lock();
|
||||
try {
|
||||
ios.write(data, offset, len);
|
||||
} finally {
|
||||
cbLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private Thread theThread = null;
|
||||
private int theLockCount = 0;
|
||||
|
||||
@ -1811,4 +1880,34 @@ public class JPEGImageWriter extends ImageWriter {
|
||||
theThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
private CallBackLock cbLock = new CallBackLock();
|
||||
|
||||
private static class CallBackLock {
|
||||
|
||||
private State lockState;
|
||||
|
||||
CallBackLock() {
|
||||
lockState = State.Unlocked;
|
||||
}
|
||||
|
||||
void check() {
|
||||
if (lockState != State.Unlocked) {
|
||||
throw new IllegalStateException("Access to the writer is not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
private void lock() {
|
||||
lockState = State.Locked;
|
||||
}
|
||||
|
||||
private void unlock() {
|
||||
lockState = State.Unlocked;
|
||||
}
|
||||
|
||||
private static enum State {
|
||||
Unlocked,
|
||||
Locked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, 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
|
||||
@ -32,6 +32,7 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.Permission;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
@ -213,7 +214,6 @@ public class MBeanInstantiator {
|
||||
|
||||
Object moi;
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// ------------------------------
|
||||
Constructor<?> cons = findConstructor(theClass, null);
|
||||
@ -224,6 +224,7 @@ public class MBeanInstantiator {
|
||||
// Instantiate the new object
|
||||
try {
|
||||
ReflectUtil.checkPackageAccess(theClass);
|
||||
ensureClassAccess(theClass);
|
||||
moi= cons.newInstance();
|
||||
} catch (InvocationTargetException e) {
|
||||
// Wrap the exception.
|
||||
@ -270,7 +271,6 @@ public class MBeanInstantiator {
|
||||
checkMBeanPermission(theClass, null, null, "instantiate");
|
||||
|
||||
// Instantiate the new object
|
||||
|
||||
// ------------------------------
|
||||
// ------------------------------
|
||||
final Class<?>[] tab;
|
||||
@ -300,6 +300,7 @@ public class MBeanInstantiator {
|
||||
}
|
||||
try {
|
||||
ReflectUtil.checkPackageAccess(theClass);
|
||||
ensureClassAccess(theClass);
|
||||
moi = cons.newInstance(params);
|
||||
}
|
||||
catch (NoSuchMethodError error) {
|
||||
@ -741,4 +742,13 @@ public class MBeanInstantiator {
|
||||
sm.checkPermission(perm);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ensureClassAccess(Class clazz)
|
||||
throws IllegalAccessException
|
||||
{
|
||||
int mod = clazz.getModifiers();
|
||||
if (!Modifier.isPublic(mod)) {
|
||||
throw new IllegalAccessException("Class is not public and can't be instantiated");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
|
||||
// from simultaneous creation and destruction
|
||||
// reduces possibility of deadlock, compared to
|
||||
// synchronizing to the class instance
|
||||
private Object traRecLock = new Object();
|
||||
private final Object traRecLock = new Object();
|
||||
|
||||
// DEVICE ATTRIBUTES
|
||||
|
||||
@ -474,7 +474,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
|
||||
This is necessary for Receivers retrieved via MidiSystem.getReceiver()
|
||||
(which opens the device implicitely).
|
||||
*/
|
||||
protected abstract class AbstractReceiver implements MidiDeviceReceiver {
|
||||
abstract class AbstractReceiver implements MidiDeviceReceiver {
|
||||
private boolean open = true;
|
||||
|
||||
|
||||
@ -483,24 +483,24 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
|
||||
Receiver. Therefore, subclasses should not override this method.
|
||||
Instead, they should implement implSend().
|
||||
*/
|
||||
public synchronized void send(MidiMessage message, long timeStamp) {
|
||||
if (open) {
|
||||
implSend(message, timeStamp);
|
||||
} else {
|
||||
@Override
|
||||
public final synchronized void send(final MidiMessage message,
|
||||
final long timeStamp) {
|
||||
if (!open) {
|
||||
throw new IllegalStateException("Receiver is not open");
|
||||
}
|
||||
implSend(message, timeStamp);
|
||||
}
|
||||
|
||||
|
||||
protected abstract void implSend(MidiMessage message, long timeStamp);
|
||||
|
||||
abstract void implSend(MidiMessage message, long timeStamp);
|
||||
|
||||
/** Close the Receiver.
|
||||
* Here, the call to the magic method closeInternal() takes place.
|
||||
* Therefore, subclasses that override this method must call
|
||||
* 'super.close()'.
|
||||
*/
|
||||
public void close() {
|
||||
@Override
|
||||
public final void close() {
|
||||
open = false;
|
||||
synchronized (AbstractMidiDevice.this.traRecLock) {
|
||||
AbstractMidiDevice.this.getReceiverList().remove(this);
|
||||
@ -508,11 +508,12 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
|
||||
AbstractMidiDevice.this.closeInternal(this);
|
||||
}
|
||||
|
||||
public MidiDevice getMidiDevice() {
|
||||
@Override
|
||||
public final MidiDevice getMidiDevice() {
|
||||
return AbstractMidiDevice.this;
|
||||
}
|
||||
|
||||
protected boolean isOpen() {
|
||||
final boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ import javax.sound.midi.*;
|
||||
*
|
||||
* @author Florian Bomers
|
||||
*/
|
||||
class FastShortMessage extends ShortMessage {
|
||||
final class FastShortMessage extends ShortMessage {
|
||||
private int packedMsg;
|
||||
|
||||
public FastShortMessage(int packedMsg) throws InvalidMidiDataException {
|
||||
|
@ -32,7 +32,7 @@ import javax.sound.midi.*;
|
||||
*
|
||||
* @author Florian Bomers
|
||||
*/
|
||||
class FastSysexMessage extends SysexMessage {
|
||||
final class FastSysexMessage extends SysexMessage {
|
||||
|
||||
FastSysexMessage(byte[] data) throws InvalidMidiDataException {
|
||||
super(data);
|
||||
|
@ -103,9 +103,9 @@ class MidiOutDevice extends AbstractMidiDevice {
|
||||
|
||||
class MidiOutReceiver extends AbstractReceiver {
|
||||
|
||||
protected void implSend(MidiMessage message, long timeStamp) {
|
||||
int length = message.getLength();
|
||||
int status = message.getStatus();
|
||||
void implSend(final MidiMessage message, final long timeStamp) {
|
||||
final int length = message.getLength();
|
||||
final int status = message.getStatus();
|
||||
if (length <= 3 && status != 0xF0 && status != 0xF7) {
|
||||
int packedMsg;
|
||||
if (message instanceof ShortMessage) {
|
||||
@ -140,11 +140,15 @@ class MidiOutDevice extends AbstractMidiDevice {
|
||||
}
|
||||
nSendShortMessage(id, packedMsg, timeStamp);
|
||||
} else {
|
||||
final byte[] data;
|
||||
if (message instanceof FastSysexMessage) {
|
||||
nSendLongMessage(id, ((FastSysexMessage) message).getReadOnlyMessage(),
|
||||
length, timeStamp);
|
||||
data = ((FastSysexMessage) message).getReadOnlyMessage();
|
||||
} else {
|
||||
nSendLongMessage(id, message.getMessage(), length, timeStamp);
|
||||
data = message.getMessage();
|
||||
}
|
||||
final int dataLength = Math.min(length, data.length);
|
||||
if (dataLength > 0) {
|
||||
nSendLongMessage(id, data, dataLength, timeStamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1026,7 +1026,7 @@ class RealTimeSequencer extends AbstractMidiDevice implements Sequencer, AutoCon
|
||||
|
||||
class SequencerReceiver extends AbstractReceiver {
|
||||
|
||||
protected void implSend(MidiMessage message, long timeStamp) {
|
||||
void implSend(MidiMessage message, long timeStamp) {
|
||||
if (recording) {
|
||||
long tickPos = 0;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 2013, 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
|
||||
@ -2234,7 +2234,7 @@ public class Window extends Container implements Accessible {
|
||||
WindowPeer peer = (WindowPeer)this.peer;
|
||||
synchronized(getTreeLock()) {
|
||||
if (peer != null) {
|
||||
peer.setAlwaysOnTop(alwaysOnTop);
|
||||
peer.updateAlwaysOnTopState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 2013, 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
|
||||
@ -53,15 +53,14 @@ public interface WindowPeer extends ContainerPeer {
|
||||
void toBack();
|
||||
|
||||
/**
|
||||
* Sets if the window should always stay on top of all other windows or
|
||||
* not.
|
||||
*
|
||||
* @param alwaysOnTop if the window should always stay on top of all other
|
||||
* windows or not
|
||||
* Updates the window's always-on-top state.
|
||||
* Sets if the window should always stay
|
||||
* on top of all other windows or not.
|
||||
*
|
||||
* @see Window#getAlwaysOnTop()
|
||||
* @see Window#setAlwaysOnTop(boolean)
|
||||
*/
|
||||
void setAlwaysOnTop(boolean alwaysOnTop);
|
||||
void updateAlwaysOnTopState();
|
||||
|
||||
/**
|
||||
* Updates the window's focusable state.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2013, 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,6 @@ import com.sun.beans.finder.BeanInfoFinder;
|
||||
import com.sun.beans.finder.PropertyEditorFinder;
|
||||
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
@ -42,7 +41,7 @@ import java.util.WeakHashMap;
|
||||
*/
|
||||
final class ThreadGroupContext {
|
||||
|
||||
private static final Map<ThreadGroup, ThreadGroupContext> contexts = new WeakHashMap<>();
|
||||
private static final WeakIdentityMap<ThreadGroupContext> contexts = new WeakIdentityMap<>();
|
||||
|
||||
/**
|
||||
* Returns the appropriate {@code AppContext} for the caller,
|
||||
@ -69,6 +68,8 @@ final class ThreadGroupContext {
|
||||
private BeanInfoFinder beanInfoFinder;
|
||||
private PropertyEditorFinder propertyEditorFinder;
|
||||
|
||||
private ThreadGroupContext() {
|
||||
}
|
||||
|
||||
boolean isDesignTime() {
|
||||
return this.isDesignTime;
|
||||
|
181
jdk/src/share/classes/java/beans/WeakIdentityMap.java
Normal file
181
jdk/src/share/classes/java/beans/WeakIdentityMap.java
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 java.beans;
|
||||
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* Hash table based mapping, which uses weak references to store keys
|
||||
* and reference-equality in place of object-equality to compare them.
|
||||
* An entry will automatically be removed when its key is no longer
|
||||
* in ordinary use. Both null values and the null key are supported.
|
||||
*
|
||||
* @see java.util.IdentityHashMap
|
||||
* @see java.util.WeakHashMap
|
||||
*/
|
||||
final class WeakIdentityMap<T> {
|
||||
|
||||
private static final int MAXIMUM_CAPACITY = 1 << 30; // it MUST be a power of two
|
||||
private static final Object NULL = new Object(); // special object for null key
|
||||
|
||||
private final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
|
||||
|
||||
private Entry<T>[] table = newTable(1<<3); // table's length MUST be a power of two
|
||||
private int threshold = 6; // the next size value at which to resize
|
||||
private int size = 0; // the number of key-value mappings
|
||||
|
||||
public T get(Object key) {
|
||||
removeStaleEntries();
|
||||
if (key == null) {
|
||||
key = NULL;
|
||||
}
|
||||
int hash = key.hashCode();
|
||||
int index = getIndex(this.table, hash);
|
||||
for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) {
|
||||
if (entry.isMatched(key, hash)) {
|
||||
return entry.value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public T put(Object key, T value) {
|
||||
removeStaleEntries();
|
||||
if (key == null) {
|
||||
key = NULL;
|
||||
}
|
||||
int hash = key.hashCode();
|
||||
int index = getIndex(this.table, hash);
|
||||
for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) {
|
||||
if (entry.isMatched(key, hash)) {
|
||||
T oldValue = entry.value;
|
||||
entry.value = value;
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
this.table[index] = new Entry<T>(key, hash, value, this.queue, this.table[index]);
|
||||
if (++this.size >= this.threshold) {
|
||||
if (this.table.length == MAXIMUM_CAPACITY) {
|
||||
this.threshold = Integer.MAX_VALUE;
|
||||
}
|
||||
else {
|
||||
removeStaleEntries();
|
||||
Entry<T>[] table = newTable(this.table.length * 2);
|
||||
transfer(this.table, table);
|
||||
|
||||
// If ignoring null elements and processing ref queue caused massive
|
||||
// shrinkage, then restore old table. This should be rare, but avoids
|
||||
// unbounded expansion of garbage-filled tables.
|
||||
if (this.size >= this.threshold / 2) {
|
||||
this.table = table;
|
||||
this.threshold *= 2;
|
||||
}
|
||||
else {
|
||||
transfer(table, this.table);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void removeStaleEntries() {
|
||||
for (Object ref = this.queue.poll(); ref != null; ref = this.queue.poll()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<T> entry = (Entry<T>) ref;
|
||||
int index = getIndex(this.table, entry.hash);
|
||||
|
||||
Entry<T> prev = this.table[index];
|
||||
Entry<T> current = prev;
|
||||
while (current != null) {
|
||||
Entry<T> next = current.next;
|
||||
if (current == entry) {
|
||||
if (prev == entry) {
|
||||
this.table[index] = next;
|
||||
}
|
||||
else {
|
||||
prev.next = next;
|
||||
}
|
||||
entry.value = null; // Help GC
|
||||
entry.next = null; // Help GC
|
||||
this.size--;
|
||||
break;
|
||||
}
|
||||
prev = current;
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void transfer(Entry<T>[] oldTable, Entry<T>[] newTable) {
|
||||
for (int i = 0; i < oldTable.length; i++) {
|
||||
Entry<T> entry = oldTable[i];
|
||||
oldTable[i] = null;
|
||||
while (entry != null) {
|
||||
Entry<T> next = entry.next;
|
||||
Object key = entry.get();
|
||||
if (key == null) {
|
||||
entry.value = null; // Help GC
|
||||
entry.next = null; // Help GC
|
||||
this.size--;
|
||||
}
|
||||
else {
|
||||
int index = getIndex(newTable, entry.hash);
|
||||
entry.next = newTable[index];
|
||||
newTable[index] = entry;
|
||||
}
|
||||
entry = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Entry<T>[] newTable(int length) {
|
||||
return (Entry<T>[]) new Entry<?>[length];
|
||||
}
|
||||
|
||||
private static int getIndex(Entry<?>[] table, int hash) {
|
||||
return hash & (table.length - 1);
|
||||
}
|
||||
|
||||
private static class Entry<T> extends WeakReference<Object> {
|
||||
private final int hash;
|
||||
private T value;
|
||||
private Entry<T> next;
|
||||
|
||||
Entry(Object key, int hash, T value, ReferenceQueue<Object> queue, Entry<T> next) {
|
||||
super(key, queue);
|
||||
this.hash = hash;
|
||||
this.value = value;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
boolean isMatched(Object key, int hash) {
|
||||
return (this.hash == hash) && (key == get());
|
||||
}
|
||||
}
|
||||
}
|
@ -41,6 +41,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import static java.io.ObjectStreamClass.processQueue;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* An ObjectInputStream deserializes primitive data and objects previously
|
||||
@ -1519,6 +1520,12 @@ public class ObjectInputStream
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCustomSubclass() {
|
||||
// Return true if this class is a custom subclass of ObjectInputStream
|
||||
return getClass().getClassLoader()
|
||||
!= ObjectInputStream.class.getClassLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in and returns class descriptor for a dynamic proxy class. Sets
|
||||
* passHandle to proxy class descriptor's assigned handle. If proxy class
|
||||
@ -1548,6 +1555,15 @@ public class ObjectInputStream
|
||||
try {
|
||||
if ((cl = resolveProxyClass(ifaces)) == null) {
|
||||
resolveEx = new ClassNotFoundException("null class");
|
||||
} else if (!Proxy.isProxyClass(cl)) {
|
||||
throw new InvalidClassException("Not a proxy");
|
||||
} else {
|
||||
// ReflectUtil.checkProxyPackageAccess makes a test
|
||||
// equivalent to isCustomSubclass so there's no need
|
||||
// to condition this call to isCustomSubclass == true here.
|
||||
ReflectUtil.checkProxyPackageAccess(
|
||||
getClass().getClassLoader(),
|
||||
cl.getInterfaces());
|
||||
}
|
||||
} catch (ClassNotFoundException ex) {
|
||||
resolveEx = ex;
|
||||
@ -1589,9 +1605,12 @@ public class ObjectInputStream
|
||||
Class<?> cl = null;
|
||||
ClassNotFoundException resolveEx = null;
|
||||
bin.setBlockDataMode(true);
|
||||
final boolean checksRequired = isCustomSubclass();
|
||||
try {
|
||||
if ((cl = resolveClass(readDesc)) == null) {
|
||||
resolveEx = new ClassNotFoundException("null class");
|
||||
} else if (checksRequired) {
|
||||
ReflectUtil.checkPackageAccess(cl);
|
||||
}
|
||||
} catch (ClassNotFoundException ex) {
|
||||
resolveEx = ex;
|
||||
|
@ -53,6 +53,7 @@ import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import sun.misc.Unsafe;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.ConstantPool;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.ReflectionFactory;
|
||||
@ -250,9 +251,11 @@ public final class Class<T> implements java.io.Serializable,
|
||||
* by this method fails
|
||||
* @exception ClassNotFoundException if the class cannot be located
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Class<?> forName(String className)
|
||||
throws ClassNotFoundException {
|
||||
return forName0(className, true, ClassLoader.getCallerClassLoader());
|
||||
return forName0(className, true,
|
||||
ClassLoader.getClassLoader(Reflection.getCallerClass()));
|
||||
}
|
||||
|
||||
|
||||
@ -317,6 +320,7 @@ public final class Class<T> implements java.io.Serializable,
|
||||
* @see java.lang.ClassLoader
|
||||
* @since 1.2
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Class<?> forName(String name, boolean initialize,
|
||||
ClassLoader loader)
|
||||
throws ClassNotFoundException
|
||||
@ -324,7 +328,7 @@ public final class Class<T> implements java.io.Serializable,
|
||||
if (sun.misc.VM.isSystemDomainLoader(loader)) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
ClassLoader ccl = ClassLoader.getCallerClassLoader();
|
||||
ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass());
|
||||
if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
|
||||
sm.checkPermission(
|
||||
SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||
@ -386,18 +390,14 @@ public final class Class<T> implements java.io.Serializable,
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
@CallerSensitive
|
||||
public T newInstance()
|
||||
throws InstantiationException, IllegalAccessException
|
||||
{
|
||||
if (System.getSecurityManager() != null) {
|
||||
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
|
||||
}
|
||||
return newInstance0();
|
||||
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
|
||||
}
|
||||
|
||||
private T newInstance0()
|
||||
throws InstantiationException, IllegalAccessException
|
||||
{
|
||||
// NOTE: the following code may not be strictly correct under
|
||||
// the current Java memory model.
|
||||
|
||||
@ -432,7 +432,7 @@ public final class Class<T> implements java.io.Serializable,
|
||||
// Security check (same as in java.lang.reflect.Constructor)
|
||||
int modifiers = tmpConstructor.getModifiers();
|
||||
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass(3);
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
if (newInstanceCallerCache != caller) {
|
||||
Reflection.ensureMemberAccess(caller, this, null, modifiers);
|
||||
newInstanceCallerCache = caller;
|
||||
@ -674,16 +674,14 @@ public final class Class<T> implements java.io.Serializable,
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see java.lang.RuntimePermission
|
||||
*/
|
||||
@CallerSensitive
|
||||
public ClassLoader getClassLoader() {
|
||||
ClassLoader cl = getClassLoader0();
|
||||
if (cl == null)
|
||||
return null;
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
ClassLoader ccl = ClassLoader.getCallerClassLoader();
|
||||
if (ClassLoader.needsClassLoaderPermissionCheck(ccl, cl)) {
|
||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||
}
|
||||
ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
@ -1392,11 +1390,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Class<?>[] getClasses() {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
|
||||
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
|
||||
|
||||
// Privileged so this implementation can look at DECLARED classes,
|
||||
// something the caller might not have privilege to do. The code here
|
||||
@ -1467,11 +1463,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Field[] getFields() throws SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
|
||||
return copyFields(privateGetPublicFields(null));
|
||||
}
|
||||
|
||||
@ -1518,11 +1512,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Method[] getMethods() throws SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
|
||||
return copyMethods(privateGetPublicMethods());
|
||||
}
|
||||
|
||||
@ -1567,11 +1559,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Constructor<?>[] getConstructors() throws SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
|
||||
return copyConstructors(privateGetDeclaredConstructors(true));
|
||||
}
|
||||
|
||||
@ -1625,12 +1615,10 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Field getField(String name)
|
||||
throws NoSuchFieldException, SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
|
||||
Field field = getField0(name);
|
||||
if (field == null) {
|
||||
throw new NoSuchFieldException(name);
|
||||
@ -1710,12 +1698,10 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Method getMethod(String name, Class<?>... parameterTypes)
|
||||
throws NoSuchMethodException, SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
|
||||
Method method = getMethod0(name, parameterTypes);
|
||||
if (method == null) {
|
||||
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
|
||||
@ -1764,12 +1750,10 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Constructor<T> getConstructor(Class<?>... parameterTypes)
|
||||
throws NoSuchMethodException, SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
|
||||
return getConstructor0(parameterTypes, Member.PUBLIC);
|
||||
}
|
||||
|
||||
@ -1807,11 +1791,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Class<?>[] getDeclaredClasses() throws SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
|
||||
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
|
||||
return getDeclaredClasses0();
|
||||
}
|
||||
|
||||
@ -1851,11 +1833,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Field[] getDeclaredFields() throws SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
|
||||
return copyFields(privateGetDeclaredFields(false));
|
||||
}
|
||||
|
||||
@ -1899,11 +1879,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Method[] getDeclaredMethods() throws SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
|
||||
return copyMethods(privateGetDeclaredMethods(false));
|
||||
}
|
||||
|
||||
@ -1944,11 +1922,9 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
|
||||
return copyConstructors(privateGetDeclaredConstructors(false));
|
||||
}
|
||||
|
||||
@ -1987,12 +1963,10 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Field getDeclaredField(String name)
|
||||
throws NoSuchFieldException, SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
|
||||
Field field = searchFields(privateGetDeclaredFields(false), name);
|
||||
if (field == null) {
|
||||
throw new NoSuchFieldException(name);
|
||||
@ -2042,12 +2016,10 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
|
||||
throws NoSuchMethodException, SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
|
||||
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
|
||||
if (method == null) {
|
||||
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
|
||||
@ -2092,12 +2064,10 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
|
||||
throws NoSuchMethodException, SecurityException {
|
||||
// be very careful not to change the stack depth of this
|
||||
// checkMemberAccess call for security reasons
|
||||
// see java.lang.SecurityManager.checkMemberAccess
|
||||
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
|
||||
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
|
||||
return getConstructor0(parameterTypes, Member.DECLARED);
|
||||
}
|
||||
|
||||
@ -2255,23 +2225,40 @@ public final class Class<T> implements java.io.Serializable,
|
||||
*/
|
||||
static native Class<?> getPrimitiveClass(String name);
|
||||
|
||||
private static boolean isCheckMemberAccessOverridden(SecurityManager smgr) {
|
||||
if (smgr.getClass() == SecurityManager.class) return false;
|
||||
|
||||
Class<?>[] paramTypes = new Class<?>[] {Class.class, int.class};
|
||||
return smgr.getClass().getMethod0("checkMemberAccess", paramTypes).
|
||||
getDeclaringClass() != SecurityManager.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if client is allowed to access members. If access is denied,
|
||||
* throw a SecurityException.
|
||||
*
|
||||
* Be very careful not to change the stack depth of this checkMemberAccess
|
||||
* call for security reasons.
|
||||
* See java.lang.SecurityManager.checkMemberAccess.
|
||||
*
|
||||
* <p> Default policy: allow all clients access with normal Java access
|
||||
* control.
|
||||
*/
|
||||
private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
|
||||
SecurityManager s = System.getSecurityManager();
|
||||
private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
|
||||
final SecurityManager s = System.getSecurityManager();
|
||||
if (s != null) {
|
||||
final ClassLoader ccl = ClassLoader.getClassLoader(caller);
|
||||
final ClassLoader cl = getClassLoader0();
|
||||
if (!isCheckMemberAccessOverridden(s)) {
|
||||
// Inlined SecurityManager.checkMemberAccess
|
||||
if (which != Member.PUBLIC) {
|
||||
if (ccl != cl) {
|
||||
s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Don't refactor; otherwise break the stack depth for
|
||||
// checkMemberAccess of subclasses of SecurityManager as specified.
|
||||
s.checkMemberAccess(this, which);
|
||||
ClassLoader cl = getClassLoader0();
|
||||
}
|
||||
|
||||
|
||||
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
|
||||
String name = this.getName();
|
||||
int i = name.lastIndexOf('.');
|
||||
|
@ -55,6 +55,7 @@ import sun.misc.CompoundEnumeration;
|
||||
import sun.misc.Resource;
|
||||
import sun.misc.URLClassPath;
|
||||
import sun.misc.VM;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
@ -1159,11 +1160,6 @@ public abstract class ClassLoader {
|
||||
return java.util.Collections.emptyEnumeration();
|
||||
}
|
||||
|
||||
// index 0: java.lang.ClassLoader.class
|
||||
// index 1: the immediate caller of index 0.
|
||||
// index 2: the immediate caller of index 1.
|
||||
private static native Class<? extends ClassLoader> getCaller(int index);
|
||||
|
||||
/**
|
||||
* Registers the caller as parallel capable.</p>
|
||||
* The registration succeeds if and only if all of the following
|
||||
@ -1179,8 +1175,11 @@ public abstract class ClassLoader {
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
@CallerSensitive
|
||||
protected static boolean registerAsParallelCapable() {
|
||||
return ParallelLoaders.register(getCaller(1));
|
||||
Class<? extends ClassLoader> callerClass =
|
||||
Reflection.getCallerClass().asSubclass(ClassLoader.class);
|
||||
return ParallelLoaders.register(callerClass);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1340,15 +1339,13 @@ public abstract class ClassLoader {
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
@CallerSensitive
|
||||
public final ClassLoader getParent() {
|
||||
if (parent == null)
|
||||
return null;
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
ClassLoader ccl = getCallerClassLoader();
|
||||
if (needsClassLoaderPermissionCheck(ccl, this)) {
|
||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||
}
|
||||
checkClassLoaderPermission(this, Reflection.getCallerClass());
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
@ -1408,6 +1405,7 @@ public abstract class ClassLoader {
|
||||
*
|
||||
* @revised 1.4
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static ClassLoader getSystemClassLoader() {
|
||||
initSystemClassLoader();
|
||||
if (scl == null) {
|
||||
@ -1415,10 +1413,7 @@ public abstract class ClassLoader {
|
||||
}
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
ClassLoader ccl = getCallerClassLoader();
|
||||
if (needsClassLoaderPermissionCheck(ccl, scl)) {
|
||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||
}
|
||||
checkClassLoaderPermission(scl, Reflection.getCallerClass());
|
||||
}
|
||||
return scl;
|
||||
}
|
||||
@ -1471,7 +1466,7 @@ public abstract class ClassLoader {
|
||||
// class loader 'from' is same as class loader 'to' or an ancestor
|
||||
// of 'to'. The class loader in a system domain can access
|
||||
// any class loader.
|
||||
static boolean needsClassLoaderPermissionCheck(ClassLoader from,
|
||||
private static boolean needsClassLoaderPermissionCheck(ClassLoader from,
|
||||
ClassLoader to)
|
||||
{
|
||||
if (from == to)
|
||||
@ -1483,13 +1478,8 @@ public abstract class ClassLoader {
|
||||
return !to.isAncestor(from);
|
||||
}
|
||||
|
||||
// Returns the invoker's class loader, or null if none.
|
||||
// NOTE: This must always be invoked when there is exactly one intervening
|
||||
// frame from the core libraries on the stack between this method's
|
||||
// invocation and the desired invoker.
|
||||
static ClassLoader getCallerClassLoader() {
|
||||
// NOTE use of more generic Reflection.getCallerClass()
|
||||
Class<?> caller = Reflection.getCallerClass(3);
|
||||
// Returns the class's class loader, or null if none.
|
||||
static ClassLoader getClassLoader(Class<?> caller) {
|
||||
// This can be null if the VM is requesting it
|
||||
if (caller == null) {
|
||||
return null;
|
||||
@ -1498,6 +1488,17 @@ public abstract class ClassLoader {
|
||||
return caller.getClassLoader0();
|
||||
}
|
||||
|
||||
static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
// caller can be null if the VM is requesting it
|
||||
ClassLoader ccl = getClassLoader(caller);
|
||||
if (needsClassLoaderPermissionCheck(ccl, cl)) {
|
||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The class loader for the system
|
||||
// @GuardedBy("ClassLoader.class")
|
||||
private static ClassLoader scl;
|
||||
|
@ -49,6 +49,8 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import sun.net.www.ParseUtil;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
@ -273,8 +275,9 @@ public class Package implements java.lang.reflect.AnnotatedElement {
|
||||
* @return the package of the requested name. It may be null if no package
|
||||
* information is available from the archive or codebase.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Package getPackage(String name) {
|
||||
ClassLoader l = ClassLoader.getCallerClassLoader();
|
||||
ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
|
||||
if (l != null) {
|
||||
return l.getPackage(name);
|
||||
} else {
|
||||
@ -294,8 +297,9 @@ public class Package implements java.lang.reflect.AnnotatedElement {
|
||||
* @return a new array of packages known to the callers {@code ClassLoader}
|
||||
* instance. An zero length array is returned if none are known.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Package[] getPackages() {
|
||||
ClassLoader l = ClassLoader.getCallerClassLoader();
|
||||
ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
|
||||
if (l != null) {
|
||||
return l.getPackages();
|
||||
} else {
|
||||
|
@ -30,6 +30,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -1024,13 +1025,24 @@ public final class ProcessBuilder
|
||||
redirects,
|
||||
redirectErrorStream);
|
||||
} catch (IOException e) {
|
||||
String exceptionInfo = ": " + e.getMessage();
|
||||
Throwable cause = e;
|
||||
if (security != null) {
|
||||
// Can not disclose the fail reason for read-protected files.
|
||||
try {
|
||||
security.checkRead(prog);
|
||||
} catch (AccessControlException ace) {
|
||||
exceptionInfo = "";
|
||||
cause = ace;
|
||||
}
|
||||
}
|
||||
// It's much easier for us to create a high-quality error
|
||||
// message than the low-level C code which found the problem.
|
||||
throw new IOException(
|
||||
"Cannot run program \"" + prog + "\""
|
||||
+ (dir == null ? "" : " (in directory \"" + dir + "\")")
|
||||
+ ": " + e.getMessage(),
|
||||
e);
|
||||
+ exceptionInfo,
|
||||
cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ package java.lang;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.StringTokenizer;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
/**
|
||||
* Every Java application has a single instance of class
|
||||
@ -790,8 +792,9 @@ public class Runtime {
|
||||
* @see java.lang.SecurityException
|
||||
* @see java.lang.SecurityManager#checkLink(java.lang.String)
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void load(String filename) {
|
||||
load0(System.getCallerClass(), filename);
|
||||
load0(Reflection.getCallerClass(), filename);
|
||||
}
|
||||
|
||||
synchronized void load0(Class<?> fromClass, String filename) {
|
||||
@ -850,8 +853,9 @@ public class Runtime {
|
||||
* @see java.lang.SecurityException
|
||||
* @see java.lang.SecurityManager#checkLink(java.lang.String)
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void loadLibrary(String libname) {
|
||||
loadLibrary0(System.getCallerClass(), libname);
|
||||
loadLibrary0(Reflection.getCallerClass(), libname);
|
||||
}
|
||||
|
||||
synchronized void loadLibrary0(Class<?> fromClass, String libname) {
|
||||
|
@ -36,10 +36,10 @@ import java.net.SocketPermission;
|
||||
import java.net.NetPermission;
|
||||
import java.util.Hashtable;
|
||||
import java.net.InetAddress;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.*;
|
||||
import java.net.URL;
|
||||
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
@ -1679,6 +1679,7 @@ class SecurityManager {
|
||||
* @since JDK1.1
|
||||
* @see #checkPermission(java.security.Permission) checkPermission
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void checkMemberAccess(Class<?> clazz, int which) {
|
||||
if (clazz == null) {
|
||||
throw new NullPointerException("class can't be null");
|
||||
|
@ -35,6 +35,7 @@ import java.security.AllPermission;
|
||||
import java.nio.channels.Channel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import sun.nio.ch.Interruptible;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.security.util.SecurityConstants;
|
||||
import sun.reflect.annotation.AnnotationType;
|
||||
@ -1072,8 +1073,9 @@ public final class System {
|
||||
* @see java.lang.Runtime#load(java.lang.String)
|
||||
* @see java.lang.SecurityManager#checkLink(java.lang.String)
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static void load(String filename) {
|
||||
Runtime.getRuntime().load0(getCallerClass(), filename);
|
||||
Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1107,8 +1109,9 @@ public final class System {
|
||||
* @see java.lang.Runtime#loadLibrary(java.lang.String)
|
||||
* @see java.lang.SecurityManager#checkLink(java.lang.String)
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static void loadLibrary(String libname) {
|
||||
Runtime.getRuntime().loadLibrary0(getCallerClass(), libname);
|
||||
Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1245,10 +1248,4 @@ public final class System {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* returns the class of the caller. */
|
||||
static Class<?> getCallerClass() {
|
||||
// NOTE use of more generic Reflection.getCallerClass()
|
||||
return Reflection.getCallerClass(3);
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import sun.nio.ch.Interruptible;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
|
||||
@ -1443,15 +1445,14 @@ class Thread implements Runnable {
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
@CallerSensitive
|
||||
public ClassLoader getContextClassLoader() {
|
||||
if (contextClassLoader == null)
|
||||
return null;
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
ClassLoader ccl = ClassLoader.getCallerClassLoader();
|
||||
if (ClassLoader.needsClassLoaderPermissionCheck(ccl, contextClassLoader)) {
|
||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||
}
|
||||
ClassLoader.checkClassLoaderPermission(contextClassLoader,
|
||||
Reflection.getCallerClass());
|
||||
}
|
||||
return contextClassLoader;
|
||||
}
|
||||
|
@ -709,7 +709,9 @@ import jdk.internal.org.objectweb.asm.Type;
|
||||
InvokerBytecodeGenerator.maybeDump(className, classFile);
|
||||
Class<? extends BoundMethodHandle> bmhClass =
|
||||
//UNSAFE.defineAnonymousClass(BoundMethodHandle.class, classFile, null).asSubclass(BoundMethodHandle.class);
|
||||
UNSAFE.defineClass(className, classFile, 0, classFile.length).asSubclass(BoundMethodHandle.class);
|
||||
UNSAFE.defineClass(className, classFile, 0, classFile.length,
|
||||
BoundMethodHandle.class.getClassLoader(), null)
|
||||
.asSubclass(BoundMethodHandle.class);
|
||||
UNSAFE.ensureClassInitialized(bmhClass);
|
||||
|
||||
return bmhClass;
|
||||
|
@ -394,7 +394,8 @@ import java.util.Objects;
|
||||
IS_METHOD = MN_IS_METHOD, // method (not constructor)
|
||||
IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
|
||||
IS_FIELD = MN_IS_FIELD, // field
|
||||
IS_TYPE = MN_IS_TYPE; // nested type
|
||||
IS_TYPE = MN_IS_TYPE, // nested type
|
||||
CALLER_SENSITIVE = MN_CALLER_SENSITIVE; // @CallerSensitive annotation detected
|
||||
|
||||
static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
|
||||
static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
|
||||
@ -430,6 +431,10 @@ import java.util.Objects;
|
||||
public boolean isPackage() {
|
||||
return !testAnyFlags(ALL_ACCESS);
|
||||
}
|
||||
/** Query whether this member has a CallerSensitive annotation. */
|
||||
public boolean isCallerSensitive() {
|
||||
return testAllFlags(CALLER_SENSITIVE);
|
||||
}
|
||||
|
||||
/** Utility method to query whether this member is accessible from a given lookup class. */
|
||||
public boolean isAccessibleFrom(Class<?> lookupClass) {
|
||||
|
@ -34,6 +34,8 @@ import sun.invoke.empty.Empty;
|
||||
import sun.invoke.util.ValueConversions;
|
||||
import sun.invoke.util.VerifyType;
|
||||
import sun.invoke.util.Wrapper;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import static java.lang.invoke.LambdaForm.*;
|
||||
import static java.lang.invoke.MethodHandleStatics.*;
|
||||
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
@ -891,9 +893,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
}
|
||||
}
|
||||
|
||||
@CallerSensitive
|
||||
private static boolean checkCallerClass(Class<?> expected, Class<?> expected2) {
|
||||
final int FRAME_COUNT_ARG = 2; // [0] Reflection [1] BindCaller [2] Expected
|
||||
Class<?> actual = sun.reflect.Reflection.getCallerClass(FRAME_COUNT_ARG);
|
||||
// This method is called via MH_checkCallerClass and so it's
|
||||
// correct to ask for the immediate caller here.
|
||||
Class<?> actual = Reflection.getCallerClass();
|
||||
if (actual != expected && actual != expected2)
|
||||
throw new InternalError("found "+actual.getName()+", expected "+expected.getName()
|
||||
+(expected == expected2 ? "" : ", or else "+expected2.getName()));
|
||||
|
@ -26,7 +26,6 @@
|
||||
package java.lang.invoke;
|
||||
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Field;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
||||
import static java.lang.invoke.MethodHandleStatics.*;
|
||||
@ -34,7 +33,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
|
||||
/**
|
||||
* The JVM interface for the method handles package is all here.
|
||||
* This is an interface internal and private to an implemetantion of JSR 292.
|
||||
* This is an interface internal and private to an implementation of JSR 292.
|
||||
* <em>This class is not part of the JSR 292 standard.</em>
|
||||
* @author jrose
|
||||
*/
|
||||
@ -101,6 +100,7 @@ class MethodHandleNatives {
|
||||
MN_IS_CONSTRUCTOR = 0x00020000, // constructor
|
||||
MN_IS_FIELD = 0x00040000, // field
|
||||
MN_IS_TYPE = 0x00080000, // nested type
|
||||
MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected
|
||||
MN_REFERENCE_KIND_SHIFT = 24, // refKind
|
||||
MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
|
||||
// The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
|
||||
@ -391,129 +391,24 @@ class MethodHandleNatives {
|
||||
* I.e., does it call Reflection.getCallerClass or a similer method
|
||||
* to ask about the identity of its caller?
|
||||
*/
|
||||
// FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive.
|
||||
static boolean isCallerSensitive(MemberName mem) {
|
||||
if (!mem.isInvocable()) return false; // fields are not caller sensitive
|
||||
|
||||
return mem.isCallerSensitive() || canBeCalledVirtual(mem);
|
||||
}
|
||||
|
||||
static boolean canBeCalledVirtual(MemberName mem) {
|
||||
assert(mem.isInvocable());
|
||||
Class<?> defc = mem.getDeclaringClass();
|
||||
switch (mem.getName()) {
|
||||
case "doPrivileged":
|
||||
case "doPrivilegedWithCombiner":
|
||||
return defc == java.security.AccessController.class;
|
||||
case "checkMemberAccess":
|
||||
return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
|
||||
case "getUnsafe":
|
||||
return defc == sun.misc.Unsafe.class;
|
||||
case "lookup":
|
||||
return defc == java.lang.invoke.MethodHandles.class;
|
||||
case "findStatic":
|
||||
case "findVirtual":
|
||||
case "findConstructor":
|
||||
case "findSpecial":
|
||||
case "findGetter":
|
||||
case "findSetter":
|
||||
case "findStaticGetter":
|
||||
case "findStaticSetter":
|
||||
case "bind":
|
||||
case "unreflect":
|
||||
case "unreflectSpecial":
|
||||
case "unreflectConstructor":
|
||||
case "unreflectGetter":
|
||||
case "unreflectSetter":
|
||||
return defc == java.lang.invoke.MethodHandles.Lookup.class;
|
||||
case "invoke":
|
||||
return defc == java.lang.reflect.Method.class;
|
||||
case "get":
|
||||
case "getBoolean":
|
||||
case "getByte":
|
||||
case "getChar":
|
||||
case "getShort":
|
||||
case "getInt":
|
||||
case "getLong":
|
||||
case "getFloat":
|
||||
case "getDouble":
|
||||
case "set":
|
||||
case "setBoolean":
|
||||
case "setByte":
|
||||
case "setChar":
|
||||
case "setShort":
|
||||
case "setInt":
|
||||
case "setLong":
|
||||
case "setFloat":
|
||||
case "setDouble":
|
||||
return defc == java.lang.reflect.Field.class;
|
||||
case "newInstance":
|
||||
if (defc == java.lang.reflect.Constructor.class) return true;
|
||||
if (defc == java.lang.Class.class) return true;
|
||||
break;
|
||||
case "forName":
|
||||
case "getClassLoader":
|
||||
case "getClasses":
|
||||
case "getFields":
|
||||
case "getMethods":
|
||||
case "getConstructors":
|
||||
case "getDeclaredClasses":
|
||||
case "getDeclaredFields":
|
||||
case "getDeclaredMethods":
|
||||
case "getDeclaredConstructors":
|
||||
case "getField":
|
||||
case "getMethod":
|
||||
case "getConstructor":
|
||||
case "getDeclaredField":
|
||||
case "getDeclaredMethod":
|
||||
case "getDeclaredConstructor":
|
||||
return defc == java.lang.Class.class;
|
||||
case "getConnection":
|
||||
case "getDriver":
|
||||
case "getDrivers":
|
||||
case "deregisterDriver":
|
||||
return defc == getClass("java.sql.DriverManager");
|
||||
case "newUpdater":
|
||||
if (defc == java.util.concurrent.atomic.AtomicIntegerFieldUpdater.class) return true;
|
||||
if (defc == java.util.concurrent.atomic.AtomicLongFieldUpdater.class) return true;
|
||||
if (defc == java.util.concurrent.atomic.AtomicReferenceFieldUpdater.class) return true;
|
||||
break;
|
||||
case "getContextClassLoader":
|
||||
return canBeCalledVirtual(mem, java.lang.Thread.class);
|
||||
case "getPackage":
|
||||
case "getPackages":
|
||||
return defc == java.lang.Package.class;
|
||||
case "getParent":
|
||||
case "getSystemClassLoader":
|
||||
return defc == java.lang.ClassLoader.class;
|
||||
case "load":
|
||||
case "loadLibrary":
|
||||
if (defc == java.lang.Runtime.class) return true;
|
||||
if (defc == java.lang.System.class) return true;
|
||||
break;
|
||||
case "getCallerClass":
|
||||
if (defc == sun.reflect.Reflection.class) return true;
|
||||
if (defc == java.lang.System.class) return true;
|
||||
break;
|
||||
case "getCallerClassLoader":
|
||||
return defc == java.lang.ClassLoader.class;
|
||||
case "registerAsParallelCapable":
|
||||
return canBeCalledVirtual(mem, java.lang.ClassLoader.class);
|
||||
case "getProxyClass":
|
||||
case "newProxyInstance":
|
||||
return defc == java.lang.reflect.Proxy.class;
|
||||
case "asInterfaceInstance":
|
||||
return defc == java.lang.invoke.MethodHandleProxies.class;
|
||||
case "getBundle":
|
||||
case "clearCache":
|
||||
return defc == java.util.ResourceBundle.class;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// avoid static dependency to a class in other modules
|
||||
private static Class<?> getClass(String cn) {
|
||||
try {
|
||||
return Class.forName(cn, false,
|
||||
MethodHandleNatives.class.getClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
|
||||
Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
|
||||
if (symbolicRefClass == definingClass) return true;
|
||||
|
@ -30,6 +30,7 @@ import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import sun.invoke.WrapperInstance;
|
||||
import java.util.ArrayList;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
@ -137,14 +138,14 @@ public class MethodHandleProxies {
|
||||
// entry points, must be covered by hand-written or automatically
|
||||
// generated adapter classes.
|
||||
//
|
||||
@CallerSensitive
|
||||
public static
|
||||
<T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
|
||||
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
|
||||
throw new IllegalArgumentException("not a public interface: "+intfc.getName());
|
||||
final MethodHandle mh;
|
||||
if (System.getSecurityManager() != null) {
|
||||
final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
|
||||
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
|
||||
final Class<?> caller = Reflection.getCallerClass();
|
||||
final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
|
||||
ReflectUtil.checkProxyPackageAccess(ccl, intfc);
|
||||
mh = ccl != null ? bindCaller(target, caller) : target;
|
||||
|
@ -26,13 +26,17 @@
|
||||
package java.lang.invoke;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import sun.invoke.util.ValueConversions;
|
||||
import sun.invoke.util.VerifyAccess;
|
||||
import sun.invoke.util.Wrapper;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import sun.invoke.util.ValueConversions;
|
||||
import sun.invoke.util.VerifyAccess;
|
||||
import sun.invoke.util.Wrapper;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.security.util.SecurityConstants;
|
||||
import static java.lang.invoke.MethodHandleStatics.*;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
||||
|
||||
@ -65,8 +69,9 @@ public class MethodHandles {
|
||||
* This lookup object is a <em>capability</em> which may be delegated to trusted agents.
|
||||
* Do not store it in place where untrusted code can access it.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Lookup lookup() {
|
||||
return new Lookup();
|
||||
return new Lookup(Reflection.getCallerClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -416,18 +421,11 @@ public class MethodHandles {
|
||||
* for method handle creation.
|
||||
* Must be called by from a method in this package,
|
||||
* which in turn is called by a method not in this package.
|
||||
* <p>
|
||||
* Also, don't make it private, lest javac interpose
|
||||
* an access$N method.
|
||||
*/
|
||||
Lookup() {
|
||||
this(getCallerClassAtEntryPoint(false), ALL_MODES);
|
||||
// make sure we haven't accidentally picked up a privileged class:
|
||||
checkUnprivilegedlookupClass(lookupClass);
|
||||
}
|
||||
|
||||
Lookup(Class<?> lookupClass) {
|
||||
this(lookupClass, ALL_MODES);
|
||||
// make sure we haven't accidentally picked up a privileged class:
|
||||
checkUnprivilegedlookupClass(lookupClass);
|
||||
}
|
||||
|
||||
private Lookup(Class<?> lookupClass, int allowedModes) {
|
||||
@ -554,20 +552,6 @@ public class MethodHandles {
|
||||
}
|
||||
}
|
||||
|
||||
/* Obtain the external caller class, when called from Lookup.<init> or a first-level subroutine. */
|
||||
private static Class<?> getCallerClassAtEntryPoint(boolean inSubroutine) {
|
||||
final int CALLER_DEPTH = 4;
|
||||
// Stack for the constructor entry point (inSubroutine=false):
|
||||
// 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
|
||||
// 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
|
||||
// The stack is slightly different for a subroutine of a Lookup.find* method:
|
||||
// 2: Lookup.*, 3: Lookup.find*.*, 4: caller
|
||||
// Note: This should be the only use of getCallerClass in this file.
|
||||
assert(Reflection.getCallerClass(CALLER_DEPTH-2) == Lookup.class);
|
||||
assert(Reflection.getCallerClass(CALLER_DEPTH-1) == (inSubroutine ? Lookup.class : MethodHandles.class));
|
||||
return Reflection.getCallerClass(CALLER_DEPTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a method handle for a static method.
|
||||
* The type of the method handle will be that of the method.
|
||||
@ -594,12 +578,14 @@ public class MethodHandles {
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public
|
||||
MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
|
||||
MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
|
||||
checkSecurityManager(refc, method); // stack walk magic: do not refactor
|
||||
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
|
||||
return getDirectMethod(REF_invokeStatic, refc, method, callerClass);
|
||||
Class<?> callerClass = Reflection.getCallerClass();
|
||||
checkSecurityManager(refc, method, callerClass);
|
||||
return getDirectMethod(REF_invokeStatic, refc, method,
|
||||
findBoundCallerClass(method, callerClass));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -645,6 +631,7 @@ public class MethodHandles {
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
|
||||
if (refc == MethodHandle.class) {
|
||||
MethodHandle mh = findVirtualForMH(name, type);
|
||||
@ -652,9 +639,10 @@ public class MethodHandles {
|
||||
}
|
||||
byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
|
||||
MemberName method = resolveOrFail(refKind, refc, name, type);
|
||||
checkSecurityManager(refc, method); // stack walk magic: do not refactor
|
||||
Class<?> callerClass = findBoundCallerClass(method);
|
||||
return getDirectMethod(refKind, refc, method, callerClass);
|
||||
Class<?> callerClass = Reflection.getCallerClass();
|
||||
checkSecurityManager(refc, method, callerClass);
|
||||
return getDirectMethod(refKind, refc, method,
|
||||
findBoundCallerClass(method, callerClass));
|
||||
}
|
||||
private MethodHandle findVirtualForMH(String name, MethodType type) {
|
||||
// these names require special lookups because of the implicit MethodType argument
|
||||
@ -691,10 +679,11 @@ public class MethodHandles {
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
|
||||
String name = "<init>";
|
||||
MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
|
||||
checkSecurityManager(refc, ctor); // stack walk magic: do not refactor
|
||||
checkSecurityManager(refc, ctor, Reflection.getCallerClass());
|
||||
return getDirectConstructor(refc, ctor);
|
||||
}
|
||||
|
||||
@ -732,14 +721,16 @@ public class MethodHandles {
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
|
||||
Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
|
||||
checkSpecialCaller(specialCaller);
|
||||
Lookup specialLookup = this.in(specialCaller);
|
||||
MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
|
||||
checkSecurityManager(refc, method); // stack walk magic: do not refactor
|
||||
Class<?> callerClass = findBoundCallerClass(method);
|
||||
return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, callerClass);
|
||||
Class<?> callerClass = Reflection.getCallerClass();
|
||||
checkSecurityManager(refc, method, callerClass);
|
||||
return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method,
|
||||
findBoundCallerClass(method, callerClass));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -759,9 +750,10 @@ public class MethodHandles {
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
|
||||
MemberName field = resolveOrFail(REF_getField, refc, name, type);
|
||||
checkSecurityManager(refc, field); // stack walk magic: do not refactor
|
||||
checkSecurityManager(refc, field, Reflection.getCallerClass());
|
||||
return getDirectField(REF_getField, refc, field);
|
||||
}
|
||||
|
||||
@ -782,9 +774,10 @@ public class MethodHandles {
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
|
||||
MemberName field = resolveOrFail(REF_putField, refc, name, type);
|
||||
checkSecurityManager(refc, field); // stack walk magic: do not refactor
|
||||
checkSecurityManager(refc, field, Reflection.getCallerClass());
|
||||
return getDirectField(REF_putField, refc, field);
|
||||
}
|
||||
|
||||
@ -804,9 +797,10 @@ public class MethodHandles {
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
|
||||
MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
|
||||
checkSecurityManager(refc, field); // stack walk magic: do not refactor
|
||||
checkSecurityManager(refc, field, Reflection.getCallerClass());
|
||||
return getDirectField(REF_getStatic, refc, field);
|
||||
}
|
||||
|
||||
@ -826,9 +820,10 @@ public class MethodHandles {
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
|
||||
MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
|
||||
checkSecurityManager(refc, field); // stack walk magic: do not refactor
|
||||
checkSecurityManager(refc, field, Reflection.getCallerClass());
|
||||
return getDirectField(REF_putStatic, refc, field);
|
||||
}
|
||||
|
||||
@ -878,12 +873,14 @@ return mh1;
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
|
||||
Class<? extends Object> refc = receiver.getClass(); // may get NPE
|
||||
MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
|
||||
checkSecurityManager(refc, method); // stack walk magic: do not refactor
|
||||
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
|
||||
MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, callerClass);
|
||||
Class<?> callerClass = Reflection.getCallerClass();
|
||||
checkSecurityManager(refc, method, callerClass);
|
||||
MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method,
|
||||
findBoundCallerClass(method, callerClass));
|
||||
return mh.bindReceiver(receiver).setVarargs(method);
|
||||
}
|
||||
|
||||
@ -908,13 +905,14 @@ return mh1;
|
||||
* is set and {@code asVarargsCollector} fails
|
||||
* @throws NullPointerException if the argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle unreflect(Method m) throws IllegalAccessException {
|
||||
MemberName method = new MemberName(m);
|
||||
byte refKind = method.getReferenceKind();
|
||||
if (refKind == REF_invokeSpecial)
|
||||
refKind = REF_invokeVirtual;
|
||||
assert(method.isMethod());
|
||||
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
|
||||
Class<?> callerClass = findBoundCallerClass(method, Reflection.getCallerClass());
|
||||
Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
|
||||
return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, callerClass);
|
||||
}
|
||||
@ -940,12 +938,13 @@ return mh1;
|
||||
* is set and {@code asVarargsCollector} fails
|
||||
* @throws NullPointerException if any argument is null
|
||||
*/
|
||||
@CallerSensitive
|
||||
public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
|
||||
checkSpecialCaller(specialCaller);
|
||||
Lookup specialLookup = this.in(specialCaller);
|
||||
MemberName method = new MemberName(m, true);
|
||||
assert(method.isMethod());
|
||||
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
|
||||
Class<?> callerClass = findBoundCallerClass(method, Reflection.getCallerClass());
|
||||
// ignore m.isAccessible: this is a new kind of access
|
||||
return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, callerClass);
|
||||
}
|
||||
@ -1050,20 +1049,35 @@ return mh1;
|
||||
* If this lookup object has private access, then the caller class is the lookupClass.
|
||||
* Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
|
||||
* This is the same caller class as is used by checkSecurityManager.
|
||||
* This function performs stack walk magic: do not refactor it.
|
||||
*/
|
||||
Class<?> findBoundCallerClass(MemberName m) {
|
||||
Class<?> findBoundCallerClass(MemberName m, Class<?> callerAtEntryPoint) {
|
||||
Class<?> callerClass = null;
|
||||
if (MethodHandleNatives.isCallerSensitive(m)) {
|
||||
// Do not refactor this to a more "logical" place, since it is stack walk magic.
|
||||
// Note that this is the same expression as in Step 2 below in checkSecurityManager.
|
||||
callerClass = ((allowedModes & PRIVATE) != 0
|
||||
? lookupClass // for strong access modes, no extra check
|
||||
// next line does stack walk magic; do not refactor:
|
||||
: getCallerClassAtEntryPoint(true));
|
||||
: callerAtEntryPoint);
|
||||
}
|
||||
return callerClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a security manager has an overridden
|
||||
* SecurityManager.checkMemberAccess method.
|
||||
*/
|
||||
private boolean isCheckMemberAccessOverridden(SecurityManager sm) {
|
||||
final Class<? extends SecurityManager> cls = sm.getClass();
|
||||
if (cls == SecurityManager.class) return false;
|
||||
|
||||
try {
|
||||
return cls.getMethod("checkMemberAccess", Class.class, int.class).
|
||||
getDeclaringClass() != SecurityManager.class;
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new InternalError("should not reach here");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
|
||||
* Determines a trustable caller class to compare with refc, the symbolic reference class.
|
||||
@ -1071,46 +1085,55 @@ return mh1;
|
||||
* Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
|
||||
* This function performs stack walk magic: do not refactor it.
|
||||
*/
|
||||
void checkSecurityManager(Class<?> refc, MemberName m) {
|
||||
void checkSecurityManager(Class<?> refc, MemberName m, Class<?> caller) {
|
||||
SecurityManager smgr = System.getSecurityManager();
|
||||
if (smgr == null) return;
|
||||
if (allowedModes == TRUSTED) return;
|
||||
|
||||
final boolean overridden = isCheckMemberAccessOverridden(smgr);
|
||||
// Step 1:
|
||||
smgr.checkMemberAccess(refc, Member.PUBLIC);
|
||||
{
|
||||
// Default policy is to allow Member.PUBLIC; no need to check
|
||||
// permission if SecurityManager is the default implementation
|
||||
final int which = Member.PUBLIC;
|
||||
final Class<?> clazz = refc;
|
||||
if (overridden) {
|
||||
// Don't refactor; otherwise break the stack depth for
|
||||
// checkMemberAccess of subclasses of SecurityManager as specified.
|
||||
smgr.checkMemberAccess(clazz, which);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2:
|
||||
Class<?> callerClass = ((allowedModes & PRIVATE) != 0
|
||||
? lookupClass // for strong access modes, no extra check
|
||||
// next line does stack walk magic; do not refactor:
|
||||
: getCallerClassAtEntryPoint(true));
|
||||
: caller);
|
||||
if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) ||
|
||||
(callerClass != lookupClass &&
|
||||
!VerifyAccess.classLoaderIsAncestor(callerClass, refc)))
|
||||
smgr.checkPackageAccess(VerifyAccess.getPackageName(refc));
|
||||
|
||||
// Step 3:
|
||||
if (m.isPublic()) return;
|
||||
Class<?> defc = m.getDeclaringClass();
|
||||
smgr.checkMemberAccess(defc, Member.DECLARED); // STACK WALK HERE
|
||||
{
|
||||
// Inline SecurityManager.checkMemberAccess
|
||||
final int which = Member.DECLARED;
|
||||
final Class<?> clazz = defc;
|
||||
if (!overridden) {
|
||||
if (caller.getClassLoader() != clazz.getClassLoader()) {
|
||||
smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
|
||||
}
|
||||
} else {
|
||||
// Don't refactor; otherwise break the stack depth for
|
||||
// checkMemberAccess of subclasses of SecurityManager as specified.
|
||||
smgr.checkMemberAccess(clazz, which);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4:
|
||||
if (defc != refc)
|
||||
smgr.checkPackageAccess(VerifyAccess.getPackageName(defc));
|
||||
|
||||
// Comment from SM.checkMemberAccess, where which=DECLARED:
|
||||
/*
|
||||
* stack depth of 4 should be the caller of one of the
|
||||
* methods in java.lang.Class that invoke checkMember
|
||||
* access. The stack should look like:
|
||||
*
|
||||
* someCaller [3]
|
||||
* java.lang.Class.someReflectionAPI [2]
|
||||
* java.lang.Class.checkMemberAccess [1]
|
||||
* SecurityManager.checkMemberAccess [0]
|
||||
*
|
||||
*/
|
||||
// For us it is this stack:
|
||||
// someCaller [3]
|
||||
// Lookup.findSomeMember [2]
|
||||
// Lookup.checkSecurityManager [1]
|
||||
// SecurityManager.checkMemberAccess [0]
|
||||
}
|
||||
|
||||
void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
|
||||
@ -1237,6 +1260,30 @@ return mh1;
|
||||
checkMethod(refKind, refc, method);
|
||||
if (method.isMethodHandleInvoke())
|
||||
return fakeMethodHandleInvoke(method);
|
||||
|
||||
Class<?> refcAsSuper;
|
||||
if (refKind == REF_invokeSpecial &&
|
||||
refc != lookupClass() &&
|
||||
refc != (refcAsSuper = lookupClass().getSuperclass()) &&
|
||||
refc.isAssignableFrom(lookupClass())) {
|
||||
assert(!method.getName().equals("<init>")); // not this code path
|
||||
// Per JVMS 6.5, desc. of invokespecial instruction:
|
||||
// If the method is in a superclass of the LC,
|
||||
// and if our original search was above LC.super,
|
||||
// repeat the search (symbolic lookup) from LC.super.
|
||||
// FIXME: MemberName.resolve should handle this instead.
|
||||
MemberName m2 = new MemberName(refcAsSuper,
|
||||
method.getName(),
|
||||
method.getMethodType(),
|
||||
REF_invokeSpecial);
|
||||
m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
|
||||
if (m2 == null) throw new InternalError(method.toString());
|
||||
method = m2;
|
||||
refc = refcAsSuper;
|
||||
// redo basic checks
|
||||
checkMethod(refKind, refc, method);
|
||||
}
|
||||
|
||||
MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
|
||||
mh = maybeBindCaller(method, mh, callerClass);
|
||||
mh = mh.setVarargs(method);
|
||||
|
@ -38,9 +38,9 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
|
||||
*/
|
||||
static native void invokeFinalizeMethod(Object o) throws Throwable;
|
||||
|
||||
static private ReferenceQueue queue = new ReferenceQueue();
|
||||
static private Finalizer unfinalized = null;
|
||||
static private Object lock = new Object();
|
||||
private static ReferenceQueue queue = new ReferenceQueue();
|
||||
private static Finalizer unfinalized = null;
|
||||
private static final Object lock = new Object();
|
||||
|
||||
private Finalizer
|
||||
next = null,
|
||||
@ -142,7 +142,11 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
|
||||
/* Called by Runtime.runFinalization() */
|
||||
static void runFinalization() {
|
||||
forkSecondaryFinalizer(new Runnable() {
|
||||
private volatile boolean running;
|
||||
public void run() {
|
||||
if (running)
|
||||
return;
|
||||
running = true;
|
||||
for (;;) {
|
||||
Finalizer f = (Finalizer)queue.poll();
|
||||
if (f == null) break;
|
||||
@ -155,7 +159,11 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
|
||||
/* Invoked by java.lang.Shutdown */
|
||||
static void runAllFinalizers() {
|
||||
forkSecondaryFinalizer(new Runnable() {
|
||||
private volatile boolean running;
|
||||
public void run() {
|
||||
if (running)
|
||||
return;
|
||||
running = true;
|
||||
for (;;) {
|
||||
Finalizer f;
|
||||
synchronized (lock) {
|
||||
@ -168,10 +176,14 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
|
||||
}
|
||||
|
||||
private static class FinalizerThread extends Thread {
|
||||
private volatile boolean running;
|
||||
FinalizerThread(ThreadGroup g) {
|
||||
super(g, "Finalizer");
|
||||
}
|
||||
public void run() {
|
||||
if (running)
|
||||
return;
|
||||
running = true;
|
||||
for (;;) {
|
||||
try {
|
||||
Finalizer f = (Finalizer)queue.remove();
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.ConstructorAccessor;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.generics.repository.ConstructorRepository;
|
||||
@ -392,14 +393,14 @@ public final class Constructor<T> extends Executable {
|
||||
* @exception ExceptionInInitializerError if the initialization provoked
|
||||
* by this method fails.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public T newInstance(Object ... initargs)
|
||||
throws InstantiationException, IllegalAccessException,
|
||||
IllegalArgumentException, InvocationTargetException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass(2);
|
||||
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, null, modifiers);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.FieldAccessor;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.generics.repository.FieldRepository;
|
||||
@ -376,9 +377,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* @exception ExceptionInInitializerError if the initialization provoked
|
||||
* by this method fails.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Object get(Object obj)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
return getFieldAccessor(obj).get(obj);
|
||||
}
|
||||
|
||||
@ -404,9 +412,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#get
|
||||
*/
|
||||
@CallerSensitive
|
||||
public boolean getBoolean(Object obj)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
return getFieldAccessor(obj).getBoolean(obj);
|
||||
}
|
||||
|
||||
@ -432,9 +447,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#get
|
||||
*/
|
||||
@CallerSensitive
|
||||
public byte getByte(Object obj)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
return getFieldAccessor(obj).getByte(obj);
|
||||
}
|
||||
|
||||
@ -462,9 +484,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#get
|
||||
*/
|
||||
@CallerSensitive
|
||||
public char getChar(Object obj)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
return getFieldAccessor(obj).getChar(obj);
|
||||
}
|
||||
|
||||
@ -492,9 +521,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#get
|
||||
*/
|
||||
@CallerSensitive
|
||||
public short getShort(Object obj)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
return getFieldAccessor(obj).getShort(obj);
|
||||
}
|
||||
|
||||
@ -522,9 +558,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#get
|
||||
*/
|
||||
@CallerSensitive
|
||||
public int getInt(Object obj)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
return getFieldAccessor(obj).getInt(obj);
|
||||
}
|
||||
|
||||
@ -552,9 +595,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#get
|
||||
*/
|
||||
@CallerSensitive
|
||||
public long getLong(Object obj)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
return getFieldAccessor(obj).getLong(obj);
|
||||
}
|
||||
|
||||
@ -582,9 +632,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#get
|
||||
*/
|
||||
@CallerSensitive
|
||||
public float getFloat(Object obj)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
return getFieldAccessor(obj).getFloat(obj);
|
||||
}
|
||||
|
||||
@ -612,9 +669,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#get
|
||||
*/
|
||||
@CallerSensitive
|
||||
public double getDouble(Object obj)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
return getFieldAccessor(obj).getDouble(obj);
|
||||
}
|
||||
|
||||
@ -684,9 +748,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* @exception ExceptionInInitializerError if the initialization provoked
|
||||
* by this method fails.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void set(Object obj, Object value)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
getFieldAccessor(obj).set(obj, value);
|
||||
}
|
||||
|
||||
@ -714,9 +785,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#set
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void setBoolean(Object obj, boolean z)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
getFieldAccessor(obj).setBoolean(obj, z);
|
||||
}
|
||||
|
||||
@ -744,9 +822,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#set
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void setByte(Object obj, byte b)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
getFieldAccessor(obj).setByte(obj, b);
|
||||
}
|
||||
|
||||
@ -774,9 +859,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#set
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void setChar(Object obj, char c)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
getFieldAccessor(obj).setChar(obj, c);
|
||||
}
|
||||
|
||||
@ -804,9 +896,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#set
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void setShort(Object obj, short s)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
getFieldAccessor(obj).setShort(obj, s);
|
||||
}
|
||||
|
||||
@ -834,9 +933,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#set
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void setInt(Object obj, int i)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
getFieldAccessor(obj).setInt(obj, i);
|
||||
}
|
||||
|
||||
@ -864,9 +970,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#set
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void setLong(Object obj, long l)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
getFieldAccessor(obj).setLong(obj, l);
|
||||
}
|
||||
|
||||
@ -894,9 +1007,16 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#set
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void setFloat(Object obj, float f)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
getFieldAccessor(obj).setFloat(obj, f);
|
||||
}
|
||||
|
||||
@ -924,17 +1044,23 @@ class Field extends AccessibleObject implements Member {
|
||||
* by this method fails.
|
||||
* @see Field#set
|
||||
*/
|
||||
@CallerSensitive
|
||||
public void setDouble(Object obj, double d)
|
||||
throws IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
getFieldAccessor(obj).setDouble(obj, d);
|
||||
}
|
||||
|
||||
// Convenience routine which performs security checks
|
||||
// security check is done before calling this method
|
||||
private FieldAccessor getFieldAccessor(Object obj)
|
||||
throws IllegalAccessException
|
||||
{
|
||||
doSecurityCheck(obj);
|
||||
boolean ov = override;
|
||||
FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor;
|
||||
return (a != null) ? a : acquireFieldAccessor(ov);
|
||||
@ -982,19 +1108,6 @@ class Field extends AccessibleObject implements Member {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: be very careful if you change the stack depth of this
|
||||
// routine. The depth of the "getCallerClass" call is hardwired so
|
||||
// that the compiler can have an easier time if this gets inlined.
|
||||
private void doSecurityCheck(Object obj) throws IllegalAccessException {
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass(4);
|
||||
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @since 1.5
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.MethodAccessor;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.generics.repository.MethodRepository;
|
||||
@ -472,14 +473,14 @@ public final class Method extends Executable {
|
||||
* @exception ExceptionInInitializerError if the initialization
|
||||
* provoked by this method fails.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Object invoke(Object obj, Object... args)
|
||||
throws IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass(1);
|
||||
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,8 @@ import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.WeakHashMap;
|
||||
import sun.misc.ProxyGenerator;
|
||||
import sun.misc.VM;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
import sun.security.util.SecurityConstants;
|
||||
@ -408,28 +410,21 @@ public class Proxy implements java.io.Serializable {
|
||||
* @throws NullPointerException if the {@code interfaces} array
|
||||
* argument or any of its elements are {@code null}
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Class<?> getProxyClass(ClassLoader loader,
|
||||
Class<?>... interfaces)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
|
||||
}
|
||||
|
||||
private static void checkProxyLoader(ClassLoader ccl,
|
||||
ClassLoader loader)
|
||||
{
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
if (loader == null && ccl != null) {
|
||||
if (!ProxyAccessHelper.allowNullLoader) {
|
||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||
}
|
||||
}
|
||||
checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
|
||||
}
|
||||
|
||||
return getProxyClass0(loader, interfaces);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a proxy class (caller-sensitive).
|
||||
* Check permissions required to create a Proxy class.
|
||||
*
|
||||
* To define a proxy class, it performs the access checks as in
|
||||
* Class.forName (VM will invoke ClassLoader.checkPackageAccess):
|
||||
@ -446,17 +441,28 @@ public class Proxy implements java.io.Serializable {
|
||||
* will throw IllegalAccessError when the generated proxy class is
|
||||
* being defined via the defineClass0 method.
|
||||
*/
|
||||
private static Class<?> getProxyClass0(ClassLoader loader,
|
||||
Class<?>... interfaces) {
|
||||
private static void checkProxyAccess(Class<?> caller,
|
||||
ClassLoader loader,
|
||||
Class<?>... interfaces)
|
||||
{
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller
|
||||
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
|
||||
final ClassLoader ccl = caller.getClassLoader();
|
||||
checkProxyLoader(ccl, loader);
|
||||
ClassLoader ccl = caller.getClassLoader();
|
||||
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
|
||||
if (!ProxyAccessHelper.allowNullLoader) {
|
||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||
}
|
||||
}
|
||||
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a proxy class. Must call the checkProxyAccess method
|
||||
* to perform permission checks before calling this.
|
||||
*/
|
||||
private static Class<?> getProxyClass0(ClassLoader loader,
|
||||
Class<?>... interfaces) {
|
||||
if (interfaces.length > 65535) {
|
||||
throw new IllegalArgumentException("interface limit exceeded");
|
||||
}
|
||||
@ -698,6 +704,7 @@ public class Proxy implements java.io.Serializable {
|
||||
* if the invocation handler, {@code h}, is
|
||||
* {@code null}
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Object newProxyInstance(ClassLoader loader,
|
||||
Class<?>[] interfaces,
|
||||
InvocationHandler h)
|
||||
@ -707,10 +714,15 @@ public class Proxy implements java.io.Serializable {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up or generate the designated proxy class.
|
||||
*/
|
||||
Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
|
||||
Class<?> cl = getProxyClass0(loader, interfaces);
|
||||
|
||||
/*
|
||||
* Invoke its constructor with the designated invocation handler.
|
||||
@ -718,7 +730,6 @@ public class Proxy implements java.io.Serializable {
|
||||
try {
|
||||
final Constructor<?> cons = cl.getConstructor(constructorParams);
|
||||
final InvocationHandler ih = h;
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
|
||||
// create proxy instance with doPrivilege as the proxy class may
|
||||
// implement non-public interfaces that requires a special permission
|
||||
|
@ -122,7 +122,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
* not connected already.
|
||||
*/
|
||||
protected void disconnect() {
|
||||
disconnect0(connectedAddress.family);
|
||||
disconnect0(connectedAddress.holder().getFamily());
|
||||
connected = false;
|
||||
connectedAddress = null;
|
||||
connectedPort = -1;
|
||||
|
@ -100,27 +100,28 @@ class Inet4Address extends InetAddress {
|
||||
|
||||
Inet4Address() {
|
||||
super();
|
||||
hostName = null;
|
||||
address = 0;
|
||||
family = IPv4;
|
||||
holder().hostName = null;
|
||||
holder().address = 0;
|
||||
holder().family = IPv4;
|
||||
}
|
||||
|
||||
Inet4Address(String hostName, byte addr[]) {
|
||||
this.hostName = hostName;
|
||||
this.family = IPv4;
|
||||
holder().hostName = hostName;
|
||||
holder().family = IPv4;
|
||||
if (addr != null) {
|
||||
if (addr.length == INADDRSZ) {
|
||||
address = addr[3] & 0xFF;
|
||||
int address = addr[3] & 0xFF;
|
||||
address |= ((addr[2] << 8) & 0xFF00);
|
||||
address |= ((addr[1] << 16) & 0xFF0000);
|
||||
address |= ((addr[0] << 24) & 0xFF000000);
|
||||
holder().address = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
Inet4Address(String hostName, int address) {
|
||||
this.hostName = hostName;
|
||||
this.family = IPv4;
|
||||
this.address = address;
|
||||
holder().hostName = hostName;
|
||||
holder().family = IPv4;
|
||||
holder().address = address;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,8 +135,8 @@ class Inet4Address extends InetAddress {
|
||||
private Object writeReplace() throws ObjectStreamException {
|
||||
// will replace the to be serialized 'this' object
|
||||
InetAddress inet = new InetAddress();
|
||||
inet.hostName = this.hostName;
|
||||
inet.address = this.address;
|
||||
inet.holder().hostName = holder().getHostName();
|
||||
inet.holder().address = holder().getAddress();
|
||||
|
||||
/**
|
||||
* Prior to 1.4 an InetAddress was created with a family
|
||||
@ -143,7 +144,7 @@ class Inet4Address extends InetAddress {
|
||||
* For compatibility reasons we must therefore write the
|
||||
* the InetAddress with this family.
|
||||
*/
|
||||
inet.family = 2;
|
||||
inet.holder().family = 2;
|
||||
|
||||
return inet;
|
||||
}
|
||||
@ -157,7 +158,7 @@ class Inet4Address extends InetAddress {
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public boolean isMulticastAddress() {
|
||||
return ((address & 0xf0000000) == 0xe0000000);
|
||||
return ((holder().getAddress() & 0xf0000000) == 0xe0000000);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,7 +168,7 @@ class Inet4Address extends InetAddress {
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isAnyLocalAddress() {
|
||||
return address == 0;
|
||||
return holder().getAddress() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,6 +196,7 @@ class Inet4Address extends InetAddress {
|
||||
// defined in "Documenting Special Use IPv4 Address Blocks
|
||||
// that have been Registered with IANA" by Bill Manning
|
||||
// draft-manning-dsua-06.txt
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 169)
|
||||
&& (((address >>> 16) & 0xFF) == 254);
|
||||
}
|
||||
@ -211,6 +213,7 @@ class Inet4Address extends InetAddress {
|
||||
// 10/8 prefix
|
||||
// 172.16/12 prefix
|
||||
// 192.168/16 prefix
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 10)
|
||||
|| ((((address >>> 24) & 0xFF) == 172)
|
||||
&& (((address >>> 16) & 0xF0) == 16))
|
||||
@ -257,6 +260,7 @@ class Inet4Address extends InetAddress {
|
||||
*/
|
||||
public boolean isMCLinkLocal() {
|
||||
// 224.0.0/24 prefix and ttl == 1
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 224)
|
||||
&& (((address >>> 16) & 0xFF) == 0)
|
||||
&& (((address >>> 8) & 0xFF) == 0);
|
||||
@ -272,6 +276,7 @@ class Inet4Address extends InetAddress {
|
||||
*/
|
||||
public boolean isMCSiteLocal() {
|
||||
// 239.255/16 prefix or ttl < 32
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 239)
|
||||
&& (((address >>> 16) & 0xFF) == 255);
|
||||
}
|
||||
@ -287,6 +292,7 @@ class Inet4Address extends InetAddress {
|
||||
*/
|
||||
public boolean isMCOrgLocal() {
|
||||
// 239.192 - 239.195
|
||||
int address = holder().getAddress();
|
||||
return (((address >>> 24) & 0xFF) == 239)
|
||||
&& (((address >>> 16) & 0xFF) >= 192)
|
||||
&& (((address >>> 16) & 0xFF) <= 195);
|
||||
@ -300,6 +306,7 @@ class Inet4Address extends InetAddress {
|
||||
* @return the raw IP address of this object.
|
||||
*/
|
||||
public byte[] getAddress() {
|
||||
int address = holder().getAddress();
|
||||
byte[] addr = new byte[INADDRSZ];
|
||||
|
||||
addr[0] = (byte) ((address >>> 24) & 0xFF);
|
||||
@ -325,7 +332,7 @@ class Inet4Address extends InetAddress {
|
||||
* @return a hash code value for this IP address.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return address;
|
||||
return holder().getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -346,7 +353,7 @@ class Inet4Address extends InetAddress {
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return (obj != null) && (obj instanceof Inet4Address) &&
|
||||
(((InetAddress)obj).address == address);
|
||||
(((InetAddress)obj).holder().getAddress() == holder().getAddress());
|
||||
}
|
||||
|
||||
// Utilities
|
||||
|
@ -40,7 +40,7 @@ class Inet4AddressImpl implements InetAddressImpl {
|
||||
public synchronized InetAddress anyLocalAddress() {
|
||||
if (anyLocalAddress == null) {
|
||||
anyLocalAddress = new Inet4Address(); // {0x00,0x00,0x00,0x00}
|
||||
anyLocalAddress.hostName = "0.0.0.0";
|
||||
anyLocalAddress.holder().hostName = "0.0.0.0";
|
||||
}
|
||||
return anyLocalAddress;
|
||||
}
|
||||
|
@ -210,18 +210,18 @@ class Inet6Address extends InetAddress {
|
||||
|
||||
Inet6Address() {
|
||||
super();
|
||||
hostName = null;
|
||||
holder().hostName = null;
|
||||
ipaddress = new byte[INADDRSZ];
|
||||
family = IPv6;
|
||||
holder().family = IPv6;
|
||||
}
|
||||
|
||||
/* checking of value for scope_id should be done by caller
|
||||
* scope_id must be >= 0, or -1 to indicate not being set
|
||||
*/
|
||||
Inet6Address(String hostName, byte addr[], int scope_id) {
|
||||
this.hostName = hostName;
|
||||
holder().hostName = hostName;
|
||||
if (addr.length == INADDRSZ) { // normal IPv6 address
|
||||
family = IPv6;
|
||||
holder().family = IPv6;
|
||||
ipaddress = addr.clone();
|
||||
}
|
||||
if (scope_id >= 0) {
|
||||
@ -335,9 +335,9 @@ class Inet6Address extends InetAddress {
|
||||
private void initif(String hostName, byte addr[],NetworkInterface nif)
|
||||
throws UnknownHostException
|
||||
{
|
||||
this.hostName = hostName;
|
||||
holder().hostName = hostName;
|
||||
if (addr.length == INADDRSZ) { // normal IPv6 address
|
||||
family = IPv6;
|
||||
holder().family = IPv6;
|
||||
ipaddress = addr.clone();
|
||||
}
|
||||
if (nif != null) {
|
||||
@ -420,6 +420,11 @@ class Inet6Address extends InetAddress {
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
if (getClass().getClassLoader() != null) {
|
||||
throw new SecurityException ("invalid address type");
|
||||
}
|
||||
|
||||
s.defaultReadObject();
|
||||
|
||||
if (ifname != null && !ifname.equals("")) {
|
||||
@ -447,7 +452,7 @@ class Inet6Address extends InetAddress {
|
||||
ipaddress.length);
|
||||
}
|
||||
|
||||
if (family != IPv6) {
|
||||
if (holder().getFamily() != IPv6) {
|
||||
throw new InvalidObjectException("invalid address family type");
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ class Inet6AddressImpl implements InetAddressImpl {
|
||||
if (anyLocalAddress == null) {
|
||||
if (InetAddress.preferIPv6Address) {
|
||||
anyLocalAddress = new Inet6Address();
|
||||
anyLocalAddress.hostName = "::";
|
||||
anyLocalAddress.holder().hostName = "::";
|
||||
} else {
|
||||
anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress();
|
||||
}
|
||||
|
@ -35,8 +35,12 @@ import java.util.ArrayList;
|
||||
import java.util.ServiceLoader;
|
||||
import java.security.AccessController;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectInputStream.GetField;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectOutputStream.PutField;
|
||||
import sun.security.action.*;
|
||||
import sun.net.InetAddressCachePolicy;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
@ -199,26 +203,49 @@ class InetAddress implements java.io.Serializable {
|
||||
/* Specify address family preference */
|
||||
static transient boolean preferIPv6Address = false;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
static class InetAddressHolder {
|
||||
|
||||
InetAddressHolder() {}
|
||||
|
||||
InetAddressHolder(String hostName, int address, int family) {
|
||||
this.hostName = hostName;
|
||||
this.address = address;
|
||||
this.family = family;
|
||||
}
|
||||
|
||||
String hostName;
|
||||
|
||||
String getHostName() {
|
||||
return hostName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds a 32-bit IPv4 address.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
int address;
|
||||
|
||||
int getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the address family type, for instance, '1' for IPv4
|
||||
* addresses, and '2' for IPv6 addresses.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
int family;
|
||||
|
||||
int getFamily() {
|
||||
return family;
|
||||
}
|
||||
}
|
||||
|
||||
/* Used to store the serializable fields of InetAddress */
|
||||
private final transient InetAddressHolder holder;
|
||||
|
||||
InetAddressHolder holder() {
|
||||
return holder;
|
||||
}
|
||||
|
||||
/* Used to store the name service provider */
|
||||
private static List<NameService> nameServices = null;
|
||||
|
||||
@ -251,6 +278,7 @@ class InetAddress implements java.io.Serializable {
|
||||
* put in the address cache, since it is not created by name.
|
||||
*/
|
||||
InetAddress() {
|
||||
holder = new InetAddressHolder();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -263,7 +291,7 @@ class InetAddress implements java.io.Serializable {
|
||||
*/
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
// will replace the deserialized 'this' object
|
||||
return new Inet4Address(this.hostName, this.address);
|
||||
return new Inet4Address(holder().getHostName(), holder().getAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -500,10 +528,10 @@ class InetAddress implements java.io.Serializable {
|
||||
* @see SecurityManager#checkConnect
|
||||
*/
|
||||
String getHostName(boolean check) {
|
||||
if (hostName == null) {
|
||||
hostName = InetAddress.getHostFromNameService(this, check);
|
||||
if (holder().getHostName() == null) {
|
||||
holder().hostName = InetAddress.getHostFromNameService(this, check);
|
||||
}
|
||||
return hostName;
|
||||
return holder().getHostName();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -666,6 +694,7 @@ class InetAddress implements java.io.Serializable {
|
||||
* @return a string representation of this IP address.
|
||||
*/
|
||||
public String toString() {
|
||||
String hostName = holder().getHostName();
|
||||
return ((hostName != null) ? hostName : "")
|
||||
+ "/" + getHostAddress();
|
||||
}
|
||||
@ -1522,14 +1551,58 @@ class InetAddress implements java.io.Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
private static final long FIELDS_OFFSET;
|
||||
private static final sun.misc.Unsafe UNSAFE;
|
||||
|
||||
static {
|
||||
try {
|
||||
sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
|
||||
FIELDS_OFFSET = unsafe.objectFieldOffset(
|
||||
InetAddress.class.getDeclaredField("holder")
|
||||
);
|
||||
UNSAFE = unsafe;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void readObject (ObjectInputStream s) throws
|
||||
IOException, ClassNotFoundException {
|
||||
s.defaultReadObject ();
|
||||
if (getClass().getClassLoader() != null) {
|
||||
hostName = null;
|
||||
address = 0;
|
||||
throw new SecurityException ("invalid address type");
|
||||
}
|
||||
GetField gf = s.readFields();
|
||||
String host = (String)gf.get("hostName", null);
|
||||
int address= gf.get("address", 0);
|
||||
int family= gf.get("family", 0);
|
||||
InetAddressHolder h = new InetAddressHolder(host, address, family);
|
||||
UNSAFE.putObject(this, FIELDS_OFFSET, h);
|
||||
}
|
||||
|
||||
/* needed because the serializable fields no longer exist */
|
||||
|
||||
/**
|
||||
* @serialField hostName String
|
||||
* @serialField address int
|
||||
* @serialField family int
|
||||
*/
|
||||
private static final ObjectStreamField[] serialPersistentFields = {
|
||||
new ObjectStreamField("hostName", String.class),
|
||||
new ObjectStreamField("address", int.class),
|
||||
new ObjectStreamField("family", int.class),
|
||||
};
|
||||
|
||||
private void writeObject (ObjectOutputStream s) throws
|
||||
IOException {
|
||||
if (getClass().getClassLoader() != null) {
|
||||
throw new SecurityException ("invalid address type");
|
||||
}
|
||||
PutField pf = s.putFields();
|
||||
pf.put("hostName", holder().getHostName());
|
||||
pf.put("address", holder().getAddress());
|
||||
pf.put("family", holder().getFamily());
|
||||
s.writeFields();
|
||||
s.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,8 +87,8 @@ public class InetSocketAddress
|
||||
if (hostname != null)
|
||||
return hostname;
|
||||
if (addr != null) {
|
||||
if (addr.hostName != null)
|
||||
return addr.hostName;
|
||||
if (addr.holder().getHostName() != null)
|
||||
return addr.holder().getHostName();
|
||||
else
|
||||
return addr.getHostAddress();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2013, 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
|
||||
@ -120,6 +120,13 @@ public class LogStream extends PrintStream {
|
||||
*/
|
||||
@Deprecated
|
||||
public static synchronized void setDefaultStream(PrintStream newDefault) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
|
||||
if (sm != null) {
|
||||
sm.checkPermission(
|
||||
new java.util.logging.LoggingPermission("control", null));
|
||||
}
|
||||
|
||||
defaultStream = newDefault;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
||||
package java.security;
|
||||
|
||||
import sun.security.util.Debug;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
/**
|
||||
* <p> The AccessController class is used for access control operations
|
||||
@ -264,6 +266,7 @@ public final class AccessController {
|
||||
* @see java.security.DomainCombiner
|
||||
*/
|
||||
|
||||
@CallerSensitive
|
||||
public static native <T> T doPrivileged(PrivilegedAction<T> action);
|
||||
|
||||
/**
|
||||
@ -288,14 +291,15 @@ public final class AccessController {
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
|
||||
|
||||
AccessControlContext acc = getStackAccessControlContext();
|
||||
if (acc == null) {
|
||||
return AccessController.doPrivileged(action);
|
||||
}
|
||||
DomainCombiner dc = acc.getAssignedCombiner();
|
||||
return AccessController.doPrivileged(action, preserveCombiner(dc));
|
||||
return AccessController.doPrivileged(action,
|
||||
preserveCombiner(dc, Reflection.getCallerClass()));
|
||||
}
|
||||
|
||||
|
||||
@ -326,6 +330,7 @@ public final class AccessController {
|
||||
* @see #doPrivileged(PrivilegedAction)
|
||||
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static native <T> T doPrivileged(PrivilegedAction<T> action,
|
||||
AccessControlContext context);
|
||||
|
||||
@ -353,6 +358,7 @@ public final class AccessController {
|
||||
* @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
|
||||
* @see java.security.DomainCombiner
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static native <T> T
|
||||
doPrivileged(PrivilegedExceptionAction<T> action)
|
||||
throws PrivilegedActionException;
|
||||
@ -383,34 +389,29 @@ public final class AccessController {
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static <T> T doPrivilegedWithCombiner
|
||||
(PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
|
||||
|
||||
@CallerSensitive
|
||||
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)
|
||||
throws PrivilegedActionException
|
||||
{
|
||||
AccessControlContext acc = getStackAccessControlContext();
|
||||
if (acc == null) {
|
||||
return AccessController.doPrivileged(action);
|
||||
}
|
||||
DomainCombiner dc = acc.getAssignedCombiner();
|
||||
return AccessController.doPrivileged(action, preserveCombiner(dc));
|
||||
return AccessController.doPrivileged(action,
|
||||
preserveCombiner(dc, Reflection.getCallerClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
* preserve the combiner across the doPrivileged call
|
||||
*/
|
||||
private static AccessControlContext preserveCombiner
|
||||
(DomainCombiner combiner) {
|
||||
|
||||
/**
|
||||
* callerClass[0] = Reflection.getCallerClass
|
||||
* callerClass[1] = AccessController.preserveCombiner
|
||||
* callerClass[2] = AccessController.doPrivileged
|
||||
* callerClass[3] = caller
|
||||
*/
|
||||
final Class<?> callerClass = sun.reflect.Reflection.getCallerClass(3);
|
||||
private static AccessControlContext preserveCombiner(DomainCombiner combiner,
|
||||
Class<?> caller)
|
||||
{
|
||||
ProtectionDomain callerPd = doPrivileged
|
||||
(new PrivilegedAction<ProtectionDomain>() {
|
||||
public ProtectionDomain run() {
|
||||
return callerClass.getProtectionDomain();
|
||||
return caller.getProtectionDomain();
|
||||
}
|
||||
});
|
||||
|
||||
@ -455,6 +456,7 @@ public final class AccessController {
|
||||
* @see #doPrivileged(PrivilegedAction)
|
||||
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static native <T> T
|
||||
doPrivileged(PrivilegedExceptionAction<T> action,
|
||||
AccessControlContext context)
|
||||
|
@ -30,6 +30,7 @@ import java.util.ServiceLoader;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
|
||||
@ -192,14 +193,11 @@ public class DriverManager {
|
||||
* has been exceeded and has at least tried to cancel the
|
||||
* current database connection attempt
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Connection getConnection(String url,
|
||||
java.util.Properties info) throws SQLException {
|
||||
|
||||
// Gets the classloader of the code that called this method, may
|
||||
// be null.
|
||||
ClassLoader callerCL = DriverManager.getCallerClassLoader();
|
||||
|
||||
return (getConnection(url, info, callerCL));
|
||||
return (getConnection(url, info, Reflection.getCallerClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,14 +224,11 @@ public class DriverManager {
|
||||
* has been exceeded and has at least tried to cancel the
|
||||
* current database connection attempt
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Connection getConnection(String url,
|
||||
String user, String password) throws SQLException {
|
||||
java.util.Properties info = new java.util.Properties();
|
||||
|
||||
// Gets the classloader of the code that called this method, may
|
||||
// be null.
|
||||
ClassLoader callerCL = DriverManager.getCallerClassLoader();
|
||||
|
||||
if (user != null) {
|
||||
info.put("user", user);
|
||||
}
|
||||
@ -241,7 +236,7 @@ public class DriverManager {
|
||||
info.put("password", password);
|
||||
}
|
||||
|
||||
return (getConnection(url, info, callerCL));
|
||||
return (getConnection(url, info, Reflection.getCallerClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,16 +254,12 @@ public class DriverManager {
|
||||
* has been exceeded and has at least tried to cancel the
|
||||
* current database connection attempt
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Connection getConnection(String url)
|
||||
throws SQLException {
|
||||
|
||||
java.util.Properties info = new java.util.Properties();
|
||||
|
||||
// Gets the classloader of the code that called this method, may
|
||||
// be null.
|
||||
ClassLoader callerCL = DriverManager.getCallerClassLoader();
|
||||
|
||||
return (getConnection(url, info, callerCL));
|
||||
return (getConnection(url, info, Reflection.getCallerClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -282,21 +273,20 @@ public class DriverManager {
|
||||
* that can connect to the given URL
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Driver getDriver(String url)
|
||||
throws SQLException {
|
||||
|
||||
println("DriverManager.getDriver(\"" + url + "\")");
|
||||
|
||||
// Gets the classloader of the code that called this method, may
|
||||
// be null.
|
||||
ClassLoader callerCL = DriverManager.getCallerClassLoader();
|
||||
Class<?> callerClass = Reflection.getCallerClass();
|
||||
|
||||
// Walk through the loaded registeredDrivers attempting to locate someone
|
||||
// who understands the given URL.
|
||||
for (DriverInfo aDriver : registeredDrivers) {
|
||||
// If the caller does not have permission to load the driver then
|
||||
// skip it.
|
||||
if(isDriverAllowed(aDriver.driver, callerCL)) {
|
||||
if(isDriverAllowed(aDriver.driver, callerClass)) {
|
||||
try {
|
||||
if(aDriver.driver.acceptsURL(url)) {
|
||||
// Success!
|
||||
@ -350,20 +340,18 @@ public class DriverManager {
|
||||
* @param driver the JDBC Driver to drop
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static synchronized void deregisterDriver(Driver driver)
|
||||
throws SQLException {
|
||||
if (driver == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Gets the classloader of the code that called this method,
|
||||
// may be null.
|
||||
ClassLoader callerCL = DriverManager.getCallerClassLoader();
|
||||
println("DriverManager.deregisterDriver: " + driver);
|
||||
|
||||
DriverInfo aDriver = new DriverInfo(driver);
|
||||
if(registeredDrivers.contains(aDriver)) {
|
||||
if (isDriverAllowed(driver, callerCL)) {
|
||||
if (isDriverAllowed(driver, Reflection.getCallerClass())) {
|
||||
registeredDrivers.remove(aDriver);
|
||||
} else {
|
||||
// If the caller does not have permission to load the driver then
|
||||
@ -384,18 +372,17 @@ public class DriverManager {
|
||||
*
|
||||
* @return the list of JDBC Drivers loaded by the caller's class loader
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static java.util.Enumeration<Driver> getDrivers() {
|
||||
java.util.Vector<Driver> result = new java.util.Vector<>();
|
||||
|
||||
// Gets the classloader of the code that called this method, may
|
||||
// be null.
|
||||
ClassLoader callerCL = DriverManager.getCallerClassLoader();
|
||||
Class<?> callerClass = Reflection.getCallerClass();
|
||||
|
||||
// Walk through the loaded registeredDrivers.
|
||||
for(DriverInfo aDriver : registeredDrivers) {
|
||||
// If the caller does not have permission to load the driver then
|
||||
// skip it.
|
||||
if(isDriverAllowed(aDriver.driver, callerCL)) {
|
||||
if(isDriverAllowed(aDriver.driver, callerClass)) {
|
||||
result.addElement(aDriver.driver);
|
||||
} else {
|
||||
println(" skipping: " + aDriver.getClass().getName());
|
||||
@ -493,17 +480,13 @@ public class DriverManager {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Internal method used to get the caller's class loader.
|
||||
// Replaces the call to the native method
|
||||
private static ClassLoader getCallerClassLoader() {
|
||||
Class<?> cc = Reflection.getCallerClass(3);
|
||||
ClassLoader cl = (cc != null) ? cc.getClassLoader() : null;
|
||||
return cl;
|
||||
}
|
||||
|
||||
|
||||
// Indicates whether the class object that would be created if the code calling
|
||||
// DriverManager is accessible.
|
||||
private static boolean isDriverAllowed(Driver driver, Class<?> caller) {
|
||||
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
|
||||
return isDriverAllowed(driver, callerCL);
|
||||
}
|
||||
|
||||
private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
|
||||
boolean result = false;
|
||||
if(driver != null) {
|
||||
@ -556,7 +539,7 @@ public class DriverManager {
|
||||
*/
|
||||
try{
|
||||
while(driversIterator.hasNext()) {
|
||||
println(" Loading done by the java.util.ServiceLoader : "+driversIterator.next());
|
||||
driversIterator.next();
|
||||
}
|
||||
} catch(Throwable t) {
|
||||
// Do nothing
|
||||
@ -586,13 +569,14 @@ public class DriverManager {
|
||||
|
||||
// Worker method called by the public getConnection() methods.
|
||||
private static Connection getConnection(
|
||||
String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {
|
||||
String url, java.util.Properties info, Class<?> caller) throws SQLException {
|
||||
/*
|
||||
* When callerCl is null, we should check the application's
|
||||
* (which is invoking this class indirectly)
|
||||
* classloader, so that the JDBC driver class outside rt.jar
|
||||
* can be loaded from here.
|
||||
*/
|
||||
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
|
||||
synchronized(DriverManager.class) {
|
||||
// synchronize loading of the correct classloader.
|
||||
if (callerCL == null) {
|
||||
|
@ -28,6 +28,9 @@ import java.io.Serializable;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* This class consists exclusively of static methods that operate on or return
|
||||
@ -264,8 +267,7 @@ public class Collections {
|
||||
}
|
||||
|
||||
private static <T>
|
||||
int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key)
|
||||
{
|
||||
int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
|
||||
int low = 0;
|
||||
int high = list.size()-1;
|
||||
|
||||
@ -441,21 +443,21 @@ public class Collections {
|
||||
/**
|
||||
* Randomly permutes the specified list using a default source of
|
||||
* randomness. All permutations occur with approximately equal
|
||||
* likelihood.<p>
|
||||
* likelihood.
|
||||
*
|
||||
* The hedge "approximately" is used in the foregoing description because
|
||||
* <p>The hedge "approximately" is used in the foregoing description because
|
||||
* default source of randomness is only approximately an unbiased source
|
||||
* of independently chosen bits. If it were a perfect source of randomly
|
||||
* chosen bits, then the algorithm would choose permutations with perfect
|
||||
* uniformity.<p>
|
||||
* uniformity.
|
||||
*
|
||||
* This implementation traverses the list backwards, from the last element
|
||||
* up to the second, repeatedly swapping a randomly selected element into
|
||||
* the "current position". Elements are randomly selected from the
|
||||
* <p>This implementation traverses the list backwards, from the last
|
||||
* element up to the second, repeatedly swapping a randomly selected element
|
||||
* into the "current position". Elements are randomly selected from the
|
||||
* portion of the list that runs from the first element to the current
|
||||
* position, inclusive.<p>
|
||||
* position, inclusive.
|
||||
*
|
||||
* This method runs in linear time. If the specified list does not
|
||||
* <p>This method runs in linear time. If the specified list does not
|
||||
* implement the {@link RandomAccess} interface and is large, this
|
||||
* implementation dumps the specified list into an array before shuffling
|
||||
* it, and dumps the shuffled array back into the list. This avoids the
|
||||
@ -469,9 +471,10 @@ public class Collections {
|
||||
public static void shuffle(List<?> list) {
|
||||
Random rnd = r;
|
||||
if (rnd == null)
|
||||
r = rnd = new Random();
|
||||
r = rnd = new Random(); // harmless race.
|
||||
shuffle(list, rnd);
|
||||
}
|
||||
|
||||
private static Random r;
|
||||
|
||||
/**
|
||||
@ -1391,6 +1394,67 @@ public class Collections {
|
||||
public int hashCode() {return m.hashCode();}
|
||||
public String toString() {return m.toString();}
|
||||
|
||||
// Override default methods in Map
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public V getOrDefault(Object k, V defaultValue) {
|
||||
// Safe cast as we don't change the value
|
||||
return ((Map<K, V>)m).getOrDefault(k, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
m.forEach(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V putIfAbsent(K key, V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replace(K key, V oldValue, V newValue) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V replace(K key, V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfPresent(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V compute(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V merge(K key, V value,
|
||||
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* We need this class in addition to UnmodifiableSet as
|
||||
* Map.Entries themselves permit modification of the backing Map
|
||||
@ -1590,9 +1654,9 @@ public class Collections {
|
||||
* </pre>
|
||||
* Failure to follow this advice may result in non-deterministic behavior.
|
||||
*
|
||||
* <p>The returned collection does <i>not</i> pass the <tt>hashCode</tt>
|
||||
* and <tt>equals</tt> operations through to the backing collection, but
|
||||
* relies on <tt>Object</tt>'s equals and hashCode methods. This is
|
||||
* <p>The returned collection does <i>not</i> pass the {@code hashCode}
|
||||
* and {@code equals} operations through to the backing collection, but
|
||||
* relies on {@code Object}'s equals and hashCode methods. This is
|
||||
* necessary to preserve the contracts of these operations in the case
|
||||
* that the backing collection is a set or a list.<p>
|
||||
*
|
||||
@ -2107,6 +2171,57 @@ public class Collections {
|
||||
public String toString() {
|
||||
synchronized (mutex) {return m.toString();}
|
||||
}
|
||||
|
||||
// Override default methods in Map
|
||||
@Override
|
||||
public V getOrDefault(Object k, V defaultValue) {
|
||||
synchronized (mutex) {return m.getOrDefault(k, defaultValue);}
|
||||
}
|
||||
@Override
|
||||
public void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
synchronized (mutex) {m.forEach(action);}
|
||||
}
|
||||
@Override
|
||||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
synchronized (mutex) {m.replaceAll(function);}
|
||||
}
|
||||
@Override
|
||||
public V putIfAbsent(K key, V value) {
|
||||
synchronized (mutex) {return m.putIfAbsent(key, value);}
|
||||
}
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
synchronized (mutex) {return m.remove(key, value);}
|
||||
}
|
||||
@Override
|
||||
public boolean replace(K key, V oldValue, V newValue) {
|
||||
synchronized (mutex) {return m.replace(key, oldValue, newValue);}
|
||||
}
|
||||
@Override
|
||||
public V replace(K key, V value) {
|
||||
synchronized (mutex) {return m.replace(key, value);}
|
||||
}
|
||||
@Override
|
||||
public V computeIfAbsent(K key,
|
||||
Function<? super K, ? extends V> mappingFunction) {
|
||||
synchronized (mutex) {return m.computeIfAbsent(key, mappingFunction);}
|
||||
}
|
||||
@Override
|
||||
public V computeIfPresent(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
synchronized (mutex) {return m.computeIfPresent(key, remappingFunction);}
|
||||
}
|
||||
@Override
|
||||
public V compute(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
synchronized (mutex) {return m.compute(key, remappingFunction);}
|
||||
}
|
||||
@Override
|
||||
public V merge(K key, V value,
|
||||
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
synchronized (mutex) {return m.merge(key, value, remappingFunction);}
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
synchronized (mutex) {s.defaultWriteObject();}
|
||||
}
|
||||
@ -2326,6 +2441,8 @@ public class Collections {
|
||||
}
|
||||
|
||||
public Iterator<E> iterator() {
|
||||
// JDK-6363904 - unwrapped iterator could be typecast to
|
||||
// ListIterator with unsafe set()
|
||||
final Iterator<E> it = c.iterator();
|
||||
return new Iterator<E>() {
|
||||
public boolean hasNext() { return it.hasNext(); }
|
||||
@ -2717,6 +2834,16 @@ public class Collections {
|
||||
throw new ClassCastException(badValueMsg(value));
|
||||
}
|
||||
|
||||
private BiFunction<? super K, ? super V, ? extends V> typeCheck(
|
||||
BiFunction<? super K, ? super V, ? extends V> func) {
|
||||
Objects.requireNonNull(func);
|
||||
return (k, v) -> {
|
||||
V newValue = func.apply(k, v);
|
||||
typeCheck(k, newValue);
|
||||
return newValue;
|
||||
};
|
||||
}
|
||||
|
||||
private String badKeyMsg(Object key) {
|
||||
return "Attempt to insert " + key.getClass() +
|
||||
" key into map with key type " + keyType;
|
||||
@ -2782,6 +2909,74 @@ public class Collections {
|
||||
return entrySet;
|
||||
}
|
||||
|
||||
// Override default methods in Map
|
||||
@Override
|
||||
public void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
m.forEach(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
m.replaceAll(typeCheck(function));
|
||||
}
|
||||
|
||||
@Override
|
||||
public V putIfAbsent(K key, V value) {
|
||||
typeCheck(key, value);
|
||||
return m.putIfAbsent(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
return m.remove(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replace(K key, V oldValue, V newValue) {
|
||||
typeCheck(key, newValue);
|
||||
return m.replace(key, oldValue, newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V replace(K key, V value) {
|
||||
typeCheck(key, value);
|
||||
return m.replace(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfAbsent(K key,
|
||||
Function<? super K, ? extends V> mappingFunction) {
|
||||
Objects.requireNonNull(mappingFunction);
|
||||
return m.computeIfAbsent(key, k -> {
|
||||
V value = mappingFunction.apply(k);
|
||||
typeCheck(k, value);
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfPresent(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
return m.computeIfPresent(key, typeCheck(remappingFunction));
|
||||
}
|
||||
|
||||
@Override
|
||||
public V compute(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
return m.compute(key, typeCheck(remappingFunction));
|
||||
}
|
||||
|
||||
@Override
|
||||
public V merge(K key, V value,
|
||||
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
Objects.requireNonNull(remappingFunction);
|
||||
return m.merge(key, value, (v1, v2) -> {
|
||||
V newValue = remappingFunction.apply(v1, v2);
|
||||
typeCheck(null, newValue);
|
||||
return newValue;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* We need this class in addition to CheckedSet as Map.Entry permits
|
||||
* modification of the backing Map via the setValue operation. This
|
||||
@ -3456,6 +3651,67 @@ public class Collections {
|
||||
|
||||
public int hashCode() {return 0;}
|
||||
|
||||
// Override default methods in Map
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public V getOrDefault(Object k, V defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
Objects.requireNonNull(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
Objects.requireNonNull(function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V putIfAbsent(K key, V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replace(K key, V oldValue, V newValue) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V replace(K key, V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfAbsent(K key,
|
||||
Function<? super K, ? extends V> mappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfPresent(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V compute(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V merge(K key, V value,
|
||||
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// Preserves singleton property
|
||||
private Object readResolve() {
|
||||
return EMPTY_MAP;
|
||||
@ -3619,6 +3875,65 @@ public class Collections {
|
||||
return values;
|
||||
}
|
||||
|
||||
// Override default methods in Map
|
||||
@Override
|
||||
public V getOrDefault(Object key, V defaultValue) {
|
||||
return eq(key, k) ? v : defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
action.accept(k, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V putIfAbsent(K key, V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replace(K key, V oldValue, V newValue) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V replace(K key, V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfAbsent(K key,
|
||||
Function<? super K, ? extends V> mappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfPresent(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V compute(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V merge(K key, V value,
|
||||
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
// Miscellaneous
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2000, 2013, 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 @@ formatVersion=1
|
||||
# Version of the currency code information in this class.
|
||||
# It is a serial number that accompanies with each amendment.
|
||||
|
||||
dataVersion=154
|
||||
dataVersion=155
|
||||
|
||||
# List of all valid ISO 4217 currency codes.
|
||||
# To ensure compatibility, do not remove codes.
|
||||
@ -585,7 +585,7 @@ ZW=ZWL
|
||||
minor0=\
|
||||
ADP-BEF-BIF-BYB-BYR-CLF-CLP-DJF-ESP-GNF-\
|
||||
GRD-ISK-ITL-JPY-KMF-KRW-LUF-MGF-PYG-PTE-RWF-\
|
||||
TPE-TRL-VND-VUV-XAF-XOF-XPF
|
||||
TPE-TRL-UGX-VND-VUV-XAF-XOF-XPF
|
||||
minor1=
|
||||
minor3=\
|
||||
BHD-IQD-JOD-KWD-LYD-OMR-TND
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, 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,11 @@
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Hash table based implementation of the <tt>Map</tt> interface. This
|
||||
@ -376,6 +380,13 @@ public class HashMap<K,V>
|
||||
return null == entry ? null : entry.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V getOrDefault(Object key, V defaultValue) {
|
||||
Entry<K,V> entry = getEntry(key);
|
||||
|
||||
return (entry == null) ? defaultValue : entry.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map contains a mapping for the
|
||||
* specified key.
|
||||
@ -603,6 +614,261 @@ public class HashMap<K,V>
|
||||
return (e == null ? null : e.value);
|
||||
}
|
||||
|
||||
// optimized implementations of default methods in Map
|
||||
|
||||
@Override
|
||||
public V putIfAbsent(K key, V value) {
|
||||
if (table == EMPTY_TABLE) {
|
||||
inflateTable(threshold);
|
||||
}
|
||||
int hash = (key == null) ? 0 : hash(key);
|
||||
int i = indexFor(hash, table.length);
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)table[i];
|
||||
for(; e != null; e = e.next) {
|
||||
if (e.hash == hash && Objects.equals(e.key, key)) {
|
||||
if(e.value != null) {
|
||||
return e.value;
|
||||
}
|
||||
e.value = value;
|
||||
modCount++;
|
||||
e.recordAccess(this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
modCount++;
|
||||
addEntry(hash, key, value, i);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
if (isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
int hash = (key == null) ? 0 : hash(key);
|
||||
int i = indexFor(hash, table.length);
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> prev = (Entry<K,V>)table[i];
|
||||
Entry<K,V> e = prev;
|
||||
|
||||
while (e != null) {
|
||||
Entry<K,V> next = e.next;
|
||||
if (e.hash == hash && Objects.equals(e.key, key)) {
|
||||
if (!Objects.equals(e.value, value)) {
|
||||
return false;
|
||||
}
|
||||
modCount++;
|
||||
size--;
|
||||
if (prev == e)
|
||||
table[i] = next;
|
||||
else
|
||||
prev.next = next;
|
||||
e.recordRemoval(this);
|
||||
return true;
|
||||
}
|
||||
prev = e;
|
||||
e = next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replace(K key, V oldValue, V newValue) {
|
||||
if (isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
int hash = (key == null) ? 0 : hash(key);
|
||||
int i = indexFor(hash, table.length);
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)table[i];
|
||||
for (; e != null; e = e.next) {
|
||||
if (e.hash == hash && Objects.equals(e.key, key) && Objects.equals(e.value, oldValue)) {
|
||||
e.value = newValue;
|
||||
e.recordAccess(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V replace(K key, V value) {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
int hash = (key == null) ? 0 : hash(key);
|
||||
int i = indexFor(hash, table.length);
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)table[i];
|
||||
for (; e != null; e = e.next) {
|
||||
if (e.hash == hash && Objects.equals(e.key, key)) {
|
||||
V oldValue = e.value;
|
||||
e.value = value;
|
||||
e.recordAccess(this);
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||
if (table == EMPTY_TABLE) {
|
||||
inflateTable(threshold);
|
||||
}
|
||||
int hash = (key == null) ? 0 : hash(key);
|
||||
int i = indexFor(hash, table.length);
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)table[i];
|
||||
for (; e != null; e = e.next) {
|
||||
if (e.hash == hash && Objects.equals(e.key, key)) {
|
||||
V oldValue = e.value;
|
||||
return oldValue == null ? (e.value = mappingFunction.apply(key)) : oldValue;
|
||||
}
|
||||
}
|
||||
|
||||
V newValue = mappingFunction.apply(key);
|
||||
if (newValue != null) {
|
||||
modCount++;
|
||||
addEntry(hash, key, newValue, i);
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
int hash = (key == null) ? 0 : hash(key);
|
||||
int i = indexFor(hash, table.length);
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> prev = (Entry<K,V>)table[i];
|
||||
Entry<K,V> e = prev;
|
||||
|
||||
while (e != null) {
|
||||
Entry<K,V> next = e.next;
|
||||
if (e.hash == hash && Objects.equals(e.key, key)) {
|
||||
V oldValue = e.value;
|
||||
if (oldValue == null)
|
||||
break;
|
||||
V newValue = remappingFunction.apply(key, oldValue);
|
||||
modCount++;
|
||||
if (newValue == null) {
|
||||
size--;
|
||||
if (prev == e)
|
||||
table[i] = next;
|
||||
else
|
||||
prev.next = next;
|
||||
e.recordRemoval(this);
|
||||
} else {
|
||||
e.value = newValue;
|
||||
e.recordAccess(this);
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
prev = e;
|
||||
e = next;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
if (table == EMPTY_TABLE) {
|
||||
inflateTable(threshold);
|
||||
}
|
||||
int hash = (key == null) ? 0 : hash(key);
|
||||
int i = indexFor(hash, table.length);
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> prev = (Entry<K,V>)table[i];
|
||||
Entry<K,V> e = prev;
|
||||
|
||||
while (e != null) {
|
||||
Entry<K,V> next = e.next;
|
||||
if (e.hash == hash && Objects.equals(e.key, key)) {
|
||||
V oldValue = e.value;
|
||||
V newValue = remappingFunction.apply(key, oldValue);
|
||||
if (newValue != oldValue) {
|
||||
modCount++;
|
||||
if (newValue == null) {
|
||||
size--;
|
||||
if (prev == e)
|
||||
table[i] = next;
|
||||
else
|
||||
prev.next = next;
|
||||
e.recordRemoval(this);
|
||||
} else {
|
||||
e.value = newValue;
|
||||
e.recordAccess(this);
|
||||
}
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
prev = e;
|
||||
e = next;
|
||||
}
|
||||
|
||||
V newValue = remappingFunction.apply(key, null);
|
||||
if (newValue != null) {
|
||||
modCount++;
|
||||
addEntry(hash, key, newValue, i);
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
if (table == EMPTY_TABLE) {
|
||||
inflateTable(threshold);
|
||||
}
|
||||
int hash = (key == null) ? 0 : hash(key);
|
||||
int i = indexFor(hash, table.length);
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> prev = (Entry<K,V>)table[i];
|
||||
Entry<K,V> e = prev;
|
||||
|
||||
while (e != null) {
|
||||
Entry<K,V> next = e.next;
|
||||
if (e.hash == hash && Objects.equals(e.key, key)) {
|
||||
V oldValue = e.value;
|
||||
V newValue = remappingFunction.apply(oldValue, value);
|
||||
modCount++;
|
||||
if (newValue == null) {
|
||||
size--;
|
||||
if (prev == e)
|
||||
table[i] = next;
|
||||
else
|
||||
prev.next = next;
|
||||
e.recordRemoval(this);
|
||||
} else {
|
||||
e.value = newValue;
|
||||
e.recordAccess(this);
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
prev = e;
|
||||
e = next;
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
modCount++;
|
||||
addEntry(hash, key, value, i);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// end of optimized implementations of default methods in Map
|
||||
|
||||
/**
|
||||
* Removes and returns the entry associated with the specified key
|
||||
* in the HashMap. Returns null if the HashMap contains no mapping
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2013, 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,11 @@
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* This class implements a hash table, which maps keys to values. Any
|
||||
@ -455,6 +459,26 @@ public class Hashtable<K,V>
|
||||
}
|
||||
}
|
||||
|
||||
private void addEntry(int hash, K key, V value, int index) {
|
||||
modCount++;
|
||||
|
||||
Entry<?,?> tab[] = table;
|
||||
if (count >= threshold) {
|
||||
// Rehash the table if the threshold is exceeded
|
||||
rehash();
|
||||
|
||||
tab = table;
|
||||
hash = hash(key);
|
||||
index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
}
|
||||
|
||||
// Creates the new entry.
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>) tab[index];
|
||||
tab[index] = new Entry<>(hash, key, value, e);
|
||||
count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the specified <code>key</code> to the specified
|
||||
* <code>value</code> in this hashtable. Neither the key nor the
|
||||
@ -492,21 +516,7 @@ public class Hashtable<K,V>
|
||||
}
|
||||
}
|
||||
|
||||
modCount++;
|
||||
if (count >= threshold) {
|
||||
// Rehash the table if the threshold is exceeded
|
||||
rehash();
|
||||
|
||||
tab = table;
|
||||
hash = hash(key);
|
||||
index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
}
|
||||
|
||||
// Creates the new entry.
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)tab[index];
|
||||
tab[index] = new Entry<>(hash, key, value, e);
|
||||
count++;
|
||||
addEntry(hash, key, value, index);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -892,6 +902,239 @@ public class Hashtable<K,V>
|
||||
return h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized V getOrDefault(Object key, V defaultValue) {
|
||||
V result = get(key);
|
||||
return (null == result) ? defaultValue : result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
Objects.requireNonNull(action); // explicit check required in case
|
||||
// table is empty.
|
||||
Entry<?,?>[] tab = table;
|
||||
for (Entry<?,?> entry : tab) {
|
||||
while (entry != null) {
|
||||
action.accept((K)entry.key, (V)entry.value);
|
||||
entry = entry.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void replaceAll(
|
||||
BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
Map.super.replaceAll(function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized V putIfAbsent(K key, V value) {
|
||||
Objects.requireNonNull(value);
|
||||
|
||||
// Makes sure the key is not already in the hashtable.
|
||||
Entry<?,?> tab[] = table;
|
||||
int hash = hash(key);
|
||||
int index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> entry = (Entry<K,V>)tab[index];
|
||||
for (; entry != null; entry = entry.next) {
|
||||
if ((entry.hash == hash) && entry.key.equals(key)) {
|
||||
V old = entry.value;
|
||||
if (old == null) {
|
||||
entry.value = value;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
}
|
||||
|
||||
addEntry(hash, key, value, index);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean remove(Object key, Object value) {
|
||||
Objects.requireNonNull(value);
|
||||
|
||||
Entry<?,?> tab[] = table;
|
||||
int hash = hash(key);
|
||||
int index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)tab[index];
|
||||
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
|
||||
if ((e.hash == hash) && e.key.equals(key) && e.value.equals(value)) {
|
||||
modCount++;
|
||||
if (prev != null) {
|
||||
prev.next = e.next;
|
||||
} else {
|
||||
tab[index] = e.next;
|
||||
}
|
||||
count--;
|
||||
e.value = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean replace(K key, V oldValue, V newValue) {
|
||||
Entry<?,?> tab[] = table;
|
||||
int hash = hash(key);
|
||||
int index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)tab[index];
|
||||
for (; e != null; e = e.next) {
|
||||
if ((e.hash == hash) && e.key.equals(key)) {
|
||||
if (e.value.equals(oldValue)) {
|
||||
e.value = newValue;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized V replace(K key, V value) {
|
||||
Entry<?,?> tab[] = table;
|
||||
int hash = hash(key);
|
||||
int index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)tab[index];
|
||||
for (; e != null; e = e.next) {
|
||||
if ((e.hash == hash) && e.key.equals(key)) {
|
||||
V oldValue = e.value;
|
||||
e.value = value;
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||
Objects.requireNonNull(mappingFunction);
|
||||
|
||||
Entry<?,?> tab[] = table;
|
||||
int hash = hash(key);
|
||||
int index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)tab[index];
|
||||
for (; e != null; e = e.next) {
|
||||
if (e.hash == hash && e.key.equals(key)) {
|
||||
// Hashtable not accept null value
|
||||
return e.value;
|
||||
}
|
||||
}
|
||||
|
||||
V newValue = mappingFunction.apply(key);
|
||||
if (newValue != null) {
|
||||
addEntry(hash, key, newValue, index);
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
Objects.requireNonNull(remappingFunction);
|
||||
|
||||
Entry<?,?> tab[] = table;
|
||||
int hash = hash(key);
|
||||
int index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)tab[index];
|
||||
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
|
||||
if (e.hash == hash && e.key.equals(key)) {
|
||||
V newValue = remappingFunction.apply(key, e.value);
|
||||
if (newValue == null) {
|
||||
modCount++;
|
||||
if (prev != null) {
|
||||
prev.next = e.next;
|
||||
} else {
|
||||
tab[index] = e.next;
|
||||
}
|
||||
count--;
|
||||
} else {
|
||||
e.value = newValue;
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
Objects.requireNonNull(remappingFunction);
|
||||
|
||||
Entry<?,?> tab[] = table;
|
||||
int hash = hash(key);
|
||||
int index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)tab[index];
|
||||
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
|
||||
if (e.hash == hash && Objects.equals(e.key, key)) {
|
||||
V newValue = remappingFunction.apply(key, e.value);
|
||||
if (newValue == null) {
|
||||
modCount++;
|
||||
if (prev != null) {
|
||||
prev.next = e.next;
|
||||
} else {
|
||||
tab[index] = e.next;
|
||||
}
|
||||
count--;
|
||||
} else {
|
||||
e.value = newValue;
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
||||
V newValue = remappingFunction.apply(key, null);
|
||||
if (newValue != null) {
|
||||
addEntry(hash, key, newValue, index);
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
Objects.requireNonNull(remappingFunction);
|
||||
|
||||
Entry<?,?> tab[] = table;
|
||||
int hash = hash(key);
|
||||
int index = (hash & 0x7FFFFFFF) % tab.length;
|
||||
@SuppressWarnings("unchecked")
|
||||
Entry<K,V> e = (Entry<K,V>)tab[index];
|
||||
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
|
||||
if (e.hash == hash && e.key.equals(key)) {
|
||||
V newValue = remappingFunction.apply(e.value, value);
|
||||
if (newValue == null) {
|
||||
modCount++;
|
||||
if (prev != null) {
|
||||
prev.next = e.next;
|
||||
} else {
|
||||
tab[index] = e.next;
|
||||
}
|
||||
count--;
|
||||
} else {
|
||||
e.value = newValue;
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
addEntry(hash, key, value, index);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the state of the Hashtable to a stream (i.e., serialize it).
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, 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,6 +25,10 @@
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* An object that maps keys to values. A map cannot contain duplicate keys;
|
||||
* each key can map to at most one value.
|
||||
@ -475,4 +479,613 @@ public interface Map<K,V> {
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
// Defaultable methods
|
||||
|
||||
/**
|
||||
* Returns the value to which the specified key is mapped,
|
||||
* or {@code defaultValue} if this map contains no mapping
|
||||
* for the key.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties.
|
||||
*
|
||||
* @param key the key whose associated value is to be returned
|
||||
* @return the value to which the specified key is mapped, or
|
||||
* {@code defaultValue} if this map contains no mapping for the key
|
||||
* @throws ClassCastException if the key is of an inappropriate type for
|
||||
* this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified key is null and this map
|
||||
* does not permit null keys
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
default V getOrDefault(Object key, V defaultValue) {
|
||||
V v;
|
||||
return (((v = get(key)) != null) || containsKey(key))
|
||||
? v
|
||||
: defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given action on each entry in this map, in the order entries
|
||||
* are returned by an entry set iterator (which may be unspecified), until
|
||||
* all entries have been processed or the action throws an {@code Exception}.
|
||||
* Exceptions thrown by the action are relayed to the caller.
|
||||
*
|
||||
* <p>The default implementation should be overridden by implementations if
|
||||
* they can provide a more performant implementation than an iterator-based
|
||||
* one.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties.
|
||||
*
|
||||
* @implSpec The default implementation is equivalent to, for this
|
||||
* {@code map}:
|
||||
* <pre> {@code
|
||||
* for ((Map.Entry<K, V> entry : map.entrySet())
|
||||
* action.accept(entry.getKey(), entry.getValue());
|
||||
* }</pre>
|
||||
*
|
||||
* @param action The action to be performed for each entry
|
||||
* @throws NullPointerException if the specified action is null
|
||||
* @throws ConcurrentModificationException if an entry is found to be
|
||||
* removed during iteration
|
||||
* @since 1.8
|
||||
*/
|
||||
default void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
Objects.requireNonNull(action);
|
||||
for (Map.Entry<K, V> entry : entrySet()) {
|
||||
K k;
|
||||
V v;
|
||||
try {
|
||||
k = entry.getKey();
|
||||
v = entry.getValue();
|
||||
} catch(IllegalStateException ise) {
|
||||
throw new ConcurrentModificationException(ise);
|
||||
}
|
||||
action.accept(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces each entry's value with the result of invoking the given
|
||||
* function on that entry, in the order entries are returned by an entry
|
||||
* set iterator, until all entries have been processed or the function
|
||||
* throws an exception.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties.
|
||||
*
|
||||
* @implSpec
|
||||
* <p>The default implementation is equivalent to, for this {@code map}:
|
||||
* <pre> {@code
|
||||
* for ((Map.Entry<K, V> entry : map.entrySet())
|
||||
* entry.setValue(function.apply(entry.getKey(), entry.getValue()));
|
||||
* }</pre>
|
||||
*
|
||||
* @param function the function to apply to each entry
|
||||
* @throws UnsupportedOperationException if the {@code set} operation
|
||||
* is not supported by this map's entry set iterator.
|
||||
* @throws ClassCastException if the class of a replacement value
|
||||
* prevents it from being stored in this map
|
||||
* @throws NullPointerException if the specified function is null, or the
|
||||
* specified replacement value is null, and this map does not permit null
|
||||
* values
|
||||
* @throws ClassCastException if a replacement value is of an inappropriate
|
||||
* type for this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if function or a replacement value is null,
|
||||
* and this map does not permit null keys or values
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws IllegalArgumentException if some property of a replacement value
|
||||
* prevents it from being stored in this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ConcurrentModificationException if an entry is found to be
|
||||
* removed during iteration
|
||||
* @since 1.8
|
||||
*/
|
||||
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
Objects.requireNonNull(function);
|
||||
for (Map.Entry<K, V> entry : entrySet()) {
|
||||
K k;
|
||||
V v;
|
||||
try {
|
||||
k = entry.getKey();
|
||||
v = entry.getValue();
|
||||
} catch(IllegalStateException ise) {
|
||||
throw new ConcurrentModificationException(ise);
|
||||
}
|
||||
entry.setValue(function.apply(k, v));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the specified key is not already associated with a value (or is mapped
|
||||
* to {@code null}) associates it with the given value and returns
|
||||
* {@code null}, else returns the current value.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation is equivalent to, for this {@code
|
||||
* map}:
|
||||
*
|
||||
* <pre> {@code
|
||||
* if (map.get(key) == null)
|
||||
* return map.put(key, value);
|
||||
* else
|
||||
* return map.get(key);
|
||||
* }</pre>
|
||||
*
|
||||
* @param key key with which the specified value is to be associated
|
||||
* @param value value to be associated with the specified key
|
||||
* @return the previous value associated with the specified key, or
|
||||
* {@code 1} if there was no mapping for the key.
|
||||
* (A {@code null} return can also indicate that the map
|
||||
* previously associated {@code null} with the key,
|
||||
* if the implementation supports null values.)
|
||||
* @throws UnsupportedOperationException if the {@code put} operation
|
||||
* is not supported by this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ClassCastException if the key or value is of an inappropriate
|
||||
* type for this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified key or value is null,
|
||||
* and this map does not permit null keys or values
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws IllegalArgumentException if some property of the specified key
|
||||
* or value prevents it from being stored in this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ConcurrentModificationException if a modification of the map is
|
||||
* detected during insertion of the value.
|
||||
* @since 1.8
|
||||
*/
|
||||
default V putIfAbsent(K key, V value) {
|
||||
V v = get(key);
|
||||
if (v == null) {
|
||||
if (put(key, value) != null) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the entry for the specified key only if it is currently
|
||||
* mapped to the specified value.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation is equivalent to, for this {@code map}:
|
||||
*
|
||||
* <pre> {@code
|
||||
* if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
|
||||
* map.remove(key);
|
||||
* return true;
|
||||
* } else
|
||||
* return false;
|
||||
* }</pre>
|
||||
*
|
||||
* @param key key with which the specified value is associated
|
||||
* @param value value expected to be associated with the specified key
|
||||
* @return {@code true} if the value was removed
|
||||
* @throws UnsupportedOperationException if the {@code remove} operation
|
||||
* is not supported by this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ClassCastException if the key or value is of an inappropriate
|
||||
* type for this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified key or value is null,
|
||||
* and this map does not permit null keys or values
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @since 1.8
|
||||
*/
|
||||
default boolean remove(Object key, Object value) {
|
||||
Object curValue = get(key);
|
||||
if (!Objects.equals(curValue, value) ||
|
||||
(curValue == null && !containsKey(key))) {
|
||||
return false;
|
||||
}
|
||||
remove(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the entry for the specified key only if currently
|
||||
* mapped to the specified value.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation is equivalent to, for this {@code map}:
|
||||
*
|
||||
* <pre> {@code
|
||||
* if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
|
||||
* map.put(key, newValue);
|
||||
* return true;
|
||||
* } else
|
||||
* return false;
|
||||
* }</pre>
|
||||
*
|
||||
* @param key key with which the specified value is associated
|
||||
* @param oldValue value expected to be associated with the specified key
|
||||
* @param newValue value to be associated with the specified key
|
||||
* @return {@code true} if the value was replaced
|
||||
* @throws UnsupportedOperationException if the {@code put} operation
|
||||
* is not supported by this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ClassCastException if the class of a specified key or value
|
||||
* prevents it from being stored in this map
|
||||
* @throws NullPointerException if a specified key or value is null,
|
||||
* and this map does not permit null keys or values
|
||||
* @throws IllegalArgumentException if some property of a specified key
|
||||
* or value prevents it from being stored in this map
|
||||
* @since 1.8
|
||||
*/
|
||||
default boolean replace(K key, V oldValue, V newValue) {
|
||||
Object curValue = get(key);
|
||||
if (!Objects.equals(curValue, oldValue) ||
|
||||
(curValue == null && !containsKey(key))) {
|
||||
return false;
|
||||
}
|
||||
put(key, newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the entry for the specified key only if it is
|
||||
* currently mapped to some value.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation is equivalent to, for this {@code map}:
|
||||
*
|
||||
* <pre> {@code
|
||||
* if (map.containsKey(key)) {
|
||||
* return map.put(key, value);
|
||||
* } else
|
||||
* return null;
|
||||
* }</pre>
|
||||
*
|
||||
* @param key key with which the specified value is associated
|
||||
* @param value value to be associated with the specified key
|
||||
* @return the previous value associated with the specified key, or
|
||||
* {@code null} if there was no mapping for the key.
|
||||
* (A {@code null} return can also indicate that the map
|
||||
* previously associated {@code null} with the key,
|
||||
* if the implementation supports null values.)
|
||||
* @throws UnsupportedOperationException if the {@code put} operation
|
||||
* is not supported by this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ClassCastException if the class of the specified key or value
|
||||
* prevents it from being stored in this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified key or value is null,
|
||||
* and this map does not permit null keys or values
|
||||
* @throws IllegalArgumentException if some property of the specified key
|
||||
* or value prevents it from being stored in this map
|
||||
* @since 1.8
|
||||
*/
|
||||
default V replace(K key, V value) {
|
||||
return containsKey(key) ? put(key, value) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the specified key is not already associated with a value (or
|
||||
* is mapped to {@code null}), attempts to compute its value using
|
||||
* the given mapping function and enters it into this map unless
|
||||
* {@code null}.
|
||||
*
|
||||
* <p>If the function returns {@code null} no mapping is recorded. If
|
||||
* the function itself throws an (unchecked) exception, the
|
||||
* exception is rethrown, and no mapping is recorded. The most
|
||||
* common usage is to construct a new object serving as an initial
|
||||
* mapped value or memoized result, as in:
|
||||
*
|
||||
* <pre> {@code
|
||||
* map.computeIfAbsent(key, k -> new Value(f(k)));
|
||||
* }</pre>
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties. In particular, all implementations of
|
||||
* subinterface {@link java.util.concurrent.ConcurrentMap} must document
|
||||
* whether the function is applied once atomically only if the value is not
|
||||
* present. Any class that permits null values must document
|
||||
* whether and how this method distinguishes absence from null mappings.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation is equivalent to the following
|
||||
* steps for this {@code map}, then returning the current value or
|
||||
* {@code null} if now absent:
|
||||
*
|
||||
* <pre> {@code
|
||||
* if (map.get(key) == null) {
|
||||
* V newValue = mappingFunction.apply(key);
|
||||
* if (newValue != null)
|
||||
* map.putIfAbsent(key, newValue);
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @param key key with which the specified value is to be associated
|
||||
* @param mappingFunction the function to compute a value
|
||||
* @return the current (existing or computed) value associated with
|
||||
* the specified key, or null if the computed value is null
|
||||
* @throws NullPointerException if the specified key is null and
|
||||
* this map does not support null keys, or the
|
||||
* mappingFunction is null
|
||||
* @throws UnsupportedOperationException if the {@code put} operation
|
||||
* is not supported by this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ClassCastException if the class of the specified key or value
|
||||
* prevents it from being stored in this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @since 1.8
|
||||
*/
|
||||
default V computeIfAbsent(K key,
|
||||
Function<? super K, ? extends V> mappingFunction) {
|
||||
V v, newValue;
|
||||
return ((v = get(key)) == null &&
|
||||
(newValue = mappingFunction.apply(key)) != null &&
|
||||
(v = putIfAbsent(key, newValue)) == null) ? newValue : v;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the value for the specified key is present and non-null, attempts to
|
||||
* compute a new mapping given the key and its current mapped value.
|
||||
*
|
||||
* <p>If the function returns {@code null}, the mapping is removed. If the
|
||||
* function itself throws an (unchecked) exception, the exception is
|
||||
* rethrown, and the current mapping is left unchanged.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties. In particular, all implementations of
|
||||
* subinterface {@link java.util.concurrent.ConcurrentMap} must document
|
||||
* whether the function is applied once atomically only if the value is not
|
||||
* present. Any class that permits null values must document
|
||||
* whether and how this method distinguishes absence from null mappings.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation is equivalent to performing the
|
||||
* following steps for this {@code map}, then returning the
|
||||
* current value or {@code null} if now absent:
|
||||
*
|
||||
* <pre> {@code
|
||||
* if (map.get(key) != null) {
|
||||
* V oldValue = map.get(key);
|
||||
* V newValue = remappingFunction.apply(key, oldValue);
|
||||
* if (newValue != null)
|
||||
* map.replace(key, oldValue, newValue);
|
||||
* else
|
||||
* map.remove(key, oldValue);
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* In concurrent contexts, the default implementation may retry
|
||||
* these steps when multiple threads attempt updates.
|
||||
*
|
||||
* @param key key with which the specified value is to be associated
|
||||
* @param remappingFunction the function to compute a value
|
||||
* @return the new value associated with the specified key, or null if none
|
||||
* @throws NullPointerException if the specified key is null and
|
||||
* this map does not support null keys, or the
|
||||
* remappingFunction is null
|
||||
* @throws UnsupportedOperationException if the {@code put} operation
|
||||
* is not supported by this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ClassCastException if the class of the specified key or value
|
||||
* prevents it from being stored in this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @since 1.8
|
||||
*/
|
||||
default V computeIfPresent(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
V oldValue;
|
||||
while ((oldValue = get(key)) != null) {
|
||||
V newValue = remappingFunction.apply(key, oldValue);
|
||||
if (newValue != null) {
|
||||
if (replace(key, oldValue, newValue))
|
||||
return newValue;
|
||||
} else if (remove(key, oldValue))
|
||||
return null;
|
||||
}
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to compute a mapping for the specified key and its
|
||||
* current mapped value (or {@code null} if there is no current
|
||||
* mapping). For example, to either create or append a {@code
|
||||
* String msg} to a value mapping:
|
||||
*
|
||||
* <pre> {@code
|
||||
* map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre>
|
||||
* (Method {@link #merge merge()} is often simpler to use for such purposes.)
|
||||
*
|
||||
* <p>If the function returns {@code null}, the mapping is removed (or
|
||||
* remains absent if initially absent). If the function itself throws an
|
||||
* (unchecked) exception, the exception is rethrown, and the current mapping
|
||||
* is left unchanged.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties. In particular, all implementations of
|
||||
* subinterface {@link java.util.concurrent.ConcurrentMap} must document
|
||||
* whether the function is applied once atomically only if the value is not
|
||||
* present. Any class that permits null values must document
|
||||
* whether and how this method distinguishes absence from null mappings.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation is equivalent to performing the following
|
||||
* steps for this {@code map}, then returning the current value or
|
||||
* {@code null} if absent:
|
||||
*
|
||||
* <pre> {@code
|
||||
* V oldValue = map.get(key);
|
||||
* V newValue = remappingFunction.apply(key, oldValue);
|
||||
* if (oldValue != null ) {
|
||||
* if (newValue != null)
|
||||
* map.replace(key, oldValue, newValue);
|
||||
* else
|
||||
* map.remove(key, oldValue);
|
||||
* } else {
|
||||
* if (newValue != null)
|
||||
* map.putIfAbsent(key, newValue);
|
||||
* else
|
||||
* return null;
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* In concurrent contexts, the default implementation may retry
|
||||
* these steps when multiple threads attempt updates.
|
||||
*
|
||||
* @param key key with which the specified value is to be associated
|
||||
* @param remappingFunction the function to compute a value
|
||||
* @return the new value associated with the specified key, or null if none
|
||||
* @throws NullPointerException if the specified key is null and
|
||||
* this map does not support null keys, or the
|
||||
* remappingFunction is null
|
||||
* @throws UnsupportedOperationException if the {@code put} operation
|
||||
* is not supported by this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ClassCastException if the class of the specified key or value
|
||||
* prevents it from being stored in this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @since 1.8
|
||||
*/
|
||||
default V compute(K key,
|
||||
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
V oldValue = get(key);
|
||||
for (;;) {
|
||||
V newValue = remappingFunction.apply(key, oldValue);
|
||||
if (oldValue != null) {
|
||||
if (newValue != null) {
|
||||
if (replace(key, oldValue, newValue))
|
||||
return newValue;
|
||||
} else if (remove(key, oldValue)) {
|
||||
return null;
|
||||
}
|
||||
oldValue = get(key);
|
||||
} else {
|
||||
if (newValue != null) {
|
||||
if ((oldValue = putIfAbsent(key, newValue)) == null)
|
||||
return newValue;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the specified key is not already associated with a value or is
|
||||
* associated with null, associates it with the given value.
|
||||
* Otherwise, replaces the value with the results of the given
|
||||
* remapping function, or removes if the result is {@code null}. This
|
||||
* method may be of use when combining multiple mapped values for a key.
|
||||
* For example, to either create or append a {@code String msg} to a
|
||||
* value mapping:
|
||||
*
|
||||
* <pre> {@code
|
||||
* map.merge(key, msg, String::concat)
|
||||
* }</pre>
|
||||
*
|
||||
* <p>If the function returns {@code null}, the mapping is removed (or
|
||||
* remains absent if initially absent). If the function itself throws an
|
||||
* (unchecked) exception, the exception is rethrown, and the current mapping
|
||||
* is left unchanged.
|
||||
*
|
||||
* <p>The default implementation makes no guarantees about synchronization
|
||||
* or atomicity properties of this method. Any implementation providing
|
||||
* atomicity guarantees must override this method and document its
|
||||
* concurrency properties. In particular, all implementations of
|
||||
* subinterface {@link java.util.concurrent.ConcurrentMap} must document
|
||||
* whether the function is applied once atomically only if the value is not
|
||||
* present. Any class that permits null values must document
|
||||
* whether and how this method distinguishes absence from null mappings.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation is equivalent to performing the
|
||||
* following steps for this {@code map}, then returning the
|
||||
* current value or {@code null} if absent:
|
||||
*
|
||||
* <pre> {@code
|
||||
* V oldValue = map.get(key);
|
||||
* V newValue = (oldValue == null) ? value :
|
||||
* remappingFunction.apply(oldValue, value);
|
||||
* if (newValue == null)
|
||||
* map.remove(key, oldValue);
|
||||
* else if (oldValue == null)
|
||||
* map.putIfAbsent(key, newValue);
|
||||
* else
|
||||
* map.replace(key, oldValue, newValue);
|
||||
* }</pre>
|
||||
*
|
||||
* In concurrent contexts, the default implementation may retry
|
||||
* these steps when multiple threads attempt updates.
|
||||
*
|
||||
* @param key key with which the specified value is to be associated
|
||||
* @param value the value to use if absent
|
||||
* @param remappingFunction the function to recompute a value if present
|
||||
* @return the new value associated with the specified key, or null if none
|
||||
* @throws UnsupportedOperationException if the {@code put} operation
|
||||
* is not supported by this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws ClassCastException if the class of the specified key or value
|
||||
* prevents it from being stored in this map
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified key is null and
|
||||
* this map does not support null keys, or the
|
||||
* remappingFunction is null
|
||||
* @since 1.8
|
||||
*/
|
||||
default V merge(K key, V value,
|
||||
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
V oldValue = get(key);
|
||||
for (;;) {
|
||||
if (oldValue != null) {
|
||||
V newValue = remappingFunction.apply(oldValue, value);
|
||||
if (newValue != null) {
|
||||
if (replace(key, oldValue, newValue))
|
||||
return newValue;
|
||||
} else if (remove(key, oldValue)) {
|
||||
return null;
|
||||
}
|
||||
oldValue = get(key);
|
||||
} else {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((oldValue = putIfAbsent(key, value)) == null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,8 @@ import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.spi.ResourceBundleControlProvider;
|
||||
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.util.locale.BaseLocale;
|
||||
import sun.util.locale.LocaleObjectCache;
|
||||
|
||||
@ -440,14 +442,10 @@ public abstract class ResourceBundle {
|
||||
|
||||
/*
|
||||
* Automatic determination of the ClassLoader to be used to load
|
||||
* resources on behalf of the client. N.B. The client is getLoader's
|
||||
* caller's caller.
|
||||
* resources on behalf of the client.
|
||||
*/
|
||||
private static ClassLoader getLoader() {
|
||||
Class<?>[] stack = getClassContext();
|
||||
/* Magic number 2 identifies our caller's caller */
|
||||
Class<?> c = stack[2];
|
||||
ClassLoader cl = (c == null) ? null : c.getClassLoader();
|
||||
private static ClassLoader getLoader(Class<?> caller) {
|
||||
ClassLoader cl = caller == null ? null : caller.getClassLoader();
|
||||
if (cl == null) {
|
||||
// When the caller's loader is the boot class loader, cl is null
|
||||
// here. In that case, ClassLoader.getSystemClassLoader() may
|
||||
@ -461,8 +459,6 @@ public abstract class ResourceBundle {
|
||||
return cl;
|
||||
}
|
||||
|
||||
private static native Class<?>[] getClassContext();
|
||||
|
||||
/**
|
||||
* A wrapper of ClassLoader.getSystemClassLoader().
|
||||
*/
|
||||
@ -746,11 +742,11 @@ public abstract class ResourceBundle {
|
||||
* if no resource bundle for the specified base name can be found
|
||||
* @return a resource bundle for the given base name and the default locale
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static final ResourceBundle getBundle(String baseName)
|
||||
{
|
||||
return getBundleImpl(baseName, Locale.getDefault(),
|
||||
/* must determine loader here, else we break stack invariant */
|
||||
getLoader(),
|
||||
getLoader(Reflection.getCallerClass()),
|
||||
getDefaultControl(baseName));
|
||||
}
|
||||
|
||||
@ -788,11 +784,11 @@ public abstract class ResourceBundle {
|
||||
* needed.
|
||||
* @since 1.6
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static final ResourceBundle getBundle(String baseName,
|
||||
Control control) {
|
||||
return getBundleImpl(baseName, Locale.getDefault(),
|
||||
/* must determine loader here, else we break stack invariant */
|
||||
getLoader(),
|
||||
getLoader(Reflection.getCallerClass()),
|
||||
control);
|
||||
}
|
||||
|
||||
@ -817,12 +813,12 @@ public abstract class ResourceBundle {
|
||||
* if no resource bundle for the specified base name can be found
|
||||
* @return a resource bundle for the given base name and locale
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static final ResourceBundle getBundle(String baseName,
|
||||
Locale locale)
|
||||
{
|
||||
return getBundleImpl(baseName, locale,
|
||||
/* must determine loader here, else we break stack invariant */
|
||||
getLoader(),
|
||||
getLoader(Reflection.getCallerClass()),
|
||||
getDefaultControl(baseName));
|
||||
}
|
||||
|
||||
@ -863,11 +859,11 @@ public abstract class ResourceBundle {
|
||||
* needed.
|
||||
* @since 1.6
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static final ResourceBundle getBundle(String baseName, Locale targetLocale,
|
||||
Control control) {
|
||||
return getBundleImpl(baseName, targetLocale,
|
||||
/* must determine loader here, else we break stack invariant */
|
||||
getLoader(),
|
||||
getLoader(Reflection.getCallerClass()),
|
||||
control);
|
||||
}
|
||||
|
||||
@ -1721,8 +1717,9 @@ public abstract class ResourceBundle {
|
||||
* @since 1.6
|
||||
* @see ResourceBundle.Control#getTimeToLive(String,Locale)
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static final void clearCache() {
|
||||
clearCache(getLoader());
|
||||
clearCache(getLoader(Reflection.getCallerClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,7 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.concurrent.locks.*;
|
||||
import java.util.*;
|
||||
import java.io.Serializable;
|
||||
@ -1483,7 +1484,23 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
|
||||
@SuppressWarnings("unchecked")
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException {
|
||||
s.defaultReadObject();
|
||||
// Don't call defaultReadObject()
|
||||
ObjectInputStream.GetField oisFields = s.readFields();
|
||||
final Segment<K,V>[] oisSegments = (Segment<K,V>[])oisFields.get("segments", null);
|
||||
|
||||
final int ssize = oisSegments.length;
|
||||
if (ssize < 1 || ssize > MAX_SEGMENTS
|
||||
|| (ssize & (ssize-1)) != 0 ) // ssize not power of two
|
||||
throw new java.io.InvalidObjectException("Bad number of segments:"
|
||||
+ ssize);
|
||||
int sshift = 0, ssizeTmp = ssize;
|
||||
while (ssizeTmp > 1) {
|
||||
++sshift;
|
||||
ssizeTmp >>>= 1;
|
||||
}
|
||||
UNSAFE.putIntVolatile(this, SEGSHIFT_OFFSET, 32 - sshift);
|
||||
UNSAFE.putIntVolatile(this, SEGMASK_OFFSET, ssize - 1);
|
||||
UNSAFE.putObjectVolatile(this, SEGMENTS_OFFSET, oisSegments);
|
||||
|
||||
// set hashMask
|
||||
UNSAFE.putIntVolatile(this, HASHSEED_OFFSET,
|
||||
@ -1517,6 +1534,9 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
|
||||
private static final long TBASE;
|
||||
private static final int TSHIFT;
|
||||
private static final long HASHSEED_OFFSET;
|
||||
private static final long SEGSHIFT_OFFSET;
|
||||
private static final long SEGMASK_OFFSET;
|
||||
private static final long SEGMENTS_OFFSET;
|
||||
|
||||
static {
|
||||
int ss, ts;
|
||||
@ -1530,6 +1550,12 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
|
||||
ss = UNSAFE.arrayIndexScale(sc);
|
||||
HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
|
||||
ConcurrentHashMap.class.getDeclaredField("hashSeed"));
|
||||
SEGSHIFT_OFFSET = UNSAFE.objectFieldOffset(
|
||||
ConcurrentHashMap.class.getDeclaredField("segmentShift"));
|
||||
SEGMASK_OFFSET = UNSAFE.objectFieldOffset(
|
||||
ConcurrentHashMap.class.getDeclaredField("segmentMask"));
|
||||
SEGMENTS_OFFSET = UNSAFE.objectFieldOffset(
|
||||
ConcurrentHashMap.class.getDeclaredField("segments"));
|
||||
} catch (Exception e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* A {@link java.util.Map} providing additional atomic
|
||||
* <tt>putIfAbsent</tt>, <tt>remove</tt>, and <tt>replace</tt> methods.
|
||||
* {@code putIfAbsent}, {@code remove}, and {@code replace} methods.
|
||||
*
|
||||
* <p>Memory consistency effects: As with other concurrent
|
||||
* collections, actions in a thread prior to placing an object into a
|
||||
@ -57,6 +57,21 @@ import java.util.Map;
|
||||
* @param <V> the type of mapped values
|
||||
*/
|
||||
public interface ConcurrentMap<K, V> extends Map<K, V> {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implNote This implementation assumes that the ConcurrentMap cannot
|
||||
* contain null values and get() returning null unambiguously means the key
|
||||
* is absent. Implementations which support null values must override this
|
||||
* default implementation.
|
||||
*/
|
||||
@Override
|
||||
default V getOrDefault(Object key, V defaultValue) {
|
||||
V v;
|
||||
return ((v = get(key)) != null) ? v : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the specified key is not already associated
|
||||
* with a value, associate it with the given value.
|
||||
@ -91,7 +106,7 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
|
||||
* Removes the entry for a key only if currently mapped to a given value.
|
||||
* This is equivalent to
|
||||
* <pre> {@code
|
||||
* if (map.containsKey(key) && map.get(key).equals(value)) {
|
||||
* if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
|
||||
* map.remove(key);
|
||||
* return true;
|
||||
* } else
|
||||
@ -101,8 +116,8 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
|
||||
*
|
||||
* @param key key with which the specified value is associated
|
||||
* @param value value expected to be associated with the specified key
|
||||
* @return <tt>true</tt> if the value was removed
|
||||
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
|
||||
* @return {@code true} if the value was removed
|
||||
* @throws UnsupportedOperationException if the {@code remove} operation
|
||||
* is not supported by this map
|
||||
* @throws ClassCastException if the key or value is of an inappropriate
|
||||
* type for this map
|
||||
@ -117,7 +132,7 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
|
||||
* Replaces the entry for a key only if currently mapped to a given value.
|
||||
* This is equivalent to
|
||||
* <pre> {@code
|
||||
* if (map.containsKey(key) && map.get(key).equals(oldValue)) {
|
||||
* if (map.containsKey(key) && Objects.equals(map.get(key), oldValue)) {
|
||||
* map.put(key, newValue);
|
||||
* return true;
|
||||
* } else
|
||||
@ -128,8 +143,8 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
|
||||
* @param key key with which the specified value is associated
|
||||
* @param oldValue value expected to be associated with the specified key
|
||||
* @param newValue value to be associated with the specified key
|
||||
* @return <tt>true</tt> if the value was replaced
|
||||
* @throws UnsupportedOperationException if the <tt>put</tt> operation
|
||||
* @return {@code true} if the value was replaced
|
||||
* @throws UnsupportedOperationException if the {@code put} operation
|
||||
* is not supported by this map
|
||||
* @throws ClassCastException if the class of a specified key or value
|
||||
* prevents it from being stored in this map
|
||||
@ -154,11 +169,11 @@ public interface ConcurrentMap<K, V> extends Map<K, V> {
|
||||
* @param key key with which the specified value is associated
|
||||
* @param value value to be associated with the specified key
|
||||
* @return the previous value associated with the specified key, or
|
||||
* <tt>null</tt> if there was no mapping for the key.
|
||||
* (A <tt>null</tt> return can also indicate that the map
|
||||
* previously associated <tt>null</tt> with the key,
|
||||
* {@code null} if there was no mapping for the key.
|
||||
* (A {@code null} return can also indicate that the map
|
||||
* previously associated {@code null} with the key,
|
||||
* if the implementation supports null values.)
|
||||
* @throws UnsupportedOperationException if the <tt>put</tt> operation
|
||||
* @throws UnsupportedOperationException if the {@code put} operation
|
||||
* is not supported by this map
|
||||
* @throws ClassCastException if the class of the specified key or value
|
||||
* prevents it from being stored in this map
|
||||
|
@ -37,6 +37,9 @@ package java.util.concurrent.atomic;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
@ -77,8 +80,9 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
* or the field is inaccessible to the caller according to Java language
|
||||
* access control
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
|
||||
return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
|
||||
return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName, Reflection.getCallerClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -365,9 +369,11 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
private final Class<T> tclass;
|
||||
private final Class<?> cclass;
|
||||
|
||||
AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName) {
|
||||
AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,
|
||||
final String fieldName,
|
||||
final Class<?> caller)
|
||||
{
|
||||
final Field field;
|
||||
final Class<?> caller;
|
||||
final int modifiers;
|
||||
try {
|
||||
field = AccessController.doPrivileged(
|
||||
@ -376,7 +382,6 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
return tclass.getDeclaredField(fieldName);
|
||||
}
|
||||
});
|
||||
caller = sun.reflect.Reflection.getCallerClass(3);
|
||||
modifiers = field.getModifiers();
|
||||
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
|
||||
caller, tclass, null, modifiers);
|
||||
|
@ -37,6 +37,9 @@ package java.util.concurrent.atomic;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
@ -77,11 +80,13 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
* or the field is inaccessible to the caller according to Java language
|
||||
* access control
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
if (AtomicLong.VM_SUPPORTS_LONG_CAS)
|
||||
return new CASUpdater<U>(tclass, fieldName);
|
||||
return new CASUpdater<U>(tclass, fieldName, caller);
|
||||
else
|
||||
return new LockedUpdater<U>(tclass, fieldName);
|
||||
return new LockedUpdater<U>(tclass, fieldName, caller);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -365,9 +370,8 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
private final Class<T> tclass;
|
||||
private final Class<?> cclass;
|
||||
|
||||
CASUpdater(final Class<T> tclass, final String fieldName) {
|
||||
CASUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller) {
|
||||
final Field field;
|
||||
final Class<?> caller;
|
||||
final int modifiers;
|
||||
try {
|
||||
field = AccessController.doPrivileged(
|
||||
@ -376,7 +380,6 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
return tclass.getDeclaredField(fieldName);
|
||||
}
|
||||
});
|
||||
caller = sun.reflect.Reflection.getCallerClass(3);
|
||||
modifiers = field.getModifiers();
|
||||
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
|
||||
caller, tclass, null, modifiers);
|
||||
@ -490,9 +493,8 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
private final Class<T> tclass;
|
||||
private final Class<?> cclass;
|
||||
|
||||
LockedUpdater(final Class<T> tclass, final String fieldName) {
|
||||
LockedUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller) {
|
||||
Field field = null;
|
||||
Class<?> caller = null;
|
||||
int modifiers = 0;
|
||||
try {
|
||||
field = AccessController.doPrivileged(
|
||||
@ -501,7 +503,6 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
return tclass.getDeclaredField(fieldName);
|
||||
}
|
||||
});
|
||||
caller = sun.reflect.Reflection.getCallerClass(3);
|
||||
modifiers = field.getModifiers();
|
||||
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
|
||||
caller, tclass, null, modifiers);
|
||||
|
@ -37,6 +37,9 @@ package java.util.concurrent.atomic;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.function.BinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
@ -96,10 +99,12 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
|
||||
* or the field is inaccessible to the caller according to Java language
|
||||
* access control
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) {
|
||||
return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass,
|
||||
vclass,
|
||||
fieldName);
|
||||
fieldName,
|
||||
Reflection.getCallerClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -297,10 +302,11 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
|
||||
|
||||
AtomicReferenceFieldUpdaterImpl(final Class<T> tclass,
|
||||
Class<V> vclass,
|
||||
final String fieldName) {
|
||||
final String fieldName,
|
||||
final Class<?> caller)
|
||||
{
|
||||
final Field field;
|
||||
final Class<?> fieldClass;
|
||||
final Class<?> caller;
|
||||
final int modifiers;
|
||||
try {
|
||||
field = AccessController.doPrivileged(
|
||||
@ -309,7 +315,6 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
|
||||
return tclass.getDeclaredField(fieldName);
|
||||
}
|
||||
});
|
||||
caller = sun.reflect.Reflection.getCallerClass(3);
|
||||
modifiers = field.getModifiers();
|
||||
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
|
||||
caller, tclass, null, modifiers);
|
||||
|
@ -36,6 +36,8 @@ import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Supplier;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
/**
|
||||
* A Logger object is used to log messages for a specific
|
||||
@ -333,13 +335,10 @@ public class Logger {
|
||||
}
|
||||
}
|
||||
|
||||
private static Logger demandLogger(String name, String resourceBundleName) {
|
||||
private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
|
||||
LogManager manager = LogManager.getLogManager();
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null && !SystemLoggerHelper.disableCallerCheck) {
|
||||
// 0: Reflection 1: Logger.demandLogger 2: Logger.getLogger 3: caller
|
||||
final int SKIP_FRAMES = 3;
|
||||
Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES);
|
||||
if (caller.getClassLoader() == null) {
|
||||
return manager.demandSystemLogger(name, resourceBundleName);
|
||||
}
|
||||
@ -377,6 +376,7 @@ public class Logger {
|
||||
|
||||
// Synchronization is not required here. All synchronization for
|
||||
// adding a new Logger object is handled by LogManager.addLogger().
|
||||
@CallerSensitive
|
||||
public static Logger getLogger(String name) {
|
||||
// This method is intentionally not a wrapper around a call
|
||||
// to getLogger(name, resourceBundleName). If it were then
|
||||
@ -388,7 +388,7 @@ public class Logger {
|
||||
// would throw an IllegalArgumentException in the second call
|
||||
// because the wrapper would result in an attempt to replace
|
||||
// the existing "resourceBundleForFoo" with null.
|
||||
return demandLogger(name, null);
|
||||
return demandLogger(name, null, Reflection.getCallerClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -434,8 +434,9 @@ public class Logger {
|
||||
|
||||
// Synchronization is not required here. All synchronization for
|
||||
// adding a new Logger object is handled by LogManager.addLogger().
|
||||
@CallerSensitive
|
||||
public static Logger getLogger(String name, String resourceBundleName) {
|
||||
Logger result = demandLogger(name, resourceBundleName);
|
||||
Logger result = demandLogger(name, resourceBundleName, Reflection.getCallerClass());
|
||||
|
||||
// MissingResourceException or IllegalArgumentException can be
|
||||
// thrown by setupResourceInfo().
|
||||
|
@ -28,6 +28,7 @@ import java.util.*;
|
||||
import java.security.*;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
@ -60,9 +61,10 @@ public class ScriptEngineManager {
|
||||
*
|
||||
* @see java.lang.Thread#getContextClassLoader
|
||||
*/
|
||||
@CallerSensitive
|
||||
public ScriptEngineManager() {
|
||||
ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (canCallerAccessLoader(ctxtLoader)) {
|
||||
if (canCallerAccessLoader(ctxtLoader, Reflection.getCallerClass())) {
|
||||
if (DEBUG) System.out.println("using " + ctxtLoader);
|
||||
init(ctxtLoader);
|
||||
} else {
|
||||
@ -419,10 +421,10 @@ public class ScriptEngineManager {
|
||||
/** Global bindings associated with script engines created by this manager. */
|
||||
private Bindings globalScope;
|
||||
|
||||
private boolean canCallerAccessLoader(ClassLoader loader) {
|
||||
private boolean canCallerAccessLoader(ClassLoader loader, Class<?> caller) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
ClassLoader callerLoader = getCallerClassLoader();
|
||||
ClassLoader callerLoader = getClassLoader(caller);
|
||||
if (!sun.misc.VM.isSystemDomainLoader(callerLoader)) {
|
||||
if (loader != callerLoader || !isAncestor(loader, callerLoader)) {
|
||||
try {
|
||||
@ -438,10 +440,9 @@ public class ScriptEngineManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Note that this code is same as ClassLoader.getCallerClassLoader().
|
||||
// Note that this code is same as ClassLoader.getClassLoader().
|
||||
// But, that method is package private and hence we can't call here.
|
||||
private ClassLoader getCallerClassLoader() {
|
||||
Class<?> caller = Reflection.getCallerClass(3);
|
||||
private ClassLoader getClassLoader(Class<?> caller) {
|
||||
if (caller == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -539,7 +539,7 @@ public abstract class EmbeddedFrame extends Frame
|
||||
public void toBack() {}
|
||||
public void updateFocusableWindowState() {}
|
||||
public void updateAlwaysOnTop() {}
|
||||
public void setAlwaysOnTop(boolean alwaysOnTop) {}
|
||||
public void updateAlwaysOnTopState() {}
|
||||
public Component getGlobalHeavyweightFocusOwner() { return null; }
|
||||
public void setBoundsPrivate(int x, int y, int width, int height) {
|
||||
setBounds(x, y, width, height, SET_BOUNDS);
|
||||
|
@ -102,11 +102,11 @@ public class TransferableProxy implements Transferable {
|
||||
protected final boolean isLocal;
|
||||
}
|
||||
|
||||
class ClassLoaderObjectOutputStream extends ObjectOutputStream {
|
||||
final class ClassLoaderObjectOutputStream extends ObjectOutputStream {
|
||||
private final Map<Set<String>, ClassLoader> map =
|
||||
new HashMap<Set<String>, ClassLoader>();
|
||||
|
||||
public ClassLoaderObjectOutputStream(OutputStream os) throws IOException {
|
||||
ClassLoaderObjectOutputStream(OutputStream os) throws IOException {
|
||||
super(os);
|
||||
}
|
||||
|
||||
@ -140,15 +140,15 @@ class ClassLoaderObjectOutputStream extends ObjectOutputStream {
|
||||
map.put(s, classLoader);
|
||||
}
|
||||
|
||||
public Map<Set<String>, ClassLoader> getClassLoaderMap() {
|
||||
Map<Set<String>, ClassLoader> getClassLoaderMap() {
|
||||
return new HashMap(map);
|
||||
}
|
||||
}
|
||||
|
||||
class ClassLoaderObjectInputStream extends ObjectInputStream {
|
||||
final class ClassLoaderObjectInputStream extends ObjectInputStream {
|
||||
private final Map<Set<String>, ClassLoader> map;
|
||||
|
||||
public ClassLoaderObjectInputStream(InputStream is,
|
||||
ClassLoaderObjectInputStream(InputStream is,
|
||||
Map<Set<String>, ClassLoader> map)
|
||||
throws IOException {
|
||||
super(is);
|
||||
@ -166,8 +166,11 @@ class ClassLoaderObjectInputStream extends ObjectInputStream {
|
||||
s.add(className);
|
||||
|
||||
ClassLoader classLoader = map.get(s);
|
||||
|
||||
if (classLoader != null) {
|
||||
return Class.forName(className, false, classLoader);
|
||||
} else {
|
||||
return super.resolveClass(classDesc);
|
||||
}
|
||||
}
|
||||
|
||||
protected Class<?> resolveProxyClass(String[] interfaces)
|
||||
@ -179,6 +182,9 @@ class ClassLoaderObjectInputStream extends ObjectInputStream {
|
||||
}
|
||||
|
||||
ClassLoader classLoader = map.get(s);
|
||||
if (classLoader == null) {
|
||||
return super.resolveProxyClass(interfaces);
|
||||
}
|
||||
|
||||
// The code below is mostly copied from the superclass.
|
||||
ClassLoader nonPublicLoader = null;
|
||||
|
@ -868,6 +868,15 @@ public class ByteComponentRaster extends SunWritableRaster {
|
||||
* or if data buffer has not enough capacity.
|
||||
*/
|
||||
protected final void verify() {
|
||||
/* Need to re-verify the dimensions since a sample model may be
|
||||
* specified to the constructor
|
||||
*/
|
||||
if (width <= 0 || height <= 0 ||
|
||||
height > (Integer.MAX_VALUE / width))
|
||||
{
|
||||
throw new RasterFormatException("Invalid raster dimension");
|
||||
}
|
||||
|
||||
for (int i = 0; i < dataOffsets.length; i++) {
|
||||
if (dataOffsets[i] < 0) {
|
||||
throw new RasterFormatException("Data offsets for band " + i
|
||||
@ -905,13 +914,14 @@ public class ByteComponentRaster extends SunWritableRaster {
|
||||
lastPixelOffset += lastScanOffset;
|
||||
|
||||
for (int i = 0; i < numDataElements; i++) {
|
||||
size = lastPixelOffset + dataOffsets[i];
|
||||
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
|
||||
throw new RasterFormatException("Incorrect band offset: "
|
||||
+ dataOffsets[i]);
|
||||
|
||||
}
|
||||
|
||||
size = lastPixelOffset + dataOffsets[i];
|
||||
|
||||
if (size > maxSize) {
|
||||
maxSize = size;
|
||||
}
|
||||
|
@ -1368,11 +1368,35 @@ public class BytePackedRaster extends SunWritableRaster {
|
||||
throw new RasterFormatException("Data offsets must be >= 0");
|
||||
}
|
||||
|
||||
/* Need to re-verify the dimensions since a sample model may be
|
||||
* specified to the constructor
|
||||
*/
|
||||
if (width <= 0 || height <= 0 ||
|
||||
height > (Integer.MAX_VALUE / width))
|
||||
{
|
||||
throw new RasterFormatException("Invalid raster dimension");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pixelBitstride was verified in constructor, so just make
|
||||
* sure that it is safe to multiply it by width.
|
||||
*/
|
||||
if ((width - 1) > Integer.MAX_VALUE / pixelBitStride) {
|
||||
throw new RasterFormatException("Invalid raster dimension");
|
||||
}
|
||||
|
||||
if (scanlineStride < 0 ||
|
||||
scanlineStride > (Integer.MAX_VALUE / height))
|
||||
{
|
||||
throw new RasterFormatException("Invalid scanline stride");
|
||||
}
|
||||
|
||||
int lastbit = (dataBitOffset
|
||||
+ (height-1) * scanlineStride * 8
|
||||
+ (width-1) * pixelBitStride
|
||||
+ pixelBitStride - 1);
|
||||
if (lastbit / 8 >= data.length) {
|
||||
if (lastbit < 0 || lastbit / 8 >= data.length) {
|
||||
throw new RasterFormatException("raster dimensions overflow " +
|
||||
"array bounds");
|
||||
}
|
||||
|
@ -333,10 +333,10 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
|
||||
hints = h;
|
||||
}
|
||||
|
||||
private native void setICMpixels(int x, int y, int w, int h, int[] lut,
|
||||
private native boolean setICMpixels(int x, int y, int w, int h, int[] lut,
|
||||
byte[] pix, int off, int scansize,
|
||||
IntegerComponentRaster ict);
|
||||
private native int setDiffICM(int x, int y, int w, int h, int[] lut,
|
||||
private native boolean setDiffICM(int x, int y, int w, int h, int[] lut,
|
||||
int transPix, int numLut, IndexColorModel icm,
|
||||
byte[] pix, int off, int scansize,
|
||||
ByteComponentRaster bct, int chanOff);
|
||||
@ -426,10 +426,10 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
|
||||
IndexColorModel icm = (IndexColorModel) model;
|
||||
ByteComponentRaster bct = (ByteComponentRaster) biRaster;
|
||||
int numlut = numSrcLUT;
|
||||
if (setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex,
|
||||
if (!setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex,
|
||||
numSrcLUT, icm,
|
||||
pix, off, scansize, bct,
|
||||
bct.getDataOffset(0)) == 0) {
|
||||
bct.getDataOffset(0))) {
|
||||
convertToRGB();
|
||||
}
|
||||
else {
|
||||
@ -470,9 +470,14 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
|
||||
if (s_useNative) {
|
||||
// Note that setICMpixels modifies the raster directly
|
||||
// so we must mark it as changed afterwards
|
||||
setICMpixels(x, y, w, h, srcLUT, pix, off, scansize,
|
||||
iraster);
|
||||
if (setICMpixels(x, y, w, h, srcLUT, pix, off, scansize,
|
||||
iraster))
|
||||
{
|
||||
iraster.markDirty();
|
||||
} else {
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int[] storage = new int[w*h];
|
||||
|
@ -208,7 +208,7 @@ public class IntegerComponentRaster extends SunWritableRaster {
|
||||
" SinglePixelPackedSampleModel");
|
||||
}
|
||||
|
||||
verify(false);
|
||||
verify();
|
||||
}
|
||||
|
||||
|
||||
@ -629,16 +629,26 @@ public class IntegerComponentRaster extends SunWritableRaster {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the layout parameters are consistent with
|
||||
* the data. If strictCheck
|
||||
* is false, this method will check for ArrayIndexOutOfBounds conditions. If
|
||||
* strictCheck is true, this method will check for additional error
|
||||
* conditions such as line wraparound (width of a line greater than
|
||||
* the scanline stride).
|
||||
* @return String Error string, if the layout is incompatible with
|
||||
* the data. Otherwise returns null.
|
||||
* Verify that the layout parameters are consistent with the data.
|
||||
*
|
||||
* The method verifies whether scanline stride and pixel stride do not
|
||||
* cause an integer overflow during calculation of a position of the pixel
|
||||
* in data buffer. It also verifies whether the data buffer has enough data
|
||||
* to correspond the raster layout attributes.
|
||||
*
|
||||
* @throws RasterFormatException if an integer overflow is detected,
|
||||
* or if data buffer has not enough capacity.
|
||||
*/
|
||||
private void verify (boolean strictCheck) {
|
||||
protected final void verify() {
|
||||
/* Need to re-verify the dimensions since a sample model may be
|
||||
* specified to the constructor
|
||||
*/
|
||||
if (width <= 0 || height <= 0 ||
|
||||
height > (Integer.MAX_VALUE / width))
|
||||
{
|
||||
throw new RasterFormatException("Invalid raster dimension");
|
||||
}
|
||||
|
||||
if (dataOffsets[0] < 0) {
|
||||
throw new RasterFormatException("Data offset ("+dataOffsets[0]+
|
||||
") must be >= 0");
|
||||
@ -647,17 +657,46 @@ public class IntegerComponentRaster extends SunWritableRaster {
|
||||
int maxSize = 0;
|
||||
int size;
|
||||
|
||||
// we can be sure that width and height are greater than 0
|
||||
if (scanlineStride < 0 ||
|
||||
scanlineStride > (Integer.MAX_VALUE / height))
|
||||
{
|
||||
// integer overflow
|
||||
throw new RasterFormatException("Incorrect scanline stride: "
|
||||
+ scanlineStride);
|
||||
}
|
||||
int lastScanOffset = (height - 1) * scanlineStride;
|
||||
|
||||
if (pixelStride < 0 ||
|
||||
pixelStride > (Integer.MAX_VALUE / width))
|
||||
{
|
||||
// integer overflow
|
||||
throw new RasterFormatException("Incorrect pixel stride: "
|
||||
+ pixelStride);
|
||||
}
|
||||
int lastPixelOffset = (width - 1) * pixelStride;
|
||||
|
||||
if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
|
||||
// integer overflow
|
||||
throw new RasterFormatException("Incorrect raster attributes");
|
||||
}
|
||||
lastPixelOffset += lastScanOffset;
|
||||
|
||||
for (int i = 0; i < numDataElements; i++) {
|
||||
size = (height-1)*scanlineStride + (width-1)*pixelStride +
|
||||
dataOffsets[i];
|
||||
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
|
||||
throw new RasterFormatException("Incorrect band offset: "
|
||||
+ dataOffsets[i]);
|
||||
}
|
||||
|
||||
size = lastPixelOffset + dataOffsets[i];
|
||||
|
||||
if (size > maxSize) {
|
||||
maxSize = size;
|
||||
}
|
||||
}
|
||||
if (data.length < maxSize) {
|
||||
throw new RasterFormatException("Data array too small (should be "+
|
||||
maxSize
|
||||
+" but is "+data.length+" )");
|
||||
throw new RasterFormatException("Data array too small (should be "
|
||||
+ maxSize + " )");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ public class IntegerInterleavedRaster extends IntegerComponentRaster {
|
||||
throw new RasterFormatException("IntegerInterleavedRasters must have"+
|
||||
" SinglePixelPackedSampleModel");
|
||||
}
|
||||
verify(false);
|
||||
verify();
|
||||
}
|
||||
|
||||
|
||||
@ -540,31 +540,6 @@ public class IntegerInterleavedRaster extends IntegerComponentRaster {
|
||||
return createCompatibleWritableRaster(width,height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the layout parameters are consistent with
|
||||
* the data. If strictCheck
|
||||
* is false, this method will check for ArrayIndexOutOfBounds conditions. If
|
||||
* strictCheck is true, this method will check for additional error
|
||||
* conditions such as line wraparound (width of a line greater than
|
||||
* the scanline stride).
|
||||
* @return String Error string, if the layout is incompatible with
|
||||
* the data. Otherwise returns null.
|
||||
*/
|
||||
private void verify (boolean strictCheck) {
|
||||
int maxSize = 0;
|
||||
int size;
|
||||
|
||||
size = (height-1)*scanlineStride + (width-1) + dataOffsets[0];
|
||||
if (size > maxSize) {
|
||||
maxSize = size;
|
||||
}
|
||||
if (data.length < maxSize) {
|
||||
throw new RasterFormatException("Data array too small (should be "+
|
||||
maxSize
|
||||
+" but is "+data.length+" )");
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new String ("IntegerInterleavedRaster: width = "+width
|
||||
+" height = " + height
|
||||
|
@ -802,6 +802,15 @@ public class ShortComponentRaster extends SunWritableRaster {
|
||||
* or if data buffer has not enough capacity.
|
||||
*/
|
||||
protected final void verify() {
|
||||
/* Need to re-verify the dimensions since a sample model may be
|
||||
* specified to the constructor
|
||||
*/
|
||||
if (width <= 0 || height <= 0 ||
|
||||
height > (Integer.MAX_VALUE / width))
|
||||
{
|
||||
throw new RasterFormatException("Invalid raster dimension");
|
||||
}
|
||||
|
||||
for (int i = 0; i < dataOffsets.length; i++) {
|
||||
if (dataOffsets[i] < 0) {
|
||||
throw new RasterFormatException("Data offsets for band " + i
|
||||
@ -839,12 +848,13 @@ public class ShortComponentRaster extends SunWritableRaster {
|
||||
lastPixelOffset += lastScanOffset;
|
||||
|
||||
for (int i = 0; i < numDataElements; i++) {
|
||||
size = lastPixelOffset + dataOffsets[i];
|
||||
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
|
||||
throw new RasterFormatException("Incorrect band offset: "
|
||||
+ dataOffsets[i]);
|
||||
}
|
||||
|
||||
size = lastPixelOffset + dataOffsets[i];
|
||||
|
||||
if (size > maxSize) {
|
||||
maxSize = size;
|
||||
}
|
||||
|
@ -841,7 +841,6 @@ abstract class CMap {
|
||||
|
||||
CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) {
|
||||
|
||||
System.err.println("WARNING: CMapFormat8 is untested.");
|
||||
bbuffer.position(offset+6);
|
||||
CharBuffer buffer = bbuffer.asCharBuffer();
|
||||
firstCode = buffer.get();
|
||||
@ -884,7 +883,6 @@ abstract class CMap {
|
||||
|
||||
CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) {
|
||||
|
||||
System.err.println("WARNING: CMapFormat8 is untested.");
|
||||
bbuffer.position(12);
|
||||
bbuffer.get(is32);
|
||||
nGroups = bbuffer.getInt();
|
||||
@ -915,7 +913,6 @@ abstract class CMap {
|
||||
|
||||
CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) {
|
||||
|
||||
System.err.println("WARNING: CMapFormat10 is untested.");
|
||||
firstCode = bbuffer.getInt() & INTMASK;
|
||||
entryCount = bbuffer.getInt() & INTMASK;
|
||||
bbuffer.position(offset+20);
|
||||
|
@ -85,45 +85,72 @@ class LCMSImageLayout {
|
||||
private boolean imageAtOnce = false;
|
||||
Object dataArray;
|
||||
|
||||
private LCMSImageLayout(int np, int pixelType, int pixelSize) {
|
||||
private int dataArrayLength; /* in bytes */
|
||||
|
||||
private LCMSImageLayout(int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this.pixelType = pixelType;
|
||||
width = np;
|
||||
height = 1;
|
||||
nextRowOffset = np * pixelSize;
|
||||
nextRowOffset = safeMult(pixelSize, np);
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
private LCMSImageLayout(int width, int height, int pixelType,
|
||||
int pixelSize) {
|
||||
int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this.pixelType = pixelType;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
nextRowOffset = width * pixelSize;
|
||||
nextRowOffset = safeMult(pixelSize, width);
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) {
|
||||
|
||||
public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this(np, pixelType, pixelSize);
|
||||
dataType = DT_BYTE;
|
||||
dataArray = data;
|
||||
dataArrayLength = data.length;
|
||||
|
||||
verify();
|
||||
}
|
||||
|
||||
public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) {
|
||||
public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this(np, pixelType, pixelSize);
|
||||
dataType = DT_SHORT;
|
||||
dataArray = data;
|
||||
dataArrayLength = 2 * data.length;
|
||||
|
||||
verify();
|
||||
}
|
||||
|
||||
public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) {
|
||||
public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this(np, pixelType, pixelSize);
|
||||
dataType = DT_INT;
|
||||
dataArray = data;
|
||||
dataArrayLength = 4 * data.length;
|
||||
|
||||
verify();
|
||||
}
|
||||
|
||||
public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) {
|
||||
public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this(np, pixelType, pixelSize);
|
||||
dataType = DT_DOUBLE;
|
||||
dataArray = data;
|
||||
dataArrayLength = 8 * data.length;
|
||||
|
||||
verify();
|
||||
}
|
||||
|
||||
private LCMSImageLayout() {
|
||||
@ -132,7 +159,7 @@ class LCMSImageLayout {
|
||||
/* This method creates a layout object for given image.
|
||||
* Returns null if the image is not supported by current implementation.
|
||||
*/
|
||||
public static LCMSImageLayout createImageLayout(BufferedImage image) {
|
||||
public static LCMSImageLayout createImageLayout(BufferedImage image) throws ImageLayoutException {
|
||||
LCMSImageLayout l = new LCMSImageLayout();
|
||||
|
||||
switch (image.getType()) {
|
||||
@ -193,9 +220,10 @@ class LCMSImageLayout {
|
||||
do {
|
||||
IntegerComponentRaster intRaster = (IntegerComponentRaster)
|
||||
image.getRaster();
|
||||
l.nextRowOffset = intRaster.getScanlineStride() * 4;
|
||||
l.offset = intRaster.getDataOffset(0) * 4;
|
||||
l.nextRowOffset = safeMult(4, intRaster.getScanlineStride());
|
||||
l.offset = safeMult(4, intRaster.getDataOffset(0));
|
||||
l.dataArray = intRaster.getDataStorage();
|
||||
l.dataArrayLength = 4 * intRaster.getDataStorage().length;
|
||||
l.dataType = DT_INT;
|
||||
|
||||
if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) {
|
||||
@ -213,6 +241,7 @@ class LCMSImageLayout {
|
||||
int firstBand = image.getSampleModel().getNumBands() - 1;
|
||||
l.offset = byteRaster.getDataOffset(firstBand);
|
||||
l.dataArray = byteRaster.getDataStorage();
|
||||
l.dataArrayLength = byteRaster.getDataStorage().length;
|
||||
l.dataType = DT_BYTE;
|
||||
if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
|
||||
l.imageAtOnce = true;
|
||||
@ -225,6 +254,7 @@ class LCMSImageLayout {
|
||||
ByteComponentRaster byteRaster = (ByteComponentRaster)
|
||||
image.getRaster();
|
||||
l.nextRowOffset = byteRaster.getScanlineStride();
|
||||
l.dataArrayLength = byteRaster.getDataStorage().length;
|
||||
l.offset = byteRaster.getDataOffset(0);
|
||||
l.dataArray = byteRaster.getDataStorage();
|
||||
l.dataType = DT_BYTE;
|
||||
@ -239,9 +269,10 @@ class LCMSImageLayout {
|
||||
do {
|
||||
ShortComponentRaster shortRaster = (ShortComponentRaster)
|
||||
image.getRaster();
|
||||
l.nextRowOffset = shortRaster.getScanlineStride() * 2;
|
||||
l.offset = shortRaster.getDataOffset(0) * 2;
|
||||
l.nextRowOffset = safeMult(2, shortRaster.getScanlineStride());
|
||||
l.offset = safeMult(2, shortRaster.getDataOffset(0));
|
||||
l.dataArray = shortRaster.getDataStorage();
|
||||
l.dataArrayLength = 2 * shortRaster.getDataStorage().length;
|
||||
l.dataType = DT_SHORT;
|
||||
|
||||
if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) {
|
||||
@ -252,6 +283,7 @@ class LCMSImageLayout {
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
l.verify();
|
||||
return l;
|
||||
}
|
||||
|
||||
@ -293,6 +325,46 @@ class LCMSImageLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private void verify() throws ImageLayoutException {
|
||||
|
||||
if (offset < 0 || offset >= dataArrayLength) {
|
||||
throw new ImageLayoutException("Invalid image layout");
|
||||
}
|
||||
|
||||
int lastPixelOffset = safeMult(nextRowOffset, (height - 1));
|
||||
|
||||
lastPixelOffset = safeAdd(lastPixelOffset, (width - 1));
|
||||
|
||||
int off = safeAdd(offset, lastPixelOffset);
|
||||
|
||||
if (off < 0 || off >= dataArrayLength) {
|
||||
throw new ImageLayoutException("Invalid image layout");
|
||||
}
|
||||
}
|
||||
|
||||
static int safeAdd(int a, int b) throws ImageLayoutException {
|
||||
long res = a;
|
||||
res += b;
|
||||
if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
|
||||
throw new ImageLayoutException("Invalid image layout");
|
||||
}
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
static int safeMult(int a, int b) throws ImageLayoutException {
|
||||
long res = a;
|
||||
res *= b;
|
||||
if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
|
||||
throw new ImageLayoutException("Invalid image layout");
|
||||
}
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
public static class ImageLayoutException extends Exception {
|
||||
public ImageLayoutException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
public static LCMSImageLayout createImageLayout(Raster r) {
|
||||
LCMSImageLayout l = new LCMSImageLayout();
|
||||
if (r instanceof ByteComponentRaster) {
|
||||
|
@ -51,6 +51,7 @@ import java.awt.image.SinglePixelPackedSampleModel;
|
||||
import java.awt.image.ComponentSampleModel;
|
||||
import sun.java2d.cmm.*;
|
||||
import sun.java2d.cmm.lcms.*;
|
||||
import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException;
|
||||
|
||||
|
||||
public class LCMSTransform implements ColorTransform {
|
||||
@ -162,6 +163,7 @@ public class LCMSTransform implements ColorTransform {
|
||||
|
||||
public void colorConvert(BufferedImage src, BufferedImage dst) {
|
||||
LCMSImageLayout srcIL, dstIL;
|
||||
try {
|
||||
|
||||
dstIL = LCMSImageLayout.createImageLayout(dst);
|
||||
|
||||
@ -172,6 +174,9 @@ public class LCMSTransform implements ColorTransform {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert images");
|
||||
}
|
||||
|
||||
Raster srcRas = src.getRaster();
|
||||
WritableRaster dstRas = dst.getRaster();
|
||||
@ -228,6 +233,7 @@ public class LCMSTransform implements ColorTransform {
|
||||
}
|
||||
int idx;
|
||||
// TODO check for src npixels = dst npixels
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
@ -236,6 +242,9 @@ public class LCMSTransform implements ColorTransform {
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert images");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++) {
|
||||
// convert src scanline
|
||||
@ -284,6 +293,7 @@ public class LCMSTransform implements ColorTransform {
|
||||
alpha = new float[w];
|
||||
}
|
||||
int idx;
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
@ -293,7 +303,9 @@ public class LCMSTransform implements ColorTransform {
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
|
||||
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert images");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++) {
|
||||
// convert src scanline
|
||||
@ -402,6 +414,7 @@ public class LCMSTransform implements ColorTransform {
|
||||
short[] srcLine = new short[w * srcNumBands];
|
||||
short[] dstLine = new short[w * dstNumBands];
|
||||
int idx;
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
@ -411,7 +424,9 @@ public class LCMSTransform implements ColorTransform {
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
|
||||
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert rasters");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++, ys++, yd++) {
|
||||
// get src scanline
|
||||
@ -502,6 +517,7 @@ public class LCMSTransform implements ColorTransform {
|
||||
byte[] dstLine = new byte[w * dstNumBands];
|
||||
int idx;
|
||||
// TODO check for src npixels = dst npixels
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
@ -510,7 +526,9 @@ public class LCMSTransform implements ColorTransform {
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
|
||||
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert rasters");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++, ys++, yd++) {
|
||||
// get src scanline
|
||||
@ -542,6 +560,8 @@ public class LCMSTransform implements ColorTransform {
|
||||
short[] srcLine = new short[w * srcNumBands];
|
||||
short[] dstLine = new short[w * dstNumBands];
|
||||
int idx;
|
||||
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
@ -551,7 +571,9 @@ public class LCMSTransform implements ColorTransform {
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
|
||||
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert rasters");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++, ys++, yd++) {
|
||||
// get src scanline
|
||||
@ -592,6 +614,7 @@ public class LCMSTransform implements ColorTransform {
|
||||
dst = new short [(src.length/getNumInComponents())*getNumOutComponents()];
|
||||
}
|
||||
|
||||
try {
|
||||
LCMSImageLayout srcIL = new LCMSImageLayout(
|
||||
src, src.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
@ -605,6 +628,9 @@ public class LCMSTransform implements ColorTransform {
|
||||
doTransform(srcIL, dstIL);
|
||||
|
||||
return dst;
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert data");
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] colorConvert(byte[] src, byte[] dst) {
|
||||
@ -612,6 +638,7 @@ public class LCMSTransform implements ColorTransform {
|
||||
dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()];
|
||||
}
|
||||
|
||||
try {
|
||||
LCMSImageLayout srcIL = new LCMSImageLayout(
|
||||
src, src.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
@ -625,5 +652,8 @@ public class LCMSTransform implements ColorTransform {
|
||||
doTransform(srcIL, dstIL);
|
||||
|
||||
return dst;
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ package sun.misc;
|
||||
import java.security.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
|
||||
/**
|
||||
* A collection of methods for performing low-level, unsafe operations.
|
||||
@ -80,9 +83,10 @@ public final class Unsafe {
|
||||
* <code>checkPropertiesAccess</code> method doesn't allow
|
||||
* access to the system properties.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Unsafe getUnsafe() {
|
||||
Class<?> cc = sun.reflect.Reflection.getCallerClass(2);
|
||||
if (!VM.isSystemDomainLoader(cc.getClassLoader()))
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
if (!VM.isSystemDomainLoader(caller.getClassLoader()))
|
||||
throw new SecurityException("Unsafe");
|
||||
return theUnsafe;
|
||||
}
|
||||
@ -817,8 +821,6 @@ public final class Unsafe {
|
||||
ClassLoader loader,
|
||||
ProtectionDomain protectionDomain);
|
||||
|
||||
public native Class<?> defineClass(String name, byte[] b, int off, int len);
|
||||
|
||||
/**
|
||||
* Define a class but do not make it known to the class loader or system dictionary.
|
||||
* <p>
|
||||
|
41
jdk/src/share/classes/sun/reflect/CallerSensitive.java
Normal file
41
jdk/src/share/classes/sun/reflect/CallerSensitive.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 sun.reflect;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
/**
|
||||
* A method annotated @CallerSensitive is sensitive to its calling class,
|
||||
* via {@link sun.reflect.Reflection#getCallerClass Reflection.getCallerClass},
|
||||
* or via some equivalent.
|
||||
*
|
||||
* @author John R. Rose
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({CONSTRUCTOR, METHOD})
|
||||
public @interface CallerSensitive {
|
||||
}
|
@ -51,16 +51,11 @@ public class Reflection {
|
||||
methodFilterMap = new HashMap<>();
|
||||
}
|
||||
|
||||
/** Returns the class of the method <code>realFramesToSkip</code>
|
||||
frames up the stack (zero-based), ignoring frames associated
|
||||
with java.lang.reflect.Method.invoke() and its implementation.
|
||||
The first frame is that associated with this method, so
|
||||
<code>getCallerClass(0)</code> returns the Class object for
|
||||
sun.reflect.Reflection. Frames associated with
|
||||
java.lang.reflect.Method.invoke() and its implementation are
|
||||
completely ignored and do not count toward the number of "real"
|
||||
frames skipped. */
|
||||
public static native Class<?> getCallerClass(int realFramesToSkip);
|
||||
/** Returns the class of the caller of the method calling this method,
|
||||
ignoring frames associated with java.lang.reflect.Method.invoke()
|
||||
and its implementation. */
|
||||
@CallerSensitive
|
||||
public static native Class<?> getCallerClass();
|
||||
|
||||
/** Retrieves the access flags written to the class file. For
|
||||
inner classes these flags may differ from those returned by
|
||||
@ -321,4 +316,27 @@ public class Reflection {
|
||||
}
|
||||
return newMembers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given method is caller-sensitive and the declaring class
|
||||
* is defined by either the bootstrap class loader or extension class loader.
|
||||
*/
|
||||
public static boolean isCallerSensitive(Method m) {
|
||||
final ClassLoader loader = m.getDeclaringClass().getClassLoader();
|
||||
if (sun.misc.VM.isSystemDomainLoader(loader) || isExtClassLoader(loader)) {
|
||||
return m.isAnnotationPresent(CallerSensitive.class);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isExtClassLoader(ClassLoader loader) {
|
||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
while (cl != null) {
|
||||
if (cl.getParent() == null && cl == loader) {
|
||||
return true;
|
||||
}
|
||||
cl = cl.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -46,8 +46,28 @@ import sun.misc.IOUtils;
|
||||
|
||||
|
||||
class Trampoline {
|
||||
static {
|
||||
if (Trampoline.class.getClassLoader() == null) {
|
||||
throw new Error(
|
||||
"Trampoline must not be defined by the bootstrap classloader");
|
||||
}
|
||||
}
|
||||
|
||||
private static void ensureInvocableMethod(Method m)
|
||||
throws InvocationTargetException
|
||||
{
|
||||
Class<?> clazz = m.getDeclaringClass();
|
||||
if (clazz.equals(AccessController.class) ||
|
||||
clazz.equals(Method.class) ||
|
||||
clazz.getName().startsWith("java.lang.invoke."))
|
||||
throw new InvocationTargetException(
|
||||
new UnsupportedOperationException("invocation not supported"));
|
||||
}
|
||||
|
||||
private static Object invoke(Method m, Object obj, Object[] params)
|
||||
throws InvocationTargetException, IllegalAccessException {
|
||||
throws InvocationTargetException, IllegalAccessException
|
||||
{
|
||||
ensureInvocableMethod(m);
|
||||
return m.invoke(obj, params);
|
||||
}
|
||||
}
|
||||
@ -251,16 +271,6 @@ public final class MethodUtil extends SecureClassLoader {
|
||||
*/
|
||||
public static Object invoke(Method m, Object obj, Object[] params)
|
||||
throws InvocationTargetException, IllegalAccessException {
|
||||
if (m.getDeclaringClass().equals(AccessController.class) ||
|
||||
(m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.class)
|
||||
&& m.getName().equals("lookup")) ||
|
||||
(m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.Lookup.class)
|
||||
&& (m.getName().startsWith("find") ||
|
||||
m.getName().startsWith("bind") ||
|
||||
m.getName().startsWith("unreflect"))) ||
|
||||
m.getDeclaringClass().equals(Method.class))
|
||||
throw new InvocationTargetException(
|
||||
new UnsupportedOperationException("invocation not supported"));
|
||||
try {
|
||||
return bounce.invoke(null, new Object[] {m, obj, params});
|
||||
} catch (InvocationTargetException ie) {
|
||||
@ -293,7 +303,7 @@ public final class MethodUtil extends SecureClassLoader {
|
||||
Method.class, Object.class, Object[].class
|
||||
};
|
||||
Method b = t.getDeclaredMethod("invoke", types);
|
||||
((AccessibleObject)b).setAccessible(true);
|
||||
b.setAccessible(true);
|
||||
return b;
|
||||
}
|
||||
});
|
||||
|
@ -55,13 +55,19 @@ import java.rmi.server.RMIClassLoader;
|
||||
public class MarshalInputStream extends ObjectInputStream {
|
||||
|
||||
/**
|
||||
* value of "java.rmi.server.useCodebaseOnly" property,
|
||||
* Value of "java.rmi.server.useCodebaseOnly" property,
|
||||
* as cached at class initialization time.
|
||||
*
|
||||
* The default value is true. That is, the value is true
|
||||
* if the property is absent or is not equal to "false".
|
||||
* The value is only false when the property is present
|
||||
* and is equal to "false".
|
||||
*/
|
||||
private static final boolean useCodebaseOnlyProperty =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetBooleanAction(
|
||||
"java.rmi.server.useCodebaseOnly")).booleanValue();
|
||||
! java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction(
|
||||
"java.rmi.server.useCodebaseOnly", "true"))
|
||||
.equalsIgnoreCase("false");
|
||||
|
||||
/** table to hold sun classes to which access is explicitly permitted */
|
||||
protected static Map<String, Class<?>> permittedSunClasses
|
||||
|
@ -204,7 +204,7 @@ public class KrbApReq {
|
||||
int usage)
|
||||
throws KrbException, IOException {
|
||||
|
||||
ctime = new KerberosTime(KerberosTime.NOW);
|
||||
ctime = KerberosTime.now();
|
||||
init(options,
|
||||
tgs_creds.ticket,
|
||||
tgs_creds.key,
|
||||
@ -287,14 +287,14 @@ public class KrbApReq {
|
||||
authenticator = new Authenticator(temp2);
|
||||
ctime = authenticator.ctime;
|
||||
cusec = authenticator.cusec;
|
||||
authenticator.ctime.setMicroSeconds(authenticator.cusec);
|
||||
authenticator.ctime =
|
||||
authenticator.ctime.withMicroSeconds(authenticator.cusec);
|
||||
|
||||
if (!authenticator.cname.equals(enc_ticketPart.cname)) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_BADMATCH);
|
||||
}
|
||||
|
||||
KerberosTime currTime = new KerberosTime(KerberosTime.NOW);
|
||||
if (!authenticator.ctime.inClockSkew(currTime))
|
||||
if (!authenticator.ctime.inClockSkew())
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
|
||||
|
||||
// start to check if it is a replay attack.
|
||||
@ -304,7 +304,7 @@ public class KrbApReq {
|
||||
if (table.get(time, authenticator.cname.toString()) != null) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_REPEAT);
|
||||
} else {
|
||||
table.put(client, time, currTime.getTime());
|
||||
table.put(client, time, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
if (initiator != null) {
|
||||
@ -329,7 +329,7 @@ public class KrbApReq {
|
||||
// else
|
||||
// save authenticator to check for later
|
||||
|
||||
KerberosTime now = new KerberosTime(KerberosTime.NOW);
|
||||
KerberosTime now = KerberosTime.now();
|
||||
|
||||
if ((enc_ticketPart.starttime != null &&
|
||||
enc_ticketPart.starttime.greaterThanWRTClockSkew(now)) ||
|
||||
|
@ -71,12 +71,18 @@ abstract class KrbAppMessage {
|
||||
}
|
||||
|
||||
if (packetTimestamp != null) {
|
||||
packetTimestamp.setMicroSeconds(packetUsec);
|
||||
if (!packetTimestamp.inClockSkew())
|
||||
if (packetUsec != null) {
|
||||
packetTimestamp =
|
||||
packetTimestamp.withMicroSeconds(packetUsec.intValue());
|
||||
}
|
||||
if (!packetTimestamp.inClockSkew()) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
|
||||
} else
|
||||
if (timestampRequired)
|
||||
}
|
||||
} else {
|
||||
if (timestampRequired) {
|
||||
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX check replay cache
|
||||
// if (rcache.repeated(packetTimestamp, packetUsec, packetSAddress))
|
||||
|
@ -103,7 +103,7 @@ public class KrbCred {
|
||||
delegatedCreds.renewTill, tgService,
|
||||
delegatedCreds.cAddr);
|
||||
|
||||
timeStamp = new KerberosTime(KerberosTime.NOW);
|
||||
timeStamp = KerberosTime.now();
|
||||
KrbCredInfo[] credInfos = {credInfo};
|
||||
EncKrbCredPart encPart =
|
||||
new EncKrbCredPart(credInfos,
|
||||
|
@ -147,8 +147,7 @@ public class KrbTgsReq {
|
||||
|
||||
princName = cname;
|
||||
servName = sname;
|
||||
ctime = new KerberosTime(KerberosTime.NOW);
|
||||
|
||||
ctime = KerberosTime.now();
|
||||
|
||||
// check if they are valid arguments. The optional fields
|
||||
// should be consistent with settings in KDCOptions.
|
||||
|
@ -30,18 +30,20 @@
|
||||
|
||||
package sun.security.krb5.internal;
|
||||
|
||||
import java.util.TimeZone;
|
||||
import sun.security.util.*;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.Config;
|
||||
import sun.security.krb5.KrbException;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Calendar;
|
||||
import sun.security.util.DerInputStream;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Implements the ASN.1 KerberosTime type.
|
||||
* Implements the ASN.1 KerberosTime type. This is an immutable class.
|
||||
*
|
||||
* <xmp>
|
||||
* KerberosTime ::= GeneralizedTime -- with no fractional seconds
|
||||
@ -62,55 +64,38 @@ import java.io.IOException;
|
||||
* same class can be used as a precise timestamp in Authenticator etc.
|
||||
*/
|
||||
|
||||
public class KerberosTime implements Cloneable {
|
||||
public class KerberosTime {
|
||||
|
||||
private long kerberosTime; // milliseconds since epoch, a Date.getTime() value
|
||||
private int microSeconds; // the last three digits of the microsecond value
|
||||
private final long kerberosTime; // milliseconds since epoch, Date.getTime()
|
||||
private final int microSeconds; // last 3 digits of the real microsecond
|
||||
|
||||
// The time when this class is loaded. Used in setNow()
|
||||
private static long initMilli = System.currentTimeMillis();
|
||||
private static long initMicro = System.nanoTime() / 1000;
|
||||
|
||||
private static long syncTime;
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public static final boolean NOW = true;
|
||||
public static final boolean UNADJUSTED_NOW = false;
|
||||
|
||||
public KerberosTime(long time) {
|
||||
kerberosTime = time;
|
||||
}
|
||||
|
||||
// Do not make this public. It's a little confusing that micro
|
||||
// is only the last 3 digits of microsecond.
|
||||
private KerberosTime(long time, int micro) {
|
||||
kerberosTime = time;
|
||||
microSeconds = micro;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new KerberosTime(kerberosTime, microSeconds);
|
||||
/**
|
||||
* Creates a KerberosTime object from milliseconds since epoch.
|
||||
*/
|
||||
public KerberosTime(long time) {
|
||||
this(time, 0);
|
||||
}
|
||||
|
||||
// This constructor is used in the native code
|
||||
// src/windows/native/sun/security/krb5/NativeCreds.c
|
||||
public KerberosTime(String time) throws Asn1Exception {
|
||||
kerberosTime = toKerberosTime(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KerberosTime object.
|
||||
* @param encoding a DER-encoded data.
|
||||
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
|
||||
* @exception IOException if an I/O error occurs while reading encoded data.
|
||||
*/
|
||||
public KerberosTime(DerValue encoding) throws Asn1Exception, IOException {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
Date temp = encoding.getGeneralizedTime();
|
||||
kerberosTime = temp.getTime();
|
||||
this(toKerberosTime(time), 0);
|
||||
}
|
||||
|
||||
private static long toKerberosTime(String time) throws Asn1Exception {
|
||||
// this method only used by KerberosTime class.
|
||||
|
||||
// ASN.1 GeneralizedTime format:
|
||||
|
||||
// "19700101000000Z"
|
||||
@ -133,30 +118,34 @@ public class KerberosTime implements Cloneable {
|
||||
Integer.parseInt(time.substring(8, 10)),
|
||||
Integer.parseInt(time.substring(10, 12)),
|
||||
Integer.parseInt(time.substring(12, 14)));
|
||||
|
||||
//The Date constructor assumes the setting are local relative
|
||||
//and converts the time to UTC before storing it. Since we
|
||||
//want the internal representation to correspond to local
|
||||
//and not UTC time we subtract the UTC time offset.
|
||||
return (calendar.getTime().getTime());
|
||||
|
||||
}
|
||||
|
||||
// should be moved to sun.security.krb5.util class
|
||||
public static String zeroPad(String s, int length) {
|
||||
StringBuffer temp = new StringBuffer(s);
|
||||
while (temp.length() < length)
|
||||
temp.insert(0, '0');
|
||||
return temp.toString();
|
||||
return calendar.getTimeInMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a KerberosTime object from a Date object.
|
||||
*/
|
||||
public KerberosTime(Date time) {
|
||||
kerberosTime = time.getTime(); // (time.getTimezoneOffset() * 60000L);
|
||||
this(time.getTime(), 0);
|
||||
}
|
||||
|
||||
public KerberosTime(boolean initToNow) {
|
||||
if (initToNow) {
|
||||
setNow();
|
||||
/**
|
||||
* Creates a KerberosTime object for now. It uses System.nanoTime()
|
||||
* to get a more precise time than "new Date()".
|
||||
*/
|
||||
public static KerberosTime now() {
|
||||
long newMilli = System.currentTimeMillis();
|
||||
long newMicro = System.nanoTime() / 1000;
|
||||
long microElapsed = newMicro - initMicro;
|
||||
long calcMilli = initMilli + microElapsed/1000;
|
||||
if (calcMilli - newMilli > 100 || newMilli - calcMilli > 100) {
|
||||
if (DEBUG) {
|
||||
System.out.println("System time adjusted");
|
||||
}
|
||||
initMilli = newMilli;
|
||||
initMicro = newMicro;
|
||||
return new KerberosTime(newMilli, 0);
|
||||
} else {
|
||||
return new KerberosTime(calcMilli, (int)(microElapsed % 1000));
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,13 +158,13 @@ public class KerberosTime implements Cloneable {
|
||||
calendar.clear();
|
||||
|
||||
calendar.setTimeInMillis(kerberosTime);
|
||||
return zeroPad(Integer.toString(calendar.get(Calendar.YEAR)), 4) +
|
||||
zeroPad(Integer.toString(calendar.get(Calendar.MONTH) + 1), 2) +
|
||||
zeroPad(Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)), 2) +
|
||||
zeroPad(Integer.toString(calendar.get(Calendar.HOUR_OF_DAY)), 2) +
|
||||
zeroPad(Integer.toString(calendar.get(Calendar.MINUTE)), 2) +
|
||||
zeroPad(Integer.toString(calendar.get(Calendar.SECOND)), 2) + 'Z';
|
||||
|
||||
return String.format("%04d%02d%02d%02d%02d%02dZ",
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH) + 1,
|
||||
calendar.get(Calendar.DAY_OF_MONTH),
|
||||
calendar.get(Calendar.HOUR_OF_DAY),
|
||||
calendar.get(Calendar.MINUTE),
|
||||
calendar.get(Calendar.SECOND));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -194,40 +183,8 @@ public class KerberosTime implements Cloneable {
|
||||
return kerberosTime;
|
||||
}
|
||||
|
||||
|
||||
public void setTime(Date time) {
|
||||
kerberosTime = time.getTime(); // (time.getTimezoneOffset() * 60000L);
|
||||
microSeconds = 0;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
kerberosTime = time;
|
||||
microSeconds = 0;
|
||||
}
|
||||
|
||||
public Date toDate() {
|
||||
Date temp = new Date(kerberosTime);
|
||||
temp.setTime(temp.getTime());
|
||||
return temp;
|
||||
}
|
||||
|
||||
public void setNow() {
|
||||
long newMilli = System.currentTimeMillis();
|
||||
long newMicro = System.nanoTime() / 1000;
|
||||
long microElapsed = newMicro - initMicro;
|
||||
long calcMilli = initMilli + microElapsed/1000;
|
||||
if (calcMilli - newMilli > 100 || newMilli - calcMilli > 100) {
|
||||
if (DEBUG) {
|
||||
System.out.println("System time adjusted");
|
||||
}
|
||||
initMilli = newMilli;
|
||||
initMicro = newMicro;
|
||||
setTime(newMilli);
|
||||
microSeconds = 0;
|
||||
} else {
|
||||
setTime(calcMilli);
|
||||
microSeconds = (int)(microElapsed % 1000);
|
||||
}
|
||||
return new Date(kerberosTime);
|
||||
}
|
||||
|
||||
public int getMicroSeconds() {
|
||||
@ -235,45 +192,25 @@ public class KerberosTime implements Cloneable {
|
||||
return temp_long.intValue() + microSeconds;
|
||||
}
|
||||
|
||||
public void setMicroSeconds(int usec) {
|
||||
microSeconds = usec % 1000;
|
||||
Integer temp_int = new Integer(usec);
|
||||
long temp_long = temp_int.longValue() / 1000L;
|
||||
kerberosTime = kerberosTime - (kerberosTime % 1000L) + temp_long;
|
||||
/**
|
||||
* Returns a new KerberosTime object with the original seconds
|
||||
* and the given microseconds.
|
||||
*/
|
||||
public KerberosTime withMicroSeconds(int usec) {
|
||||
return new KerberosTime(
|
||||
kerberosTime - kerberosTime%1000L + usec/1000L,
|
||||
usec%1000);
|
||||
}
|
||||
|
||||
public void setMicroSeconds(Integer usec) {
|
||||
if (usec != null) {
|
||||
microSeconds = usec.intValue() % 1000;
|
||||
long temp_long = usec.longValue() / 1000L;
|
||||
kerberosTime = kerberosTime - (kerberosTime % 1000L) + temp_long;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean inClockSkew(int clockSkew) {
|
||||
KerberosTime now = new KerberosTime(KerberosTime.NOW);
|
||||
|
||||
if (java.lang.Math.abs(kerberosTime - now.kerberosTime) >
|
||||
clockSkew * 1000L)
|
||||
return false;
|
||||
return true;
|
||||
private boolean inClockSkew(int clockSkew) {
|
||||
return java.lang.Math.abs(kerberosTime - System.currentTimeMillis())
|
||||
<= clockSkew * 1000L;
|
||||
}
|
||||
|
||||
public boolean inClockSkew() {
|
||||
return inClockSkew(getDefaultSkew());
|
||||
}
|
||||
|
||||
public boolean inClockSkew(int clockSkew, KerberosTime now) {
|
||||
if (java.lang.Math.abs(kerberosTime - now.kerberosTime) >
|
||||
clockSkew * 1000L)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean inClockSkew(KerberosTime time) {
|
||||
return inClockSkew(getDefaultSkew(), time);
|
||||
}
|
||||
|
||||
public boolean greaterThanWRTClockSkew(KerberosTime time, int clockSkew) {
|
||||
if ((kerberosTime - time.kerberosTime) > clockSkew * 1000L)
|
||||
return true;
|
||||
@ -317,24 +254,22 @@ public class KerberosTime implements Cloneable {
|
||||
return temp_long.intValue();
|
||||
}
|
||||
|
||||
public void setSeconds(int sec) {
|
||||
Integer temp_int = new Integer(sec);
|
||||
kerberosTime = temp_int.longValue() * 1000L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse (unmarshal) a kerberostime from a DER input stream. This form
|
||||
* parsing might be used when expanding a value which is part of
|
||||
* a constructed sequence and uses explicitly tagged type.
|
||||
*
|
||||
* @exception Asn1Exception on error.
|
||||
* @param data the Der input stream value, which contains one or more marshaled value.
|
||||
* @param data the Der input stream value, which contains
|
||||
* one or more marshaled value.
|
||||
* @param explicitTag tag number.
|
||||
* @param optional indicates if this data field is optional
|
||||
* @return an instance of KerberosTime.
|
||||
*
|
||||
*/
|
||||
public static KerberosTime parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
|
||||
public static KerberosTime parse(
|
||||
DerInputStream data, byte explicitTag, boolean optional)
|
||||
throws Asn1Exception, IOException {
|
||||
if ((optional) && (((byte)data.peekByte() & (byte)0x1F)!= explicitTag))
|
||||
return null;
|
||||
DerValue der = data.getDerValue();
|
||||
@ -343,7 +278,8 @@ public class KerberosTime implements Cloneable {
|
||||
}
|
||||
else {
|
||||
DerValue subDer = der.getData().getDerValue();
|
||||
return new KerberosTime(subDer);
|
||||
Date temp = subDer.getGeneralizedTime();
|
||||
return new KerberosTime(temp.getTime(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,14 +187,10 @@ public class KrbCredInfo {
|
||||
kcred.pname = (PrincipalName)pname.clone();
|
||||
if (flags != null)
|
||||
kcred.flags = (TicketFlags)flags.clone();
|
||||
if (authtime != null)
|
||||
kcred.authtime = (KerberosTime)authtime.clone();
|
||||
if (starttime != null)
|
||||
kcred.starttime = (KerberosTime)starttime.clone();
|
||||
if (endtime != null)
|
||||
kcred.endtime = (KerberosTime)endtime.clone();
|
||||
if (renewTill != null)
|
||||
kcred.renewTill = (KerberosTime)renewTill.clone();
|
||||
kcred.authtime = authtime;
|
||||
kcred.starttime = starttime;
|
||||
kcred.endtime = endtime;
|
||||
kcred.renewTill = renewTill;
|
||||
if (sname != null)
|
||||
kcred.sname = (PrincipalName)sname.clone();
|
||||
if (caddr != null)
|
||||
|
@ -90,7 +90,7 @@ public class LastReqEntry {
|
||||
public Object clone() {
|
||||
LastReqEntry newEntry = new LastReqEntry();
|
||||
newEntry.lrType = lrType;
|
||||
newEntry.lrValue = (KerberosTime)lrValue.clone();
|
||||
newEntry.lrValue = lrValue;
|
||||
return newEntry;
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ public class PAEncTSEnc {
|
||||
}
|
||||
|
||||
public PAEncTSEnc() {
|
||||
KerberosTime now = new KerberosTime(KerberosTime.NOW);
|
||||
KerberosTime now = KerberosTime.now();
|
||||
pATimeStamp = now;
|
||||
pAUSec = new Integer(now.getMicroSeconds());
|
||||
}
|
||||
|
@ -68,14 +68,11 @@ public class Credentials {
|
||||
sname = (PrincipalName) new_sname.clone();
|
||||
key = (EncryptionKey) new_key.clone();
|
||||
|
||||
authtime = (KerberosTime) new_authtime.clone();
|
||||
if (new_starttime != null) {
|
||||
starttime = (KerberosTime) new_starttime.clone();
|
||||
}
|
||||
endtime = (KerberosTime) new_endtime.clone();
|
||||
if (new_renewTill != null) {
|
||||
renewTill = (KerberosTime) new_renewTill.clone();
|
||||
}
|
||||
authtime = new_authtime;
|
||||
starttime = new_starttime;
|
||||
endtime = new_endtime;
|
||||
renewTill = new_renewTill;
|
||||
|
||||
if (new_caddr != null) {
|
||||
caddr = (HostAddresses) new_caddr.clone();
|
||||
}
|
||||
@ -104,14 +101,11 @@ public class Credentials {
|
||||
ticket = (Ticket) kdcRep.ticket.clone();
|
||||
key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
|
||||
flags = (TicketFlags) kdcRep.encKDCRepPart.flags.clone();
|
||||
authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone();
|
||||
if (kdcRep.encKDCRepPart.starttime != null) {
|
||||
starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone();
|
||||
}
|
||||
endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone();
|
||||
if (kdcRep.encKDCRepPart.renewTill != null) {
|
||||
renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone();
|
||||
}
|
||||
authtime = kdcRep.encKDCRepPart.authtime;
|
||||
starttime = kdcRep.encKDCRepPart.starttime;
|
||||
endtime = kdcRep.encKDCRepPart.endtime;
|
||||
renewTill = kdcRep.encKDCRepPart.renewTill;
|
||||
|
||||
sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
|
||||
caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone();
|
||||
secondTicket = (Ticket) new_secondTicket.clone();
|
||||
@ -128,18 +122,10 @@ public class Credentials {
|
||||
sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
|
||||
cname = (PrincipalName) kdcRep.cname.clone();
|
||||
key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
|
||||
authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone();
|
||||
if (kdcRep.encKDCRepPart.starttime != null) {
|
||||
starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone();
|
||||
} else {
|
||||
starttime = null;
|
||||
}
|
||||
endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone();
|
||||
if (kdcRep.encKDCRepPart.renewTill != null) {
|
||||
renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone();
|
||||
} else {
|
||||
renewTill = null;
|
||||
}
|
||||
authtime = kdcRep.encKDCRepPart.authtime;
|
||||
starttime = kdcRep.encKDCRepPart.starttime;
|
||||
endtime = kdcRep.encKDCRepPart.endtime;
|
||||
renewTill = kdcRep.encKDCRepPart.renewTill;
|
||||
// if (kdcRep.msgType == Krb5.KRB_AS_REP) {
|
||||
// isEncInSKey = false;
|
||||
// secondTicket = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2013, 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
|
||||
@ -101,7 +101,7 @@ abstract class SHA2 extends DigestBase {
|
||||
i2bBig4((int)bitsProcessed, buffer, 60);
|
||||
implCompress(buffer, 0);
|
||||
|
||||
i2bBig(state, 0, out, ofs, 32);
|
||||
i2bBig(state, 0, out, ofs, engineGetDigestLength());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -843,5 +843,52 @@ public final class UntrustedCertificates {
|
||||
"zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" +
|
||||
"-----END CERTIFICATE-----");
|
||||
|
||||
//
|
||||
// Revoked code signing certificate w/ a stolen key issued by GoDaddy
|
||||
// used to sign malware
|
||||
//
|
||||
|
||||
// Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT,
|
||||
// O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US
|
||||
// Issuer: SERIALNUMBER=07969287,
|
||||
// CN=Go Daddy Secure Certification Authority,
|
||||
// OU=http://certificates.godaddy.com/repository,
|
||||
// O="GoDaddy.com, Inc.",
|
||||
// L=Scottsdale,
|
||||
// ST=Arizona,
|
||||
// C=US
|
||||
// Serial: 2b:73:43:2a:a8:4f:44
|
||||
add("clearesult-consulting-inc-2AA84F44",
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\n" +
|
||||
"BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY\n" +
|
||||
"BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm\n" +
|
||||
"aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5\n" +
|
||||
"IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky\n" +
|
||||
"ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC\n" +
|
||||
"VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS\n" +
|
||||
"RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh\n" +
|
||||
"BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B\n" +
|
||||
"AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU\n" +
|
||||
"IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277\n" +
|
||||
"p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E\n" +
|
||||
"jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV\n" +
|
||||
"9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/\n" +
|
||||
"U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw\n" +
|
||||
"DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E\n" +
|
||||
"BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n\n" +
|
||||
"ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH\n" +
|
||||
"AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w\n" +
|
||||
"gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk\n" +
|
||||
"eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku\n" +
|
||||
"Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9\n" +
|
||||
"rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB\n" +
|
||||
"XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K\n" +
|
||||
"v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC\n" +
|
||||
"2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP\n" +
|
||||
"4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR\n" +
|
||||
"DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI\n" +
|
||||
"LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU=\n" +
|
||||
"-----END CERTIFICATE-----");
|
||||
}
|
||||
}
|
||||
|
@ -350,16 +350,21 @@ JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim);
|
||||
/*
|
||||
* java.lang.Class and java.lang.ClassLoader
|
||||
*/
|
||||
|
||||
#define JVM_DEPTH -1
|
||||
|
||||
/*
|
||||
* Returns the class in which the code invoking the native method
|
||||
* belongs.
|
||||
* Returns the immediate caller class of the native method invoking
|
||||
* JVM_GetCallerClass. The Method.invoke and other frames due to
|
||||
* reflection machinery are skipped.
|
||||
*
|
||||
* Note that in JDK 1.1, native methods did not create a frame.
|
||||
* In 1.2, they do. Therefore native methods like Class.forName
|
||||
* can no longer look at the current frame for the caller class.
|
||||
* The depth parameter must be -1 (JVM_DEPTH). The caller is expected
|
||||
* to be marked with sun.reflect.CallerSensitive. The JVM will throw
|
||||
* an error if it is not marked propertly.
|
||||
*/
|
||||
JNIEXPORT jclass JNICALL
|
||||
JVM_GetCallerClass(JNIEnv *env, int n);
|
||||
JVM_GetCallerClass(JNIEnv *env, int depth);
|
||||
|
||||
|
||||
/*
|
||||
* Find primitive classes
|
||||
|
@ -177,23 +177,36 @@ keystore.type=jks
|
||||
# corresponding RuntimePermission ("accessClassInPackage."+package) has
|
||||
# been granted.
|
||||
package.access=sun.,\
|
||||
com.sun.xml.internal.bind.,\
|
||||
com.sun.xml.internal.org.jvnet.staxex.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
com.sun.org.glassfish.gmbal.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
jdk.nashorn.tools.
|
||||
|
||||
|
||||
#
|
||||
# List of comma-separated packages that start with or equal this string
|
||||
# will cause a security exception to be thrown when
|
||||
@ -205,23 +218,36 @@ package.access=sun.,\
|
||||
# checkPackageDefinition.
|
||||
#
|
||||
package.definition=sun.,\
|
||||
com.sun.xml.internal.bind.,\
|
||||
com.sun.xml.internal.org.jvnet.staxex.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
com.sun.org.glassfish.gmbal.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
jdk.nashorn.tools.
|
||||
|
||||
|
||||
#
|
||||
# Determines whether this properties file can be appended to
|
||||
# or overridden on the command line via -Djava.security.properties
|
||||
|
@ -178,17 +178,29 @@ keystore.type=jks
|
||||
# corresponding RuntimePermission ("accessClassInPackage."+package) has
|
||||
# been granted.
|
||||
package.access=sun.,\
|
||||
com.sun.xml.internal.bind.,\
|
||||
com.sun.xml.internal.org.jvnet.staxex.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
com.sun.org.glassfish.gmbal.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
jdk.internal.,\
|
||||
@ -207,17 +219,29 @@ package.access=sun.,\
|
||||
# checkPackageDefinition.
|
||||
#
|
||||
package.definition=sun.,\
|
||||
com.sun.xml.internal.bind.,\
|
||||
com.sun.xml.internal.org.jvnet.staxex.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
com.sun.org.glassfish.gmbal.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
jdk.internal.,\
|
||||
|
@ -179,17 +179,29 @@ keystore.type=jks
|
||||
# corresponding RuntimePermission ("accessClassInPackage."+package) has
|
||||
# been granted.
|
||||
package.access=sun.,\
|
||||
com.sun.xml.internal.bind.,\
|
||||
com.sun.xml.internal.org.jvnet.staxex.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
com.sun.org.glassfish.gmbal.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
jdk.internal.,\
|
||||
@ -207,17 +219,29 @@ package.access=sun.,\
|
||||
# checkPackageDefinition.
|
||||
#
|
||||
package.definition=sun.,\
|
||||
com.sun.xml.internal.bind.,\
|
||||
com.sun.xml.internal.org.jvnet.staxex.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
com.sun.org.glassfish.gmbal.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
jdk.internal.,\
|
||||
|
@ -178,22 +178,35 @@ keystore.type=jks
|
||||
# corresponding RuntimePermission ("accessClassInPackage."+package) has
|
||||
# been granted.
|
||||
package.access=sun.,\
|
||||
com.sun.xml.internal.bind.,\
|
||||
com.sun.xml.internal.org.jvnet.staxex.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
com.sun.org.glassfish.gmbal.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
jdk.nashorn.tools.
|
||||
jdk.nashorn.tools.,\
|
||||
com.sun.java.accessibility.
|
||||
|
||||
#
|
||||
# List of comma-separated packages that start with or equal this string
|
||||
@ -206,22 +219,35 @@ package.access=sun.,\
|
||||
# checkPackageDefinition.
|
||||
#
|
||||
package.definition=sun.,\
|
||||
com.sun.xml.internal.bind.,\
|
||||
com.sun.xml.internal.org.jvnet.staxex.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
com.sun.org.glassfish.gmbal.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
jdk.nashorn.tools.
|
||||
jdk.nashorn.tools.,\
|
||||
com.sun.java.accessibility.
|
||||
|
||||
#
|
||||
# Determines whether this properties file can be appended to
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user