Skip to content

Commit 4e6a4af

Browse files
author
Mandy Chung
committedSep 3, 2020
8244090: public lookup should find public members of public exported types
Reviewed-by: lfoltan, psandoz
1 parent 49a9d49 commit 4e6a4af

24 files changed

+369
-75
lines changed
 

‎src/hotspot/share/ci/ciEnv.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ Method* ciEnv::lookup_method(ciInstanceKlass* accessor,
761761
InstanceKlass* accessor_klass = accessor->get_instanceKlass();
762762
Klass* holder_klass = holder->get_Klass();
763763
Method* dest_method;
764-
LinkInfo link_info(holder_klass, name, sig, accessor_klass, LinkInfo::AccessCheck::required, tag);
764+
LinkInfo link_info(holder_klass, name, sig, accessor_klass, LinkInfo::AccessCheck::required, LinkInfo::LoaderConstraintCheck::required, tag);
765765
switch (bc) {
766766
case Bytecodes::_invokestatic:
767767
dest_method =

‎src/hotspot/share/ci/ciMethod.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,8 @@ ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, boo
809809
Symbol* h_signature = signature()->get_symbol();
810810

811811
LinkInfo link_info(resolved, h_name, h_signature, caller_klass,
812-
check_access ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip);
812+
check_access ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip,
813+
check_access ? LinkInfo::LoaderConstraintCheck::required : LinkInfo::LoaderConstraintCheck::skip);
813814
Method* m = NULL;
814815
// Only do exact lookup if receiver klass has been linked. Otherwise,
815816
// the vtable has not been setup, and the LinkResolver will fail.

‎src/hotspot/share/classfile/javaClasses.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,11 @@ class java_lang_invoke_MemberName: AllStatic {
11341134
MN_NESTMATE_CLASS = 0x00000001,
11351135
MN_HIDDEN_CLASS = 0x00000002,
11361136
MN_STRONG_LOADER_LINK = 0x00000004,
1137-
MN_ACCESS_VM_ANNOTATIONS = 0x00000008
1137+
MN_ACCESS_VM_ANNOTATIONS = 0x00000008,
1138+
// Lookup modes
1139+
MN_MODULE_MODE = 0x00000010,
1140+
MN_UNCONDITIONAL_MODE = 0x00000020,
1141+
MN_TRUSTED_MODE = -1
11381142
};
11391143

11401144
// Accessors for code generation:

‎src/hotspot/share/classfile/systemDictionary.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2830,7 +2830,7 @@ Handle SystemDictionary::link_method_handle_constant(Klass* caller,
28302830
// There's special logic on JDK side to handle them
28312831
// (see MethodHandles.linkMethodHandleConstant() and MethodHandles.findVirtualForMH()).
28322832
} else {
2833-
MethodHandles::resolve_MemberName(mname, caller, /*speculative_resolve*/false, CHECK_(empty));
2833+
MethodHandles::resolve_MemberName(mname, caller, 0, false /*speculative_resolve*/, CHECK_(empty));
28342834
}
28352835

28362836
// After method/field resolution succeeded, it's safe to resolve MH signature as well.

‎src/hotspot/share/interpreter/linkResolver.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, const methodHandle
241241

242242
// Coming from the constant pool always checks access
243243
_check_access = true;
244+
_check_loader_constraints = true;
244245
}
245246

246247
LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
@@ -256,17 +257,20 @@ LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
256257

257258
// Coming from the constant pool always checks access
258259
_check_access = true;
260+
_check_loader_constraints = true;
259261
}
260262

261263
#ifndef PRODUCT
262264
void LinkInfo::print() {
263265
ResourceMark rm;
264-
tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
266+
tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s check_loader_constraints=%s",
265267
_resolved_klass->name()->as_C_string(),
266268
_name->as_C_string(),
267269
_signature->as_C_string(),
268270
_current_klass == NULL ? "(none)" : _current_klass->name()->as_C_string(),
269-
_check_access ? "true" : "false");
271+
_check_access ? "true" : "false",
272+
_check_loader_constraints ? "true" : "false");
273+
270274
}
271275
#endif // PRODUCT
272276
//------------------------------------------------------------------------------------------------------------------------
@@ -795,7 +799,8 @@ Method* LinkResolver::resolve_method(const LinkInfo& link_info,
795799
resolved_method->method_holder(),
796800
resolved_method,
797801
CHECK_NULL);
798-
802+
}
803+
if (link_info.check_loader_constraints()) {
799804
// check loader constraints
800805
check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL);
801806
}
@@ -891,7 +896,8 @@ Method* LinkResolver::resolve_interface_method(const LinkInfo& link_info, Byteco
891896
resolved_method->method_holder(),
892897
resolved_method,
893898
CHECK_NULL);
894-
899+
}
900+
if (link_info.check_loader_constraints()) {
895901
check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL);
896902
}
897903

