}
return proxyClass;
}
public static RubyModule getProxyClass(Ruby runtime, JavaClass javaClass) {
RubyClass proxyClass;
final Class<?> c = javaClass.javaClass();
if ((proxyClass = javaClass.getProxyClass()) != null) {
return proxyClass;
}
if (c.isInterface()) {
return getInterfaceModule(runtime, javaClass);
}
javaClass.lockProxy();
try {
if ((proxyClass = javaClass.getProxyClass()) == null) {
if (c.isArray()) {
proxyClass = createProxyClass(runtime,
runtime.getJavaSupport().getArrayProxyClass(),
javaClass, true);
} else if (c.isPrimitive()) {
proxyClass = createProxyClass(runtime,
runtime.getJavaSupport().getConcreteProxyClass(),
javaClass, true);
} else if (c == Object.class) {
// java.lang.Object is added at root of java proxy classes
proxyClass = createProxyClass(runtime,
runtime.getJavaSupport().getConcreteProxyClass(),
javaClass, true);
proxyClass.getMetaClass().defineFastMethod("inherited",
runtime.getJavaSupport().getConcreteProxyCallback());
addToJavaPackageModule(proxyClass, javaClass);
} else {
// other java proxy classes added under their superclass' java proxy
proxyClass = createProxyClass(runtime,
(RubyClass) getProxyClass(runtime, JavaClass.get(runtime, c.getSuperclass())),
javaClass, false);
// include interface modules into the proxy class
Class<?>[] interfaces = c.getInterfaces();
for (int i = interfaces.length; --i >= 0;) {
JavaClass ifc = JavaClass.get(runtime, interfaces[i]);
proxyClass.includeModule(getInterfaceModule(runtime, ifc));
}
if (Modifier.isPublic(c.getModifiers())) {
addToJavaPackageModule(proxyClass, javaClass);
}
}
// JRUBY-1000, fail early when attempting to subclass a final Java class;
// solved here by adding an exception-throwing "inherited"
if (Modifier.isFinal(c.getModifiers())) {
proxyClass.getMetaClass().addMethod("inherited", new org.jruby.internal.runtime.methods.JavaMethod() {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
throw context.getRuntime().newTypeError("can not extend final Java class: " + c.getCanonicalName());
}
});