On Wed, Jul 22, 2009 at 10:45 PM, Stuart Halloway<stuart.hallo...@gmail.com> wrote: > > I have a failing test in the JMX server code [1]: > > (deftest dynamic-mbean > (let [mbean-name "clojure.contrib.test_contrib.test_jmx:name=Foo"] > (jmx/register-mbean > (jmx/dynamic-mbean > (ref {:string-attribute "a-string"})) > mbean-name) > (is (= "a-string" (jmx/read mbean-name :string-attribute))))) > > > The weird thing is, the same exact code works from the REPL. The > second weird thing is, the error is a permissions error (and no > SecurityManager is installed). > > In the interest of decency, I will show only a fraction of the stack > trace: > > actual: java.security.AccessControlException: access denied > (javax.management.MBeanTrustPermission register) > [java] at java.security.AccessControlContext.checkPermission > (AccessControlContext.java:264) > java.lang.SecurityManager.checkPermission (SecurityManager.java:568) > > com > .sun > .jmx > .interceptor.DefaultMBeanServerInterceptor.checkMBeanTrustPermission > (DefaultMBeanServerInterceptor.java:1724) > com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean > (DefaultMBeanServerInterceptor.java:335) > com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean > (JmxMBeanServer.java:497) > sun.reflect.NativeMethodAccessorImpl.invoke0 > (NativeMethodAccessorImpl.java:-2) > sun.reflect.NativeMethodAccessorImpl.invoke > (NativeMethodAccessorImpl.java:39) > sun.reflect.DelegatingMethodAccessorImpl.invoke > (DelegatingMethodAccessorImpl.java:25) > java.lang.reflect.Method.invoke (Method.java:585) > clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:90) > clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:28) > clojure.contrib.jmx/register_mbean (server.clj:17) > > Since the code works at the REPL, I suspect a classloader issue. Am I > right? If so, can I change the classloader used by Clojure's proxy > function? >
I took a quick look at the lib, and yes, it could be a classloader thing. But I wonder if your plan is destined for success. If registerMBean is capturing the actual class of a proxy there are a few issues. One is that proxy doesn't guarantee a unique class per usage, in fact, currently it will reuse the same class for any invocation with the same set of superclasses. The second has to do with visibility. There simply is no way to dynamically generate a class accessible by name from every other class in an app, due at least to classloader hierarchy in the basic Java case, and modularity systems like OSGi make it less possible, since they are working to prevent exactly that. Even if proxy did generate a unique class per call site _and_ you could establish a classloader of your choice with context classloader or something, you'd still have a problem in that there is no standard root classloader that will load classes for you from bytecode, so such a classloader has to be a child of another, and thus the classes it loads not universally visible. The bottom line is that the instances generated by proxy are meant to be manipulated via the interfaces they implement. The specific classes of which they are instances is an implementation detail. Rich --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---