Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
9c508616
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9c508616
编写于
9月 11, 2014
作者:
J
jfranck
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8054987: (reflect) Add sharing of annotations between instances of Executable
Reviewed-by: duke
上级
ce704cf0
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
263 addition
and
9 deletion
+263
-9
src/share/classes/java/lang/reflect/Constructor.java
src/share/classes/java/lang/reflect/Constructor.java
+14
-0
src/share/classes/java/lang/reflect/Executable.java
src/share/classes/java/lang/reflect/Executable.java
+15
-5
src/share/classes/java/lang/reflect/Field.java
src/share/classes/java/lang/reflect/Field.java
+15
-4
src/share/classes/java/lang/reflect/Method.java
src/share/classes/java/lang/reflect/Method.java
+14
-0
test/java/lang/reflect/annotationSharing/AnnotationSharing.java
...ava/lang/reflect/annotationSharing/AnnotationSharing.java
+205
-0
未找到文件。
src/share/classes/java/lang/reflect/Constructor.java
浏览文件 @
9c508616
...
@@ -94,8 +94,19 @@ public final class Constructor<T> extends Executable {
...
@@ -94,8 +94,19 @@ public final class Constructor<T> extends Executable {
// For sharing of ConstructorAccessors. This branching structure
// For sharing of ConstructorAccessors. This branching structure
// is currently only two levels deep (i.e., one root Constructor
// is currently only two levels deep (i.e., one root Constructor
// and potentially many Constructor objects pointing to it.)
// and potentially many Constructor objects pointing to it.)
//
// If this branching structure would ever contain cycles, deadlocks can
// occur in annotation code.
private
Constructor
<
T
>
root
;
private
Constructor
<
T
>
root
;
/**
* Used by Excecutable for annotation sharing.
*/
@Override
Executable
getRoot
()
{
return
root
;
}
/**
/**
* Package-private constructor used by ReflectAccess to enable
* Package-private constructor used by ReflectAccess to enable
* instantiation of these objects in Java code from the java.lang
* instantiation of these objects in Java code from the java.lang
...
@@ -132,6 +143,9 @@ public final class Constructor<T> extends Executable {
...
@@ -132,6 +143,9 @@ public final class Constructor<T> extends Executable {
// which implicitly requires that new java.lang.reflect
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects be fabricated for each reflective call on Class
// objects.)
// objects.)
if
(
this
.
root
!=
null
)
throw
new
IllegalArgumentException
(
"Can not copy a non-root Constructor"
);
Constructor
<
T
>
res
=
new
Constructor
<>(
clazz
,
Constructor
<
T
>
res
=
new
Constructor
<>(
clazz
,
parameterTypes
,
parameterTypes
,
exceptionTypes
,
modifiers
,
slot
,
exceptionTypes
,
modifiers
,
slot
,
...
...
src/share/classes/java/lang/reflect/Executable.java
浏览文件 @
9c508616
...
@@ -52,6 +52,11 @@ public abstract class Executable extends AccessibleObject
...
@@ -52,6 +52,11 @@ public abstract class Executable extends AccessibleObject
*/
*/
abstract
byte
[]
getAnnotationBytes
();
abstract
byte
[]
getAnnotationBytes
();
/**
* Accessor method to allow code sharing
*/
abstract
Executable
getRoot
();
/**
/**
* Does the Executable have generic information.
* Does the Executable have generic information.
*/
*/
...
@@ -543,11 +548,16 @@ public abstract class Executable extends AccessibleObject
...
@@ -543,11 +548,16 @@ public abstract class Executable extends AccessibleObject
private
synchronized
Map
<
Class
<?
extends
Annotation
>,
Annotation
>
declaredAnnotations
()
{
private
synchronized
Map
<
Class
<?
extends
Annotation
>,
Annotation
>
declaredAnnotations
()
{
if
(
declaredAnnotations
==
null
)
{
if
(
declaredAnnotations
==
null
)
{
declaredAnnotations
=
AnnotationParser
.
parseAnnotations
(
Executable
root
=
getRoot
();
getAnnotationBytes
(),
if
(
root
!=
null
)
{
sun
.
misc
.
SharedSecrets
.
getJavaLangAccess
().
declaredAnnotations
=
root
.
declaredAnnotations
();
getConstantPool
(
getDeclaringClass
()),
}
else
{
getDeclaringClass
());
declaredAnnotations
=
AnnotationParser
.
parseAnnotations
(
getAnnotationBytes
(),
sun
.
misc
.
SharedSecrets
.
getJavaLangAccess
().
getConstantPool
(
getDeclaringClass
()),
getDeclaringClass
());
}
}
}
return
declaredAnnotations
;
return
declaredAnnotations
;
}
}
...
...
src/share/classes/java/lang/reflect/Field.java
浏览文件 @
9c508616
...
@@ -81,6 +81,9 @@ class Field extends AccessibleObject implements Member {
...
@@ -81,6 +81,9 @@ class Field extends AccessibleObject implements Member {
// For sharing of FieldAccessors. This branching structure is
// For sharing of FieldAccessors. This branching structure is
// currently only two levels deep (i.e., one root Field and
// currently only two levels deep (i.e., one root Field and
// potentially many Field objects pointing to it.)
// potentially many Field objects pointing to it.)
//
// If this branching structure would ever contain cycles, deadlocks can
// occur in annotation code.
private
Field
root
;
private
Field
root
;
// Generics infrastructure
// Generics infrastructure
...
@@ -141,6 +144,9 @@ class Field extends AccessibleObject implements Member {
...
@@ -141,6 +144,9 @@ class Field extends AccessibleObject implements Member {
// which implicitly requires that new java.lang.reflect
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects be fabricated for each reflective call on Class
// objects.)
// objects.)
if
(
this
.
root
!=
null
)
throw
new
IllegalArgumentException
(
"Can not copy a non-root Field"
);
Field
res
=
new
Field
(
clazz
,
name
,
type
,
modifiers
,
slot
,
signature
,
annotations
);
Field
res
=
new
Field
(
clazz
,
name
,
type
,
modifiers
,
slot
,
signature
,
annotations
);
res
.
root
=
this
;
res
.
root
=
this
;
// Might as well eagerly propagate this if already present
// Might as well eagerly propagate this if already present
...
@@ -1137,10 +1143,15 @@ class Field extends AccessibleObject implements Member {
...
@@ -1137,10 +1143,15 @@ class Field extends AccessibleObject implements Member {
private
synchronized
Map
<
Class
<?
extends
Annotation
>,
Annotation
>
declaredAnnotations
()
{
private
synchronized
Map
<
Class
<?
extends
Annotation
>,
Annotation
>
declaredAnnotations
()
{
if
(
declaredAnnotations
==
null
)
{
if
(
declaredAnnotations
==
null
)
{
declaredAnnotations
=
AnnotationParser
.
parseAnnotations
(
Field
root
=
this
.
root
;
annotations
,
sun
.
misc
.
SharedSecrets
.
getJavaLangAccess
().
if
(
root
!=
null
)
{
getConstantPool
(
getDeclaringClass
()),
declaredAnnotations
=
root
.
declaredAnnotations
();
getDeclaringClass
());
}
else
{
declaredAnnotations
=
AnnotationParser
.
parseAnnotations
(
annotations
,
sun
.
misc
.
SharedSecrets
.
getJavaLangAccess
().
getConstantPool
(
getDeclaringClass
()),
getDeclaringClass
());
}
}
}
return
declaredAnnotations
;
return
declaredAnnotations
;
}
}
...
...
src/share/classes/java/lang/reflect/Method.java
浏览文件 @
9c508616
...
@@ -79,6 +79,9 @@ public final class Method extends Executable {
...
@@ -79,6 +79,9 @@ public final class Method extends Executable {
// For sharing of MethodAccessors. This branching structure is
// For sharing of MethodAccessors. This branching structure is
// currently only two levels deep (i.e., one root Method and
// currently only two levels deep (i.e., one root Method and
// potentially many Method objects pointing to it.)
// potentially many Method objects pointing to it.)
//
// If this branching structure would ever contain cycles, deadlocks can
// occur in annotation code.
private
Method
root
;
private
Method
root
;
// Generics infrastructure
// Generics infrastructure
...
@@ -144,6 +147,9 @@ public final class Method extends Executable {
...
@@ -144,6 +147,9 @@ public final class Method extends Executable {
// which implicitly requires that new java.lang.reflect
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects be fabricated for each reflective call on Class
// objects.)
// objects.)
if
(
this
.
root
!=
null
)
throw
new
IllegalArgumentException
(
"Can not copy a non-root Method"
);
Method
res
=
new
Method
(
clazz
,
name
,
parameterTypes
,
returnType
,
Method
res
=
new
Method
(
clazz
,
name
,
parameterTypes
,
returnType
,
exceptionTypes
,
modifiers
,
slot
,
signature
,
exceptionTypes
,
modifiers
,
slot
,
signature
,
annotations
,
parameterAnnotations
,
annotationDefault
);
annotations
,
parameterAnnotations
,
annotationDefault
);
...
@@ -153,6 +159,14 @@ public final class Method extends Executable {
...
@@ -153,6 +159,14 @@ public final class Method extends Executable {
return
res
;
return
res
;
}
}
/**
* Used by Excecutable for annotation sharing.
*/
@Override
Executable
getRoot
()
{
return
root
;
}
@Override
@Override
boolean
hasGenericInformation
()
{
boolean
hasGenericInformation
()
{
return
(
getGenericSignature
()
!=
null
);
return
(
getGenericSignature
()
!=
null
);
...
...
test/java/lang/reflect/annotationSharing/AnnotationSharing.java
0 → 100644
浏览文件 @
9c508616
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8054987
* @summary Test sharing of annotations between Executable/Field instances.
* Sharing should not be noticeable when performing mutating
* operations.
* @run testng AnnotationSharing
*/
import
java.lang.annotation.*
;
import
java.lang.reflect.*
;
import
org.testng.annotations.Test
;
public
class
AnnotationSharing
{
public
static
void
main
(
String
...
args
)
throws
Exception
{
}
@Test
public
void
testMethodSharing
()
throws
Exception
{
Method
[]
m1
=
AnnotationSharing
.
class
.
getMethods
();
Method
[]
m2
=
AnnotationSharing
.
class
.
getMethods
();
validateSharingSafelyObservable
(
m1
,
m2
);
}
@Test
public
void
testDeclaredMethodSharing
()
throws
Exception
{
Method
[]
m3
=
AnnotationSharing
.
class
.
getDeclaredMethods
();
Method
[]
m4
=
AnnotationSharing
.
class
.
getDeclaredMethods
();
validateSharingSafelyObservable
(
m3
,
m4
);
}
@Test
public
void
testFieldSharing
()
throws
Exception
{
Field
[]
f1
=
AnnotationSharing
.
class
.
getFields
();
Field
[]
f2
=
AnnotationSharing
.
class
.
getFields
();
validateSharingSafelyObservable
(
f1
,
f2
);
}
@Test
public
void
testDeclaredFieldsSharing
()
throws
Exception
{
Field
[]
f3
=
AnnotationSharing
.
class
.
getDeclaredFields
();
Field
[]
f4
=
AnnotationSharing
.
class
.
getDeclaredFields
();
validateSharingSafelyObservable
(
f3
,
f4
);
}
@Test
public
void
testMethodSharingOccurs
()
throws
Exception
{
Method
mm1
=
AnnotationSharing
.
class
.
getDeclaredMethod
(
"m"
,
(
Class
<?>[])
null
);
Method
mm2
=
AnnotationSharing
.
class
.
getDeclaredMethod
(
"m"
,
(
Class
<?>[])
null
);
validateAnnotationSharing
(
mm1
,
mm2
);
}
@Test
public
void
testMethodSharingIsSafe
()
throws
Exception
{
Method
mm1
=
AnnotationSharing
.
class
.
getDeclaredMethod
(
"m"
,
(
Class
<?>[])
null
);
Method
mm2
=
AnnotationSharing
.
class
.
getDeclaredMethod
(
"m"
,
(
Class
<?>[])
null
);
validateAnnotationSharingIsSafe
(
mm1
,
mm2
);
validateArrayValues
(
mm1
.
getAnnotation
(
Baz
.
class
),
mm2
.
getAnnotation
(
Baz
.
class
));
}
@Test
public
void
testFieldSharingOccurs
()
throws
Exception
{
Field
ff1
=
AnnotationSharing
.
class
.
getDeclaredField
(
"f"
);
Field
ff2
=
AnnotationSharing
.
class
.
getDeclaredField
(
"f"
);
validateAnnotationSharing
(
ff1
,
ff2
);
}
@Test
public
void
testFieldSharingIsSafe
()
throws
Exception
{
Field
ff1
=
AnnotationSharing
.
class
.
getDeclaredField
(
"f"
);
Field
ff2
=
AnnotationSharing
.
class
.
getDeclaredField
(
"f"
);
validateAnnotationSharingIsSafe
(
ff1
,
ff2
);
validateArrayValues
(
ff1
.
getAnnotation
(
Baz
.
class
),
ff2
.
getAnnotation
(
Baz
.
class
));
}
// Validate that AccessibleObject instances are not shared
private
static
void
validateSharingSafelyObservable
(
AccessibleObject
[]
m1
,
AccessibleObject
[]
m2
)
throws
Exception
{
// Validate that setAccessible works
for
(
AccessibleObject
m
:
m1
)
m
.
setAccessible
(
false
);
for
(
AccessibleObject
m
:
m2
)
m
.
setAccessible
(
true
);
for
(
AccessibleObject
m
:
m1
)
if
(
m
.
isAccessible
())
throw
new
RuntimeException
(
m
+
" should not be accessible"
);
for
(
AccessibleObject
m
:
m2
)
if
(!
m
.
isAccessible
())
throw
new
RuntimeException
(
m
+
" should be accessible"
);
// Validate that methods are still equal()
for
(
int
i
=
0
;
i
<
m1
.
length
;
i
++)
if
(!
m1
[
i
].
equals
(
m2
[
i
]))
throw
new
RuntimeException
(
m1
[
i
]
+
" and "
+
m2
[
i
]
+
" should be equal()"
);
// Validate that the arrays aren't shared
for
(
int
i
=
0
;
i
<
m1
.
length
;
i
++)
m1
[
i
]
=
null
;
for
(
int
i
=
0
;
i
<
m2
.
length
;
i
++)
if
(
m2
[
i
]
==
null
)
throw
new
RuntimeException
(
"Detected sharing of AccessibleObject arrays"
);
}
// Validate that annotations are shared
private
static
void
validateAnnotationSharing
(
AccessibleObject
m1
,
AccessibleObject
m2
)
{
Bar
b1
=
m1
.
getAnnotation
(
Bar
.
class
);
Bar
b2
=
m2
.
getAnnotation
(
Bar
.
class
);
if
(
b1
!=
b2
)
throw
new
RuntimeException
(
b1
+
" and "
+
b2
+
" should be =="
);
}
// Validate that Method instances representing the annotation elements
// behave as intended
private
static
void
validateAnnotationSharingIsSafe
(
AccessibleObject
m1
,
AccessibleObject
m2
)
throws
Exception
{
Bar
b1
=
m1
.
getAnnotation
(
Bar
.
class
);
Bar
b2
=
m2
.
getAnnotation
(
Bar
.
class
);
Method
mm1
=
b1
.
annotationType
().
getMethod
(
"value"
,
(
Class
<?>[])
null
);
Method
mm2
=
b2
.
annotationType
().
getMethod
(
"value"
,
(
Class
<?>[])
null
);
inner
(
mm1
,
mm2
);
mm1
=
b1
.
getClass
().
getMethod
(
"value"
,
(
Class
<?>[])
null
);
mm2
=
b2
.
getClass
().
getMethod
(
"value"
,
(
Class
<?>[])
null
);
inner
(
mm1
,
mm2
);
}
private
static
void
inner
(
Method
mm1
,
Method
mm2
)
throws
Exception
{
if
(!
mm1
.
equals
(
mm2
))
throw
new
RuntimeException
(
mm1
+
" and "
+
mm2
+
" should be equal()"
);
mm1
.
setAccessible
(
false
);
mm2
.
setAccessible
(
true
);
if
(
mm1
.
isAccessible
())
throw
new
RuntimeException
(
mm1
+
" should not be accessible"
);
if
(!
mm2
.
isAccessible
())
throw
new
RuntimeException
(
mm2
+
" should be accessible"
);
}
// Validate that array element values are not shared
private
static
void
validateArrayValues
(
Baz
a
,
Baz
b
)
{
String
[]
s1
=
a
.
value
();
String
[]
s2
=
b
.
value
();
s1
[
0
]
=
"22"
;
if
(!
s2
[
0
].
equals
(
"1"
))
throw
new
RuntimeException
(
"Mutation of array elements should not be detectable"
);
}
@Foo
@Bar
(
"val"
)
@Baz
({
"1"
,
"2"
})
public
void
m
()
{
return
;
}
@Foo
@Bar
(
"someValue"
)
@Baz
({
"1"
,
"22"
,
"33"
})
public
Object
f
=
new
Object
();
}
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
Foo
{}
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
Bar
{
String
value
();
}
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
Baz
{
String
[]
value
();
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录