6

I'd like to obtain the list of imports a class has. Since this is removed by the compiler, I suppose via reflection one could scan through the class, it's methods, fields and so on and collect a list of classes which are required in order for the classloader to load the class. Is there some sort of library, tutorial, or article you could point me at so I could better understand how this can be done? (I understand similar questions have been asked, but I could not find a proper answer and I'm quite sure this should be possible). I saw some examples showing how you could do it, if you had the sources, but that would not necessarily be the case in my scenario.

Many thanks in advance!

carlspring
  • 31,231
  • 29
  • 115
  • 197
  • possible duplicate of [How to get all imports defined in a class using java reflection?](http://stackoverflow.com/questions/5701305/how-to-get-all-imports-defined-in-a-class-using-java-reflection) – Fritz Jul 29 '13 at 15:35
  • @Gamb: This is NOT a duplicate! I have already looked at that and I'm aware that you cannot get the exact list of imports. However, in theory you should be able to collect a list of all the classes used by your class using reflection. I am looking for such a library. – carlspring Jul 29 '13 at 15:37
  • 1
    You need to look at the raw byte code. Your class might need a class which needs another class. You have to keep doing this until you run out of classes. Note:this might be more than you need because a class might not need another class just because it references. Also a class might need via reflection another class. – Peter Lawrey Jul 29 '13 at 15:38
  • @carlspring What theory are you thinking of? Reflection can't find out which methods were actually called. You could try executing all the code and looking at the stacktrace, but then you might miss some execution paths. – Sotirios Delimanolis Jul 29 '13 at 15:39
  • @SotiriosDelimanolis: Executing the code will just give you the exceptions one by one and not all the missing classes. – carlspring Jul 29 '13 at 15:43
  • @PeterLawrey: Thanks for pointing that out. You are right. Any further suggestions? – carlspring Jul 29 '13 at 15:44
  • @carlspring I'm afraid the question itself is a duplicate. You, however, rely solely on theory and try to accomplish this at all costs. May I ask how do you plan (theorically) to identify imports such as `foo.bar.*`? – Fritz Jul 29 '13 at 15:50
  • @carlspring For the imports of one class alone, you can read the byte code with a library like ASM. – Peter Lawrey Jul 29 '13 at 15:59
  • @PeterLawrey: Do you think you could provide a working example of how that could be done with ASM? – carlspring Jul 29 '13 at 16:13
  • @carlspring The best examples are on the web site. It would take a couple of hours to write. – Peter Lawrey Jul 29 '13 at 16:17

2 Answers2

9

No, reflection will not help

void test() {
    Date date = new Date();
}

you cannot detect that Date is used inside method with reflection. But you can use Javassist https://github.com/jboss-javassist/javassist

    ClassPool cp = ClassPool.getDefault();
    Collection classes = cp.get("test.Test").getRefClasses();

this code produces a collection of the names of all the classes referenced in test.Test class

AlikElzin-kilaka
  • 34,335
  • 35
  • 194
  • 277
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
1

I don't think this is remotely possible except by reading the source .java file itself. I'm fairly sure Java just using the list to scan during compiling then throws it away.

Spring does stuff like this however, and there is a google project that can scan packages for annotations and the like (Forget the name--classpath?).

I recommend you look into spring, chances are it does exactly what you want and a lot more and does it in a way that the next programmer will understand automatically (if they know Spring).

Bill K
  • 62,186
  • 18
  • 105
  • 157
  • IoC is not exactly what I'm looking for, but you are indeed right that Spring seems to be doing some similar magic. – carlspring Jul 29 '13 at 15:42
  • Spring isn't just IoC any more, it makes aspect-oriented java more accessible. It can scan and instantiate packages and allows you to do things before and after methods are called, etc. – Bill K Jul 29 '13 at 15:58