687 ensureVisible(loader, type); |
687 ensureVisible(loader, type); |
688 } |
688 } |
689 } |
689 } |
690 |
690 |
691 /* |
691 /* |
692 * Returns all types referenced by all public method signatures of |
692 * Returns all types referenced by all public non-static method signatures of |
693 * the proxy interfaces |
693 * the proxy interfaces |
694 */ |
694 */ |
695 private static Set<Class<?>> referencedTypes(ClassLoader loader, |
695 private static Set<Class<?>> referencedTypes(ClassLoader loader, |
696 List<Class<?>> interfaces) { |
696 List<Class<?>> interfaces) { |
697 return interfaces.stream() |
697 return interfaces.stream() |
698 .flatMap(intf -> Stream.of(intf.getMethods()) |
698 .flatMap(intf -> Stream.of(intf.getMethods()) |
|
699 .filter(m -> !Modifier.isStatic(m.getModifiers())) |
699 .flatMap(ProxyBuilder::methodRefTypes) |
700 .flatMap(ProxyBuilder::methodRefTypes) |
700 .map(ProxyBuilder::getElementType) |
701 .map(ProxyBuilder::getElementType) |
701 .filter(t -> !t.isPrimitive())) |
702 .filter(t -> !t.isPrimitive())) |
702 .collect(Collectors.toSet()); |
703 .collect(Collectors.toSet()); |
703 } |
704 } |
793 |
794 |
794 // all proxy interfaces are public and at least one in a non-exported package |
795 // all proxy interfaces are public and at least one in a non-exported package |
795 // map to dynamic proxy module and add reads edge and qualified exports, if necessary |
796 // map to dynamic proxy module and add reads edge and qualified exports, if necessary |
796 Module target = getDynamicModule(loader); |
797 Module target = getDynamicModule(loader); |
797 |
798 |
798 // set up proxy class access to proxy interfaces and superinterfaces |
799 // set up proxy class access to proxy interfaces and types |
799 Deque<Class<?>> deque = new LinkedList<>(interfaces); |
800 // referenced in the method signature |
800 Set<Class<?>> visited = new HashSet<>(); |
801 Set<Class<?>> types = new HashSet<>(interfaces); |
801 while (!deque.isEmpty()) { |
802 types.addAll(refTypes); |
802 Class<?> c = deque.poll(); |
803 for (Class<?> c : types) { |
803 if (!visited.add(c)) { |
|
804 continue; |
|
805 } |
|
806 ensureAccess(target, c); |
804 ensureAccess(target, c); |
807 |
805 } |
808 // add all superinterfaces |
|
809 for (Class<?> intf : c.getInterfaces()) { |
|
810 deque.add(intf); |
|
811 } |
|
812 } |
|
813 |
|
814 // set up proxy class access to types referenced in the method signature |
|
815 refTypes.stream() |
|
816 .filter(t -> !visited.contains(t)) |
|
817 .forEach(t -> ensureAccess(target, t)); |
|
818 return target; |
806 return target; |
819 } |
807 } |
820 |
808 |
821 /* |
809 /* |
822 * Ensure the given module can access the given class. |
810 * Ensure the given module can access the given class. |