@@ -1055,7 +1061,7 @@ void LinkResolver::resolve_field(fieldDescriptor& fd,
10551061
}
10561062
}
10571063

1058-
if ((sel_klass != current_klass) && (current_klass != NULL)) {
1064+
if (link_info.check_loader_constraints() && (sel_klass != current_klass) && (current_klass != NULL)) {
10591065
check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
10601066
}
10611067

@@ -1089,7 +1095,8 @@ void LinkResolver::resolve_static_call(CallInfo& result,
10891095
// Use updated LinkInfo to reresolve with resolved method holder
10901096
LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
10911097
link_info.current_klass(),
1092-
link_info.check_access() ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip);
1098+
link_info.check_access() ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip,
1099+
link_info.check_loader_constraints() ? LinkInfo::LoaderConstraintCheck::required : LinkInfo::LoaderConstraintCheck::skip);
10931100
resolved_method = linktime_resolve_static_method(new_info, CHECK);
10941101
}
10951102

@@ -1250,7 +1257,7 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
12501257
ss.print("'");
12511258
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), ss.as_string());
12521259
// check loader constraints if found a different method
1253-
} else if (sel_method() != resolved_method()) {
1260+
} else if (link_info.check_loader_constraints() && sel_method() != resolved_method()) {
12541261
check_method_loader_constraints(link_info, sel_method, "method", CHECK);
12551262
}
12561263
}

‎src/hotspot/share/interpreter/linkResolver.hpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,44 +141,51 @@ class LinkInfo : public StackObj {
141141
Klass* _current_klass; // class that owns the constant pool
142142
methodHandle _current_method; // sending method
143143
bool _check_access;
144+
bool _check_loader_constraints;
144145
constantTag _tag;
145146

146147
public:
147148
enum class AccessCheck { required, skip };
149+
enum class LoaderConstraintCheck { required, skip };
148150

149151
LinkInfo(const constantPoolHandle& pool, int index, const methodHandle& current_method, TRAPS);
150152
LinkInfo(const constantPoolHandle& pool, int index, TRAPS);
151153

152154
// Condensed information from other call sites within the vm.
153155
LinkInfo(Klass* resolved_klass, Symbol* name, Symbol* signature, Klass* current_klass,
154156
AccessCheck check_access = AccessCheck::required,
157+
LoaderConstraintCheck check_loader_constraints = LoaderConstraintCheck::required,
155158
constantTag tag = JVM_CONSTANT_Invalid) :
156159
_name(name),
157160
_signature(signature), _resolved_klass(resolved_klass), _current_klass(current_klass), _current_method(methodHandle()),
158-
_check_access(check_access == AccessCheck::required), _tag(tag) {}
161+
_check_access(check_access == AccessCheck::required),
162+
_check_loader_constraints(check_loader_constraints == LoaderConstraintCheck::required), _tag(tag) {}
159163

160164
LinkInfo(Klass* resolved_klass, Symbol* name, Symbol* signature, const methodHandle& current_method,
161165
AccessCheck check_access = AccessCheck::required,
166+
LoaderConstraintCheck check_loader_constraints = LoaderConstraintCheck::required,
162167
constantTag tag = JVM_CONSTANT_Invalid) :
163168
_name(name),
164169
_signature(signature), _resolved_klass(resolved_klass), _current_klass(current_method->method_holder()), _current_method(current_method),
165-
_check_access(check_access == AccessCheck::required), _tag(tag) {}
170+
_check_access(check_access == AccessCheck::required),
171+
_check_loader_constraints(check_loader_constraints == LoaderConstraintCheck::required), _tag(tag) {}
172+
166173

167174
// Case where we just find the method and don't check access against the current class
168175
LinkInfo(Klass* resolved_klass, Symbol*name, Symbol* signature) :
169176
_name(name),
170177
_signature(signature), _resolved_klass(resolved_klass), _current_klass(NULL), _current_method(methodHandle()),
171-
_check_access(false), _tag(JVM_CONSTANT_Invalid) {}
178+
_check_access(false), _check_loader_constraints(false), _tag(JVM_CONSTANT_Invalid) {}
172179

173180
// accessors
174-
Symbol* name() const { return _name; }
175-
Symbol* signature() const { return _signature; }
176-
Klass* resolved_klass() const { return _resolved_klass; }
177-
Klass* current_klass() const { return _current_klass; }
178-
Method* current_method() const { return _current_method(); }
179-
constantTag tag() const { return _tag; }
180-
bool check_access() const { return _check_access; }
181-
181+
Symbol* name() const { return _name; }
182+
Symbol* signature() const { return _signature; }
183+
Klass* resolved_klass() const { return _resolved_klass; }
184+
Klass* current_klass() const { return _current_klass; }
185+
Method* current_method() const { return _current_method(); }
186+
constantTag tag() const { return _tag; }
187+
bool check_access() const { return _check_access; }
188+
bool check_loader_constraints() const { return _check_loader_constraints; }
182189
void print() PRODUCT_RETURN;
183190
};
184191

