Find java class dependencies at runtime

前端 未结 2 1539
不思量自难忘°
不思量自难忘° 2020-12-18 15:11

What\'s the most effective way to get a list of dependencies for a Java class at runtime?

Using this (based on ASM ByteCode Manipulator 3.3.1), I can do the followin

2条回答
  •  攒了一身酷
    2020-12-18 15:51

    “Is there any alternative to using ASM to get a list of dependencies for a class?” Well there are several alternatives. One is to implement the operation without additional libraries.

    “Why the heck is that so difficult?” It’s not that difficult. But you should not judge by looking at a mighty library intended for lots of different use cases when you need it for a rather tiny task.

    Here is a piece of code performing the entire dependency scan in a straightforward manner. It’s quite efficient but will become a nightmare once you want it to do other things than that. So once you need other byte code operations I recommend turning back to use a library for it.

    public static Set> getDependencies(Class from)
      throws IOException, ClassNotFoundException {
    
      while(from.isArray()) from=from.getComponentType();
      if(from.isPrimitive()) return Collections.emptySet();
      byte[] buf=null;
      int read=0;
      try(InputStream is=from.getResourceAsStream(from.getSimpleName()+".class")) {
        for(int r; ;read+=r) {
          int num=Math.max(is.available()+100, 100);
          if(buf==null) buf=new byte[num];
          else if(buf.length-read names=getDependencies(ByteBuffer.wrap(buf, 0, read));
      Set> classes=new HashSet<>(names.size());
      ClassLoader cl=from.getClassLoader();
      for(String name:names) classes.add(Class.forName(name, false, cl));
      classes.remove(from);// remove self-reference
      return classes;
    }
    
    public static Set getDependencies(ByteBuffer bb) {
    
      if(bb.getInt()!=0xcafebabe)
        throw new IllegalArgumentException("Not a class file");
      bb.position(8);
      final int numC=bb.getChar();
      BitSet clazz=new BitSet(numC), sign=new BitSet(numC);
      for(int c=1; c names=new HashSet<>();
      for(int c=1; c names,
      ByteBuffer src, int s, int strSize) {
      final int e=s+strSize;
      StringBuilder dst=new StringBuilder(strSize);
      ascii: {
        for(;s names,
      ByteBuffer bb, int s, int l) {
      final int e=s+l;
      for(;s

提交回复
热议问题