1 2 Previous Next 15 Replies Latest reply: Sep 3, 2008 10:09 AM by 807589 RSS

    Creating a private inner class using reflection

    796211
      Hi people. I need an implementation of an interface that is a private inner class. This is required purely for testing purposes. I thought I might be able to get it by reflection but am having difficulties. Please can anyone help?

      I need to test class C and that takes a BInterface. BInterface is implemented by B as a private inner class of A.

      eg:
      A=
      package com.test;
      
      public class A
      {
          public A()
          {
          }
      
          // ...
      
          private class B implements BInterface
          {
              private final A a;
              
              public  B(A a)
              {
                  this.a = a;
              }
      
              // ...
      
              public String getName()
              {
                  return "bla";
              }
          }
      }
      BInterface=
      package com.test;
      
      public interface BInterface
      {
          String getName();
      }
      C=
      package com.test;
      
      public class C
      {
          private final BInterface b;
      
          public C(BInterface b)
          {
              this.b = b;
          }
      
          // bla
      }
      and CTest=
      package com.test.tester;
      
      import com.test.A;
      import com.test.C;
      import com.test.BInterface;
      
      import java.lang.reflect.Constructor;
      
      public class CTest
      {
          public CTest()
          {
              BInterface bObject = null;
              try
              {
                  Class bClass = Class.forName("com.test.A$B");
                  Class[] params = {com.test.A.class, com.test.A.class};
                  Constructor constructor = bClass.getConstructor(params);
                  A a = new A();
                  Object[] args = {a, a};
                  bObject = (BInterface)constructor.newInstance(args);
              }
              catch (Exception e)
              {
                  e.printStackTrace();
              }
      
              C c = new C(bObject);
          }
      
          public static void main(String[] args)
          {
              new CTest();
          }
      }
      When I run CTest I get an exception that:

      java.lang.IllegalAccessException: Class com.test.tester.CTest can not access a member of class com.test.A$B with modifiers "public"
           at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
           at java.lang.reflect.Constructor.newInstance(Constructor.java:505) etc...

      Does anyone know what I'm doing wrong?

      Oh, and the package structure is fixed and there's nothing I can do about it.

      Much appreciated, Paul.
        • 1. Re: Creating a private inner class using reflection
          807589
          Either use dynamic proxies (google is your friend) which will allow you to generate a class at runtime which implements any interface(s) you need, or, if it's for actual testing (rather than just trying stuff out) you might be interested in a mock objects framework, such as EasyMock. On the subject of dynamic proxies, libraries like CGLIB and ASM will allow you to generate proxies for classes as well as interfaces

          hth
          • 2. Re: Creating a private inner class using reflection
            796211
            Thanks for the response. Does this mean it is not possible to do it the way I was trying to do it?
            • 3. Re: Creating a private inner class using reflection
              807589
              No, sorry. I was in the middle of editing my reply when you replied to it! I think I mis-read your question, or the wording doesn't quite match up with what your code seems to say. What is it you want? To instantiate that inner class? Inner classes have an implicit constructor that takes an instance of their enclosing type
              • 4. Re: Creating a private inner class using reflection
                796211
                Yes, basically, if you look at the test, I need to instantiate B (which is an private inner class of A) and then pass it into C. In the normal code, this isn't a problem but I am trying to unit test C in isolation and so need that implementation.

                I am passing an object of the enclosing type in (in fact I am passing two of those objects in) to the newInstance method as args.
                • 5. Re: Creating a private inner class using reflection
                  796211
                  If I move CTest into the same package as class A then it works.

                  However, I can't do this because of the way the project has been set up - it needs to be in the tester sub package.

                  (it's an really bad way to do it I know - usually I have a different source root and store the tests in the same package as the classes)

                  Is there anyway I can accomplish what I am trying?

                  Thanks, Paul.
                  • 6. Re: Creating a private inner class using reflection
                    807589
                    >
                    Yes, basically, if you look at the test, I need to instantiate B (which is an private inner class of A) and then pass it into C. In the normal code, this isn't a problem but I am trying to unit test C in isolation and so need that implementation.
                    >

                    You're not going to want to hear this, but either your test is broken or your class design is broken.

                    A unit test is supposed to test a class in isolation: verifying that it properly implements its contract. From a simple testing perspective, if you require an instance of B, which requires an instance of A, which may in the future require an instance of D, you're not testing in isolation.

                    From a design perspective, the contract of C requires a class that's not visible to it. Now, there may be a good reason for B to be an inner class of A. However, from a design perspective you should interpose some visible class -- typically an interface IB -- that is implemented by B and could also be implemented by a stub/mock object for testing C.

                    If you get deep enough into the philosophy of unit testing, you'll discover that the end result of a set of true unit tests is that you create interfaces for all functionality, and then implementation classes for those interfaces. Some people take this too far, creating interfaces in front of POJOs, but at least in the case of behavioral classes, I think it's an excellent idea.
                    • 7. Re: Creating a private inner class using reflection
                      807589
                      I have a similar problem as this one that maybe you can help with.
                      I'm creating an application to do blackbox testing to other applications' GUIs. During the process I'm ripping the application and executing methods through reflection to ask for the position, size, etc..
                      It was all working fine until I come up with an application that have defined a button as an inner class (with default modifier) of a panel. When I try to execute a method on this object I obviously get the same exception that Boomah had.
                      Is there some hack that would allow me to access it? (Remember I'm doing blackbox testing and therefore I'm not able to change the source code)

                      thanks,
                      José Tavares
                      • 8. Re: Creating a private inner class using reflection
                        807589
                        Well I've just found a workaround to this problem but I'm afraid of potential side effects. What I do is setAccessible(true) to the method before invoking it.
                        What possible side effects can this approach rise?

                        Thanks,
                        José Tavares
                        • 9. Re: Creating a private inner class using reflection
                          807589
                          jpsstavares wrote:
                          Well I've just found a workaround to this problem but I'm afraid of potential side effects. What I do is setAccessible(true) to the method before invoking it.
                          What possible side effects can this approach rise?

                          Thanks,
                          José Tavares
                          The side effect is that you're now not black box testing. Why do you need to get at this class? You say it's an inner class, but don't say whether it's an anonymous type or not. Why d'you need it? It's package-private, right? Why not put your test in the same package? Common enough pattern, that. But consider first whether you really need access to the class at all
                          • 10. Re: Creating a private inner class using reflection
                            807589
                            The class is just defined as class ColorButton as inner class of public class ColorSetupPanel.

                            The application I'm coding, executes a user provided jar and test it (generates clicks, keystrokes, etc). To do so I analyze the application's components and classify them. Then I need to store some values of these components, like position, size, text, etc, for future generation of more test cases.

                            In this particular application (I was testing [JabRef |http://jabref.sourceforge.net/] ) they have a ColorSetupPanel that has ColorButtons, an inner class of it. When I was trying to get the ColorButton position the IllegalAcessException was thrown.

                            José Tavares

                            Edit: My application is supposed to test any Swing Application.

                            Edited by: jpsstavares on Sep 3, 2008 5:50 AM
                            • 11. Re: Creating a private inner class using reflection
                              807589
                              jpsstavares wrote:
                              The class is just defined as class ColorButton as inner class of public class ColorSetupPanel.

                              The application I'm coding, executes a user provided jar and test it (generates clicks, keystrokes, etc). To do so I analyze the application's components and classify them. Then I need to store some values of these components, like position, size, text, etc, for future generation of more test cases.
                              All of those properties are available through JButton's API (I'm guessing this class is a subclass of JButton). As long as you can get hold of an instance of this class - which should be possible through whatever's containing them - then you can use JButton
                              • 12. Re: Creating a private inner class using reflection
                                807589
                                Yes your right, I could make a huge if-else-if statement verifying the instance of every object that I catch.

                                But in the design phase we decide that we wanted to store the methods needed to define a component in a XML file so it could be easily extended.

                                Thanks for your thoughts and suggestions!
                                • 13. Re: Creating a private inner class using reflection
                                  807589
                                  jpsstavares wrote:
                                  Yes your right, I could make a huge if-else-if statement verifying the instance of every object that I catch.

                                  But in the design phase we decide that we wanted to store the methods needed to define a component in a XML file so it could be easily extended.
                                  I'm trying very hard to put that in the context of your earlier posts, but it isn't working
                                  • 14. Re: Creating a private inner class using reflection
                                    807589
                                    Let me try to explain things clearer.
                                    During the ripping process I go through every component of the interface. At each one I could either:
                                    a) test the object and check if it is an instanceof JButton, JFrame, and every other type of swing component to get the properties I need to identify this component later (these properties vary according to the type of object); or
                                    b) have a configuration file that says that for each type of component what methods shall I use to get the properties I want.

                                    Both approaches would work, but if later on I need to extend it to support a new GUI library, for example. But it would be easier to add the types of components and the methods to get their properties to an XML file than add it to the code.

                                    Is it clearer? (I know. I have a problem explaining things..)
                                    1 2 Previous Next