‎src/hotspot/share/jvmci/jvmciJavaClasses.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void HotSpotJVMCI::compute_offset(int &dest_offset, Klass* klass, const char* na
9090
#ifndef PRODUCT
9191
static void check_resolve_method(const char* call_type, Klass* resolved_klass, Symbol* method_name, Symbol* method_signature, TRAPS) {
9292
Method* method;
93-
LinkInfo link_info(resolved_klass, method_name, method_signature, NULL, LinkInfo::AccessCheck::skip);
93+
LinkInfo link_info(resolved_klass, method_name, method_signature, NULL, LinkInfo::AccessCheck::skip, LinkInfo::LoaderConstraintCheck::skip);
9494
if (strcmp(call_type, "call_static") == 0) {
9595
method = LinkResolver::resolve_static_call_or_null(link_info);
9696
} else if (strcmp(call_type, "call_virtual") == 0) {

‎src/hotspot/share/jvmci/jvmciRuntime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1327,7 +1327,7 @@ Method* JVMCIRuntime::lookup_method(InstanceKlass* accessor,
13271327
assert(check_klass_accessibility(accessor, holder), "holder not accessible");
13281328

13291329
Method* dest_method;
1330-
LinkInfo link_info(holder, name, sig, accessor, LinkInfo::AccessCheck::required, tag);
1330+
LinkInfo link_info(holder, name, sig, accessor, LinkInfo::AccessCheck::required, LinkInfo::LoaderConstraintCheck::required, tag);
13311331
switch (bc) {
13321332
case Bytecodes::_invokestatic:
13331333
dest_method =

‎src/hotspot/share/prims/methodHandles.cpp

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ enum {
132132
REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
133133
SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
134134
SEARCH_INTERFACES = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
135+
LM_UNCONDITIONAL = java_lang_invoke_MemberName::MN_UNCONDITIONAL_MODE,
136+
LM_MODULE = java_lang_invoke_MemberName::MN_MODULE_MODE,
137+
LM_TRUSTED = java_lang_invoke_MemberName::MN_TRUSTED_MODE,
135138
ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
136139
};
137140

@@ -672,11 +675,10 @@ oop MethodHandles::field_signature_type_or_null(Symbol* s) {
672675
return NULL;
673676
}
674677

675-
676678
// An unresolved member name is a mere symbolic reference.
677679
// Resolving it plants a vmtarget/vmindex in it,
678680
// which refers directly to JVM internals.
679-
Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller,
681+
Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller, int lookup_mode,
680682
bool speculative_resolve, TRAPS) {
681683
Handle empty;
682684
assert(java_lang_invoke_MemberName::is_instance(mname()), "");
@@ -745,16 +747,21 @@ Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller,
745747
TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty));
746748
if (type == NULL) return empty; // no such signature exists in the VM
747749

750+
// skip access check if it's trusted lookup
748751
LinkInfo::AccessCheck access_check = caller != NULL ?
749752
LinkInfo::AccessCheck::required :
750753
LinkInfo::AccessCheck::skip;
754+
// skip loader constraints if it's trusted lookup or a public lookup
755+
LinkInfo::LoaderConstraintCheck loader_constraint_check = (caller != NULL && (lookup_mode & LM_UNCONDITIONAL) == 0) ?
756+
LinkInfo::LoaderConstraintCheck::required :
757+
LinkInfo::LoaderConstraintCheck::skip;
751758

752759
// Time to do the lookup.
753760
switch (flags & ALL_KINDS) {
754761
case IS_METHOD:
755762
{
756763
CallInfo result;
757-
LinkInfo link_info(defc, name, type, caller, access_check);
764+
LinkInfo link_info(defc, name, type, caller, access_check, loader_constraint_check);
758765
{
759766
assert(!HAS_PENDING_EXCEPTION, "");
760767
if (ref_kind == JVM_REF_invokeStatic) {
@@ -795,7 +802,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller,
795802
case IS_CONSTRUCTOR:
796803
{
797804
CallInfo result;
798-
LinkInfo link_info(defc, name, type, caller, access_check);
805+
LinkInfo link_info(defc, name, type, caller, access_check, loader_constraint_check);
799806
{
800807
assert(!HAS_PENDING_EXCEPTION, "");
801808
if (name == vmSymbols::object_initializer_name()) {
@@ -820,7 +827,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller,
820827
fieldDescriptor result; // find_field initializes fd if found
821828
{
822829
assert(!HAS_PENDING_EXCEPTION, "");
823-
LinkInfo link_info(defc, name, type, caller, LinkInfo::AccessCheck::skip);
830+
LinkInfo link_info(defc, name, type, caller, LinkInfo::AccessCheck::skip, loader_constraint_check);
824831
LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);
825832
if (HAS_PENDING_EXCEPTION) {
826833
if (speculative_resolve) {
@@ -1117,6 +1124,9 @@ void MethodHandles::trace_method_handle_interpreter_entry(MacroAssembler* _masm,
11171124
template(java_lang_invoke_MemberName,MN_HIDDEN_CLASS) \
11181125
template(java_lang_invoke_MemberName,MN_STRONG_LOADER_LINK) \
11191126
template(java_lang_invoke_MemberName,MN_ACCESS_VM_ANNOTATIONS) \
1127+
template(java_lang_invoke_MemberName,MN_MODULE_MODE) \
1128+
template(java_lang_invoke_MemberName,MN_UNCONDITIONAL_MODE) \
1129+
template(java_lang_invoke_MemberName,MN_TRUSTED_MODE) \
11201130
/*end*/
11211131

11221132
#define IGNORE_REQ(req_expr) /* req_expr */
@@ -1190,13 +1200,17 @@ JVM_END
11901200

11911201
// void resolve(MemberName self, Class<?> caller)
11921202
JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh,
1193-
jboolean speculative_resolve)) {
1203+
jint lookup_mode, jboolean speculative_resolve)) {
11941204
if (mname_jh == NULL) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); }
11951205
Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
11961206

11971207
// The trusted Java code that calls this method should already have performed
11981208
// access checks on behalf of the given caller. But, we can verify this.
1199-
if (VerifyMethodHandles && caller_jh != NULL &&
1209+
// This only verifies from the context of the lookup class. It does not
1210+
// verify the lookup context for a Lookup object teleported from one module
1211+
// to another. Such Lookup object can only access the intersection of the set
1212+
// of accessible classes from both lookup class and previous lookup class.
1213+
if (VerifyMethodHandles && (lookup_mode & LM_TRUSTED) == LM_TRUSTED && caller_jh != NULL &&
12001214
java_lang_invoke_MemberName::clazz(mname()) != NULL) {
12011215
Klass* reference_klass = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
12021216
if (reference_klass != NULL && reference_klass->is_objArray_klass()) {
@@ -1207,18 +1221,25 @@ JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh,
12071221
if (reference_klass != NULL && reference_klass->is_instance_klass()) {
12081222
// Emulate LinkResolver::check_klass_accessability.
12091223
Klass* caller = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
1210-
if (caller != SystemDictionary::Object_klass()
1224+
// access check on behalf of the caller if this is not a public lookup
1225+
// i.e. lookup mode is not UNCONDITIONAL
1226+
if ((lookup_mode & LM_UNCONDITIONAL) == 0
12111227
&& Reflection::verify_class_access(caller,
12121228
InstanceKlass::cast(reference_klass),
12131229
true) != Reflection::ACCESS_OK) {
1214-
THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name());
1230+
ResourceMark rm(THREAD);
1231+
stringStream ss;
1232+
ss.print("caller %s tried to access %s", caller->class_in_module_of_loader(),
1233+
reference_klass->class_in_module_of_loader());
1234+
THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), ss.as_string());
12151235
}
12161236
}
12171237
}
12181238

12191239
Klass* caller = caller_jh == NULL ? NULL :
12201240
java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
1221-
Handle resolved = MethodHandles::resolve_MemberName(mname, caller, speculative_resolve == JNI_TRUE,
1241+
Handle resolved = MethodHandles::resolve_MemberName(mname, caller, lookup_mode,
1242+
speculative_resolve == JNI_TRUE,
12221243
CHECK_NULL);
12231244

12241245
if (resolved.is_null()) {
@@ -1518,7 +1539,7 @@ JVM_END
15181539
static JNINativeMethod MHN_methods[] = {
15191540
{CC "init", CC "(" MEM "" OBJ ")V", FN_PTR(MHN_init_Mem)},
15201541
{CC "expand", CC "(" MEM ")V", FN_PTR(MHN_expand_Mem)},
1521-
{CC "resolve", CC "(" MEM "" CLS "Z)" MEM, FN_PTR(MHN_resolve_Mem)},
1542+
{CC "resolve", CC "(" MEM "" CLS "IZ)" MEM, FN_PTR(MHN_resolve_Mem)},
15221543
// static native int getNamedCon(int which, Object[] name)
15231544
{CC "getNamedCon", CC "(I[" OBJ ")I", FN_PTR(MHN_getNamedCon)},
15241545
// static native int getMembers(Class<?> defc, String matchName, String matchSig,

‎src/hotspot/share/prims/methodHandles.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class MethodHandles: AllStatic {
6060

6161
public:
6262
// working with member names
63-
static Handle resolve_MemberName(Handle mname, Klass* caller,
63+
static Handle resolve_MemberName(Handle mname, Klass* caller, int lookup_mode,
6464
bool speculative_resolve, TRAPS); // compute vmtarget/vmindex from name/type
6565
static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing
6666
static oop init_MemberName(Handle mname_h, Handle target_h, TRAPS); // compute vmtarget/vmindex from target

‎src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import java.util.Arrays;
2929
import static java.lang.invoke.LambdaForm.*;
3030
import static java.lang.invoke.LambdaForm.Kind.*;
31-
import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeVirtual;
31+
import static java.lang.invoke.MethodHandleNatives.Constants.*;
3232
import static java.lang.invoke.MethodHandleStatics.*;
3333

3434
/**
@@ -177,7 +177,7 @@ private static Kind whichKind(int whichCache) {
177177
MethodType.methodType(MethodHandle.class), REF_invokeVirtual);
178178
NF_getTarget = new NamedFunction(
179179
MemberName.getFactory()
180-
.resolveOrFail(REF_invokeVirtual, member, DelegatingMethodHandle.class, NoSuchMethodException.class));
180+
.resolveOrFail(REF_invokeVirtual, member, DelegatingMethodHandle.class, LM_TRUSTED, NoSuchMethodException.class));
181181
} catch (ReflectiveOperationException ex) {
182182
throw newInternalError(ex);
183183
}

‎src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member,
6363
member.isMethod() && !member.isAbstract()) {
6464
// Check for corner case: invokeinterface of Object method
6565
MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
66-
m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
66+
m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null, LM_TRUSTED);
6767
if (m != null && m.isPublic()) {
6868
assert(member.getReferenceKind() == m.getReferenceKind()); // else this.form is wrong
6969
member = m;
@@ -260,7 +260,8 @@ static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
260260
.changeReturnType(void.class); // <init> returns void
261261
MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
262262
try {
263-
linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
263+
linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, LM_TRUSTED,
264+
NoSuchMethodException.class);
264265
} catch (ReflectiveOperationException ex) {
265266
throw newInternalError(ex);
266267
}
@@ -771,7 +772,8 @@ static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, i
771772
linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
772773
MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
773774
try {
774-
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
775+
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
776+
NoSuchMethodException.class);
775777
} catch (ReflectiveOperationException ex) {
776778
throw newInternalError(ex);
777779
}
@@ -914,13 +916,15 @@ private static NamedFunction createFunction(byte func) {
914916
case NF_UNSAFE:
915917
MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getField);
916918
return new NamedFunction(
917-
MemberName.getFactory()
918-
.resolveOrFail(REF_getField, member, DirectMethodHandle.class, NoSuchMethodException.class));
919+
MemberName.getFactory().resolveOrFail(REF_getField, member,
920+
DirectMethodHandle.class, LM_TRUSTED,
921+
NoSuchMethodException.class));
919922
case NF_checkReceiver:
920923
member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
921924
return new NamedFunction(
922-
MemberName.getFactory()
923-
.resolveOrFail(REF_invokeVirtual, member, DirectMethodHandle.class, NoSuchMethodException.class));
925+
MemberName.getFactory().resolveOrFail(REF_invokeVirtual, member,
926+
DirectMethodHandle.class, LM_TRUSTED,
927+
NoSuchMethodException.class));
924928
default:
925929
throw newInternalError("Unknown function: " + func);
926930
}
@@ -934,8 +938,9 @@ private static NamedFunction getNamedFunction(String name, MethodType type)
934938
{
935939
MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
936940
return new NamedFunction(
937-
MemberName.getFactory()
938-
.resolveOrFail(REF_invokeStatic, member, DirectMethodHandle.class, NoSuchMethodException.class));
941+
MemberName.getFactory().resolveOrFail(REF_invokeStatic, member,
942+
DirectMethodHandle.class, LM_TRUSTED,
943+
NoSuchMethodException.class));
939944
}
940945

941946
static {

‎src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,9 @@ private MemberName loadMethod(byte[] classFile) {
322322
private static MemberName resolveInvokerMember(Class<?> invokerClass, String name, MethodType type) {
323323
MemberName member = new MemberName(invokerClass, name, type, REF_invokeStatic);
324324
try {
325-
member = MEMBERNAME_FACTORY.resolveOrFail(REF_invokeStatic, member, HOST_CLASS, ReflectiveOperationException.class);
325+
member = MEMBERNAME_FACTORY.resolveOrFail(REF_invokeStatic, member,
326+
HOST_CLASS, LM_TRUSTED,
327+
ReflectiveOperationException.class);
326328
} catch (ReflectiveOperationException e) {
327329
throw newInternalError(e);
328330
}
@@ -693,7 +695,7 @@ private String getInternalName(Class<?> c) {
693695

694696
private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
695697
MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
696-
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
698+
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder, LM_TRUSTED);
697699
if (TRACE_RESOLVE) {
698700
System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " +
699701
shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") );

‎src/java.base/share/classes/java/lang/invoke/Invokers.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ private static NamedFunction getNamedFunction(String name, MethodType type)
661661
MemberName member = new MemberName(Invokers.class, name, type, REF_invokeStatic);
662662
return new NamedFunction(
663663
MemberName.getFactory()
664-
.resolveOrFail(REF_invokeStatic, member, Invokers.class, NoSuchMethodException.class));
664+
.resolveOrFail(REF_invokeStatic, member, Invokers.class, LM_TRUSTED, NoSuchMethodException.class));
665665
}
666666

667667
private static class Lazy {

‎src/java.base/share/classes/java/lang/invoke/LambdaForm.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
import java.util.HashMap;
4141

4242
import static java.lang.invoke.LambdaForm.BasicType.*;
43-
import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
43+
import static java.lang.invoke.MethodHandleNatives.Constants.*;
4444
import static java.lang.invoke.MethodHandleStatics.*;
4545

4646
/**
@@ -1758,10 +1758,10 @@ private static void createFormsFor(BasicType type) {
17581758
MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic);
17591759
MemberName zeMem = null;
17601760
try {
1761-
idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, NoSuchMethodException.class);
1761+
idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, LM_TRUSTED, NoSuchMethodException.class);
17621762
if (!isVoid) {
17631763
zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic);
1764-
zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, NoSuchMethodException.class);
1764+
zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, LM_TRUSTED, NoSuchMethodException.class);
17651765
}
17661766
} catch (IllegalAccessException|NoSuchMethodException ex) {
17671767
throw newInternalError(ex);

‎src/java.base/share/classes/java/lang/invoke/MemberName.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ List<MemberName> getMembers(Class<?> defc,
10641064
* If lookup fails or access is not permitted, null is returned.
10651065
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
10661066
*/
1067-
private MemberName resolve(byte refKind, MemberName ref, Class<?> lookupClass,
1067+
private MemberName resolve(byte refKind, MemberName ref, Class<?> lookupClass, int allowedModes,
10681068
boolean speculativeResolve) {
10691069
MemberName m = ref.clone(); // JVM will side-effect the ref
10701070
assert(refKind == m.getReferenceKind());
@@ -1084,7 +1084,7 @@ private MemberName resolve(byte refKind, MemberName ref, Class<?> lookupClass,
10841084
//
10851085
// REFC view on PTYPES doesn't matter, since it is used only as a starting point for resolution and doesn't
10861086
// participate in method selection.
1087-
m = MethodHandleNatives.resolve(m, lookupClass, speculativeResolve);
1087+
m = MethodHandleNatives.resolve(m, lookupClass, allowedModes, speculativeResolve);
10881088
if (m == null && speculativeResolve) {
10891089
return null;
10901090
}
@@ -1108,10 +1108,12 @@ private MemberName resolve(byte refKind, MemberName ref, Class<?> lookupClass,
11081108
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
11091109
*/
11101110
public <NoSuchMemberException extends ReflectiveOperationException>
1111-
MemberName resolveOrFail(byte refKind, MemberName m, Class<?> lookupClass,
1112-
Class<NoSuchMemberException> nsmClass)
1111+
MemberName resolveOrFail(byte refKind, MemberName m,
1112+
Class<?> lookupClass, int allowedModes,
1113+
Class<NoSuchMemberException> nsmClass)
11131114
throws IllegalAccessException, NoSuchMemberException {
1114-
MemberName result = resolve(refKind, m, lookupClass, false);
1115+
assert lookupClass != null || allowedModes == LM_TRUSTED;
1116+
MemberName result = resolve(refKind, m, lookupClass, allowedModes, false);
11151117
if (result.isResolved())
11161118
return result;
11171119
ReflectiveOperationException ex = result.makeAccessException();
@@ -1124,8 +1126,9 @@ MemberName resolveOrFail(byte refKind, MemberName m, Class<?> lookupClass,
11241126
* If lookup fails or access is not permitted, return null.
11251127
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
11261128
*/
1127-
public MemberName resolveOrNull(byte refKind, MemberName m, Class<?> lookupClass) {
1128-
MemberName result = resolve(refKind, m, lookupClass, true);
1129+
public MemberName resolveOrNull(byte refKind, MemberName m, Class<?> lookupClass, int allowedModes) {
1130+
assert lookupClass != null || allowedModes == LM_TRUSTED;
1131+
MemberName result = resolve(refKind, m, lookupClass, allowedModes, true);
11291132
if (result != null && result.isResolved())
11301133
return result;
11311134
return null;

‎src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private MethodHandleNatives() { } // static only
5151

5252
static native void init(MemberName self, Object ref);
5353
static native void expand(MemberName self);
54-
static native MemberName resolve(MemberName self, Class<?> caller,
54+
static native MemberName resolve(MemberName self, Class<?> caller, int lookupMode,
5555
boolean speculativeResolve) throws LinkageError, ClassNotFoundException;
5656
static native int getMembers(Class<?> defc, String matchName, String matchSig,
5757
int matchFlags, Class<?> caller, int skip, MemberName[] results);
@@ -149,6 +149,15 @@ static class Constants {
149149
HIDDEN_CLASS = 0x00000002,
150150
STRONG_LOADER_LINK = 0x00000004,
151151
ACCESS_VM_ANNOTATIONS = 0x00000008;
152+
153+
/**
154+
* Lookup modes
155+
*/
156+
static final int
157+
LM_MODULE = Lookup.MODULE,
158+
LM_UNCONDITIONAL = Lookup.UNCONDITIONAL,
159+
LM_TRUSTED = -1;
160+
152161
}
153162

154163
static boolean refKindIsValid(int refKind) {
@@ -561,7 +570,7 @@ VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
561570
guardType, REF_invokeStatic);
562571

563572
linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
564-
VarHandleGuards.class);
573+
VarHandleGuards.class, LM_TRUSTED);
565574
if (linker != null) {
566575
return linker;
567576
}

‎src/java.base/share/classes/java/lang/invoke/MethodHandles.java

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,14 +1409,7 @@ public Class<?> previousLookupClass() {
14091409

14101410
// This is just for calling out to MethodHandleImpl.
14111411
private Class<?> lookupClassOrNull() {
1412-
if (allowedModes == TRUSTED) {
1413-
return null;
1414-
}
1415-
if (allowedModes == UNCONDITIONAL) {
1416-
// use Object as the caller to pass to VM doing resolution
1417-
return Object.class;
1418-
}
1419-
return lookupClass;
1412+
return (allowedModes == TRUSTED) ? null : lookupClass;
14201413
}
14211414

14221415
/** Tells which access-protection classes of members this lookup object can produce.
@@ -3442,7 +3435,7 @@ MemberName resolveOrFail(byte refKind, Class<?> refc, String name, Class<?> type
34423435
checkSymbolicClass(refc); // do this before attempting to resolve
34433436
Objects.requireNonNull(name);
34443437
Objects.requireNonNull(type);
3445-
return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
3438+
return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes,
34463439
NoSuchFieldException.class);
34473440
}
34483441

@@ -3451,15 +3444,15 @@ MemberName resolveOrFail(byte refKind, Class<?> refc, String name, MethodType ty
34513444
Objects.requireNonNull(name);
34523445
Objects.requireNonNull(type);
34533446
checkMethodName(refKind, name); // NPE check on name
3454-
return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
3447+
return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes,
34553448
NoSuchMethodException.class);
34563449
}
34573450

34583451
MemberName resolveOrFail(byte refKind, MemberName member) throws ReflectiveOperationException {
34593452
checkSymbolicClass(member.getDeclaringClass()); // do this before attempting to resolve
34603453
Objects.requireNonNull(member.getName());
34613454
Objects.requireNonNull(member.getType());
3462-
return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(),
3455+
return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(), allowedModes,
34633456
ReflectiveOperationException.class);
34643457
}
34653458

@@ -3470,7 +3463,7 @@ MemberName resolveOrNull(byte refKind, MemberName member) {
34703463
}
34713464
Objects.requireNonNull(member.getName());
34723465
Objects.requireNonNull(member.getType());
3473-
return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull());
3466+
return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull(), allowedModes);
34743467
}
34753468

34763469
void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
@@ -3774,7 +3767,7 @@ private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberNa
37743767
method.getName(),
37753768
method.getMethodType(),
37763769
REF_invokeSpecial);
3777-
m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
3770+
m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull(), allowedModes);
37783771
} while (m2 == null && // no method is found yet
37793772
refc != refcAsSuper); // search up to refc
37803773
if (m2 == null) throw new InternalError(method.toString());
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* @test
26+
* @bug 8244090
27+
* @build m1/* m2/*
28+
* @run main/othervm m1/p.Main
29+
* @summary Tests public lookups produced from MethodHandles.publicLookup()::in
30+
*/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
module m1 {
24+
requires m2;
25+
exports p;
26+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package p;
25+
26+
import java.lang.invoke.MethodHandle;
27+
import java.lang.invoke.MethodHandles;
28+
import java.lang.invoke.MethodHandles.Lookup;
29+
import java.lang.invoke.MethodType;
30+
import java.net.URL;
31+
import java.net.URLClassLoader;
32+
import java.nio.file.Paths;
33+
import java.util.Arrays;
34+
35+
import static java.lang.invoke.MethodHandles.Lookup.*;
36+
37+
public class Main {
38+
/*
39+
* Each Test object loads q.EndPoint and q.T with a custom loader.
40+
* These types are used to look up a method handle "EndPoint::test(T)".
41+
*/
42+
static class Test {
43+
final ClassLoader loader;
44+
final Class<?> target;
45+
final Class<?> param;
46+
Test(String name) throws Exception {
47+
URL url = Paths.get(System.getProperty("test.classes"), "modules", "m2")
48+
.toUri().toURL();
49+
this.loader = new URLClassLoader(name, new URL[]{url}, null);
50+
this.target = Class.forName("q.EndPoint", true, loader);
51+
this.param = Class.forName("q.T", true, loader);
52+
assertTrue(target != q.EndPoint.class);
53+
assertTrue(param != q.T.class);
54+
}
55+
56+
/*
57+
*
58+
*/
59+
public void verifyAccess(Lookup... publicLookups) throws Throwable {
60+
System.err.println(loader.getName() + ": verify access for " + Arrays.toString(publicLookups));
61+
for (Lookup lookup : publicLookups) {
62+
assertTrue((lookup.lookupModes() & UNCONDITIONAL) == UNCONDITIONAL);
63+
assertTrue((lookup.lookupModes() & PUBLIC) == 0);
64+
MethodHandle mh = lookup.findVirtual(target, "test", MethodType.methodType(void.class, param));
65+
mh.invoke(target.newInstance(), param.newInstance());
66+
checkTypeConsistency(mh);
67+
}
68+
}
69+
}
70+
71+
/*
72+
* Verify that publicLookup can teleport to:
73+
* 1) q.EndPoint defined in m2
74+
* 2) q.EndPoint defined by a custom loader CL1 in one unnamed module
75+
* 3) q.EndPoint defined by a custom loader CL2 in another unnamed module
76+
*
77+
* All the resulting Lookup objects are public lookups and can find
78+
* any public accessible member.
79+
*/
80+
public static void main(String... args) throws Throwable {
81+
Test test1 = new Test("CL1");
82+
Test test2 = new Test("CL2");
83+
84+
Lookup lookup1 = MethodHandles.publicLookup();
85+
Lookup lookup2 = MethodHandles.publicLookup().in(test1.target);
86+
Lookup lookup3 = MethodHandles.publicLookup().in(test2.target);
87+
assertTrue(lookup2.lookupClass().getClassLoader() != lookup3.lookupClass().getClassLoader());
88+
89+
test1.verifyAccess(lookup1, lookup2, lookup3);
90+
test2.verifyAccess(lookup1, lookup2, lookup3);
91+
}
92+
93+
static void checkTypeConsistency(MethodHandle mh) throws Throwable {
94+
try {
95+
mh.invoke(new q.EndPoint(), new q.T());
96+
throw new Error("expect fail to invoke due to type inconsistency");
97+
} catch (ClassCastException e) {
98+
assertTrue(e.getMessage().startsWith("Cannot cast q."));
99+
}
100+
}
101+
102+
static void assertTrue(boolean v) {
103+
if (!v) {
104+
throw new AssertionError("unexpected result");
105+
}
106+
}
107+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
module m2 {
24+
exports q;
25+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package q;
24+
25+
public class EndPoint {
26+
public void test(T t) {
27+
}
28+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package q;
24+
25+
public class T {
26+
}

0 commit comments

Comments
 (0)
Please sign in to comment.