Commit 5225abe9413b4aa801488bc01834bc3aedf386e7
1 parent
38127d17
some tweaks to HandlerList and added more javadoc
Showing
1 changed file
with
165 additions
and
54 deletions
java/common/com/mumfrey/liteloader/core/event/HandlerList.java
| @@ -82,9 +82,8 @@ public class HandlerList<T> extends LinkedList<T> | @@ -82,9 +82,8 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 82 | */ | 82 | */ |
| 83 | protected void bake() | 83 | protected void bake() |
| 84 | { | 84 | { |
| 85 | - HandlerListClassLoader<T> classLoader = new HandlerListClassLoader<T>(this.type, this.size()); | ||
| 86 | - this.bakedHandler = classLoader.newHandler(); | ||
| 87 | - this.bakedHandler.populate(this); | 85 | + HandlerListClassLoader<T> classLoader = new HandlerListClassLoader<T>(this.type); |
| 86 | + this.bakedHandler = classLoader.newHandler(this); | ||
| 88 | } | 87 | } |
| 89 | 88 | ||
| 90 | /** | 89 | /** |
| @@ -370,7 +369,22 @@ public class HandlerList<T> extends LinkedList<T> | @@ -370,7 +369,22 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 370 | { | 369 | { |
| 371 | public abstract T get(); | 370 | public abstract T get(); |
| 372 | 371 | ||
| 373 | - public abstract void populate(List<T> listeners); | 372 | + public abstract BakedHandlerList<T> populate(List<T> listeners); |
| 373 | + } | ||
| 374 | + | ||
| 375 | + /** | ||
| 376 | + * Exception to throw when failing to bake a handler list | ||
| 377 | + * | ||
| 378 | + * @author Adam Mummery-Smith | ||
| 379 | + */ | ||
| 380 | + static class BakingFailedException extends RuntimeException | ||
| 381 | + { | ||
| 382 | + private static final long serialVersionUID = 1L; | ||
| 383 | + | ||
| 384 | + public BakingFailedException(Throwable cause) | ||
| 385 | + { | ||
| 386 | + super("An unexpected error occurred while baking the handler list", cause); | ||
| 387 | + } | ||
| 374 | } | 388 | } |
| 375 | 389 | ||
| 376 | /** | 390 | /** |
| @@ -381,66 +395,118 @@ public class HandlerList<T> extends LinkedList<T> | @@ -381,66 +395,118 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 381 | */ | 395 | */ |
| 382 | static class HandlerListClassLoader<T> extends URLClassLoader | 396 | static class HandlerListClassLoader<T> extends URLClassLoader |
| 383 | { | 397 | { |
| 398 | + private static final String HANDLER_VAR_PREFIX = "handler$"; | ||
| 399 | + | ||
| 384 | /** | 400 | /** |
| 385 | * Unique index number, just to ensure no name clashes | 401 | * Unique index number, just to ensure no name clashes |
| 386 | */ | 402 | */ |
| 387 | private static int handlerIndex; | 403 | private static int handlerIndex; |
| 388 | 404 | ||
| 389 | - private int lineNumber = 1; | ||
| 390 | - | 405 | + /** |
| 406 | + * Interface type which this classloader is generating handler for | ||
| 407 | + */ | ||
| 391 | private final Class<T> type; | 408 | private final Class<T> type; |
| 392 | 409 | ||
| 410 | + /** | ||
| 411 | + * Calculated class ref for the class type so that we don't have to keep calling getName().replace('.', '/') | ||
| 412 | + */ | ||
| 393 | private final String typeRef; | 413 | private final String typeRef; |
| 394 | 414 | ||
| 415 | + /** | ||
| 416 | + * Size of the handler list | ||
| 417 | + */ | ||
| 395 | private int size; | 418 | private int size; |
| 396 | - | 419 | + |
| 397 | /** | 420 | /** |
| 398 | * @param type | 421 | * @param type |
| 399 | * @param size | 422 | * @param size |
| 400 | */ | 423 | */ |
| 401 | - HandlerListClassLoader(Class<T> type, int size) | 424 | + HandlerListClassLoader(Class<T> type) |
| 402 | { | 425 | { |
| 403 | super(new URL[0], Launch.classLoader); | 426 | super(new URL[0], Launch.classLoader); |
| 404 | this.type = type; | 427 | this.type = type; |
| 405 | this.typeRef = type.getName().replace('.', '/'); | 428 | this.typeRef = type.getName().replace('.', '/'); |
| 406 | - this.size = size; | ||
| 407 | } | 429 | } |
| 408 | 430 | ||
| 409 | /** | 431 | /** |
| 410 | * Create and return a new baked handler list | 432 | * Create and return a new baked handler list |
| 411 | */ | 433 | */ |
| 412 | @SuppressWarnings("unchecked") | 434 | @SuppressWarnings("unchecked") |
| 413 | - public BakedHandlerList<T> newHandler() | 435 | + public BakedHandlerList<T> newHandler(HandlerList<T> list) |
| 436 | + { | ||
| 437 | + this.size = list.size(); | ||
| 438 | + | ||
| 439 | + Class<BakedHandlerList<T>> handlerClass = null; | ||
| 440 | + | ||
| 441 | + try | ||
| 442 | + { | ||
| 443 | + // Inflect the class name and attempt to generate the class | ||
| 444 | + String className = HandlerListClassLoader.getNextClassName(Obf.HandlerList.name, this.type.getSimpleName()); | ||
| 445 | + handlerClass = (Class<BakedHandlerList<T>>)this.loadClass(className); | ||
| 446 | + } | ||
| 447 | + catch (ClassNotFoundException ex) | ||
| 448 | + { | ||
| 449 | + throw new BakingFailedException(ex); | ||
| 450 | + } | ||
| 451 | + | ||
| 452 | + try | ||
| 453 | + { | ||
| 454 | + // Create an instance of the class, populate the entries from the supplied list and return it | ||
| 455 | + BakedHandlerList<T> handlerList = this.createInstance(handlerClass); | ||
| 456 | + return handlerList.populate(list); | ||
| 457 | + } | ||
| 458 | + catch (InstantiationException ex) | ||
| 459 | + { | ||
| 460 | + throw new BakingFailedException(ex); | ||
| 461 | + } | ||
| 462 | + } | ||
| 463 | + | ||
| 464 | + /** | ||
| 465 | + * Create an instance of the baked class | ||
| 466 | + * | ||
| 467 | + * @param handlerClass Baked HandlerList class | ||
| 468 | + * @return new instance of the Baked HandlerList class | ||
| 469 | + * @throws InstantiationException if the handler can't be created for some reason | ||
| 470 | + */ | ||
| 471 | + private BakedHandlerList<T> createInstance(Class<BakedHandlerList<T>> handlerClass) throws InstantiationException | ||
| 414 | { | 472 | { |
| 415 | try | 473 | try |
| 416 | { | 474 | { |
| 417 | - String className = this.getNextClassName(); | ||
| 418 | - Class<BakedHandlerList<T>> handlerClass = (Class<BakedHandlerList<T>>)this.loadClass(className); | ||
| 419 | Constructor<BakedHandlerList<T>> ctor = handlerClass.getDeclaredConstructor(); | 475 | Constructor<BakedHandlerList<T>> ctor = handlerClass.getDeclaredConstructor(); |
| 420 | ctor.setAccessible(true); | 476 | ctor.setAccessible(true); |
| 421 | return ctor.newInstance(); | 477 | return ctor.newInstance(); |
| 422 | } | 478 | } |
| 423 | catch (Exception ex) | 479 | catch (Exception ex) |
| 424 | { | 480 | { |
| 425 | - throw new RuntimeException(ex); | 481 | + InstantiationException ie = new InstantiationException("Error instantiating class " + handlerClass); |
| 482 | + ie.setStackTrace(ex.getStackTrace()); | ||
| 483 | + throw ie; | ||
| 426 | } | 484 | } |
| 427 | } | 485 | } |
| 428 | 486 | ||
| 487 | + /* (non-Javadoc) | ||
| 488 | + * @see java.net.URLClassLoader#findClass(java.lang.String) | ||
| 489 | + */ | ||
| 429 | @Override | 490 | @Override |
| 430 | protected Class<?> findClass(String name) throws ClassNotFoundException | 491 | protected Class<?> findClass(String name) throws ClassNotFoundException |
| 431 | { | 492 | { |
| 432 | try | 493 | try |
| 433 | { | 494 | { |
| 495 | + // Read the basic class template | ||
| 434 | byte[] bytes = Launch.classLoader.getClassBytes(Obf.BakedHandlerList.name); | 496 | byte[] bytes = Launch.classLoader.getClassBytes(Obf.BakedHandlerList.name); |
| 435 | ClassReader classReader = new ClassReader(bytes); | 497 | ClassReader classReader = new ClassReader(bytes); |
| 436 | ClassNode classNode = new ClassNode(); | 498 | ClassNode classNode = new ClassNode(); |
| 437 | classReader.accept(classNode, ClassReader.EXPAND_FRAMES); | 499 | classReader.accept(classNode, ClassReader.EXPAND_FRAMES); |
| 438 | 500 | ||
| 501 | + // Apply all transformations to the class, injects our custom code | ||
| 439 | this.transform(name, classNode); | 502 | this.transform(name, classNode); |
| 440 | 503 | ||
| 504 | + // Write the class | ||
| 441 | ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); | 505 | ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); |
| 442 | classNode.accept(classWriter); | 506 | classNode.accept(classWriter); |
| 443 | bytes = classWriter.toByteArray(); | 507 | bytes = classWriter.toByteArray(); |
| 508 | + | ||
| 509 | + // Delegate to ClassLoader's usual behaviour to load the class we just generated | ||
| 444 | return this.defineClass(name, bytes, 0, bytes.length); | 510 | return this.defineClass(name, bytes, 0, bytes.length); |
| 445 | } | 511 | } |
| 446 | catch (Throwable th) | 512 | catch (Throwable th) |
| @@ -450,30 +516,49 @@ public class HandlerList<T> extends LinkedList<T> | @@ -450,30 +516,49 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 450 | } | 516 | } |
| 451 | } | 517 | } |
| 452 | 518 | ||
| 453 | - private void transform(String name, ClassNode classNode) | 519 | + /** |
| 520 | + * Perform all class bytecode transformations | ||
| 521 | + * | ||
| 522 | + * @param name | ||
| 523 | + * @param classNode | ||
| 524 | + * @throws IOException | ||
| 525 | + */ | ||
| 526 | + private void transform(String name, ClassNode classNode) throws IOException | ||
| 454 | { | 527 | { |
| 455 | LiteLoaderLogger.info("Baking listener list for %s with %d listeners", this.type.getSimpleName(), this.size); | 528 | LiteLoaderLogger.info("Baking listener list for %s with %d listeners", this.type.getSimpleName(), this.size); |
| 456 | LiteLoaderLogger.debug("Generating: %s", name); | 529 | LiteLoaderLogger.debug("Generating: %s", name); |
| 457 | 530 | ||
| 458 | this.populateClass(name, classNode); | 531 | this.populateClass(name, classNode); |
| 459 | this.transformMethods(name, classNode); | 532 | this.transformMethods(name, classNode); |
| 460 | - this.injectInterfaceMethods(name, classNode); | 533 | + this.injectInterfaceMethods(classNode, this.type.getName()); |
| 461 | } | 534 | } |
| 462 | 535 | ||
| 536 | + /** | ||
| 537 | + * Populate the class node itself | ||
| 538 | + * | ||
| 539 | + * @param name | ||
| 540 | + * @param classNode | ||
| 541 | + */ | ||
| 463 | private void populateClass(String name, ClassNode classNode) | 542 | private void populateClass(String name, ClassNode classNode) |
| 464 | { | 543 | { |
| 465 | classNode.access = classNode.access & ~Opcodes.ACC_ABSTRACT; | 544 | classNode.access = classNode.access & ~Opcodes.ACC_ABSTRACT; |
| 466 | classNode.name = name.replace('.', '/'); | 545 | classNode.name = name.replace('.', '/'); |
| 467 | classNode.superName = Obf.BakedHandlerList.ref; | 546 | classNode.superName = Obf.BakedHandlerList.ref; |
| 468 | - classNode.interfaces.add(this.type.getName().replace('.', '/')); | ||
| 469 | - classNode.sourceFile = "Dynamic"; | 547 | + classNode.interfaces.add(this.typeRef); |
| 548 | + classNode.sourceFile = name.substring(name.lastIndexOf('.') + 1) + ".java"; | ||
| 470 | 549 | ||
| 471 | - for (int i = 0; i < this.size; i++) | 550 | + for (int handlerIndex = 0; handlerIndex < this.size; handlerIndex++) |
| 472 | { | 551 | { |
| 473 | - classNode.fields.add(new FieldNode(Opcodes.ACC_PRIVATE, "handler$" + i, "L" + this.typeRef + ";", null, null)); | 552 | + classNode.fields.add(new FieldNode(Opcodes.ACC_PRIVATE, HandlerListClassLoader.HANDLER_VAR_PREFIX + handlerIndex, "L" + this.typeRef + ";", null, null)); |
| 474 | } | 553 | } |
| 475 | } | 554 | } |
| 476 | 555 | ||
| 556 | + /** | ||
| 557 | + * Transform existing methods in the template class | ||
| 558 | + * | ||
| 559 | + * @param name | ||
| 560 | + * @param classNode | ||
| 561 | + */ | ||
| 477 | private void transformMethods(String name, ClassNode classNode) | 562 | private void transformMethods(String name, ClassNode classNode) |
| 478 | { | 563 | { |
| 479 | for (Iterator<MethodNode> methodIterator = classNode.methods.iterator(); methodIterator.hasNext();) | 564 | for (Iterator<MethodNode> methodIterator = classNode.methods.iterator(); methodIterator.hasNext();) |
| @@ -494,6 +579,12 @@ public class HandlerList<T> extends LinkedList<T> | @@ -494,6 +579,12 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 494 | } | 579 | } |
| 495 | } | 580 | } |
| 496 | 581 | ||
| 582 | + /** | ||
| 583 | + * Transform the constructor | ||
| 584 | + * | ||
| 585 | + * @param classNode | ||
| 586 | + * @param method | ||
| 587 | + */ | ||
| 497 | private void processCtor(ClassNode classNode, MethodNode method) | 588 | private void processCtor(ClassNode classNode, MethodNode method) |
| 498 | { | 589 | { |
| 499 | for (Iterator<AbstractInsnNode> iter = method.instructions.iterator(); iter.hasNext();) | 590 | for (Iterator<AbstractInsnNode> iter = method.instructions.iterator(); iter.hasNext();) |
| @@ -510,6 +601,12 @@ public class HandlerList<T> extends LinkedList<T> | @@ -510,6 +601,12 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 510 | } | 601 | } |
| 511 | } | 602 | } |
| 512 | 603 | ||
| 604 | + /** | ||
| 605 | + * Transform .get() | ||
| 606 | + * | ||
| 607 | + * @param classNode | ||
| 608 | + * @param method | ||
| 609 | + */ | ||
| 513 | private void processGet(ClassNode classNode, MethodNode method) | 610 | private void processGet(ClassNode classNode, MethodNode method) |
| 514 | { | 611 | { |
| 515 | method.access = method.access & ~Opcodes.ACC_ABSTRACT; | 612 | method.access = method.access & ~Opcodes.ACC_ABSTRACT; |
| @@ -519,40 +616,41 @@ public class HandlerList<T> extends LinkedList<T> | @@ -519,40 +616,41 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 519 | method.instructions.add(new InsnNode(Opcodes.ARETURN)); | 616 | method.instructions.add(new InsnNode(Opcodes.ARETURN)); |
| 520 | } | 617 | } |
| 521 | 618 | ||
| 619 | + /** | ||
| 620 | + * Transform .processPopulate() | ||
| 621 | + * | ||
| 622 | + * @param classNode | ||
| 623 | + * @param method | ||
| 624 | + */ | ||
| 522 | private void processPopulate(ClassNode classNode, MethodNode method) | 625 | private void processPopulate(ClassNode classNode, MethodNode method) |
| 523 | { | 626 | { |
| 524 | method.access = method.access & ~Opcodes.ACC_ABSTRACT; | 627 | method.access = method.access & ~Opcodes.ACC_ABSTRACT; |
| 525 | method.instructions.clear(); | 628 | method.instructions.clear(); |
| 526 | 629 | ||
| 527 | - for (int i = 0; i < this.size; i++) | 630 | + for (int handlerIndex = 0; handlerIndex < this.size; handlerIndex++) |
| 528 | { | 631 | { |
| 529 | method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); | 632 | method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); |
| 530 | method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); | 633 | method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); |
| 531 | - method.instructions.add(new IntInsnNode(Opcodes.BIPUSH, i)); | 634 | + method.instructions.add(new IntInsnNode(Opcodes.BIPUSH, handlerIndex)); |
| 532 | method.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true)); | 635 | method.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true)); |
| 533 | method.instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, this.typeRef)); | 636 | method.instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, this.typeRef)); |
| 534 | - method.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, "handler$" + i, "L" + this.typeRef + ";")); | 637 | + method.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, HandlerListClassLoader.HANDLER_VAR_PREFIX + handlerIndex, "L" + this.typeRef + ";")); |
| 535 | } | 638 | } |
| 536 | 639 | ||
| 537 | - method.instructions.add(new InsnNode(Opcodes.RETURN)); | ||
| 538 | - } | ||
| 539 | - | ||
| 540 | - private void injectInterfaceMethods(String name, ClassNode classNode) | ||
| 541 | - { | ||
| 542 | - try | ||
| 543 | - { | ||
| 544 | - String interfaceName = this.type.getName(); | ||
| 545 | - this.injectInterfaceMethods(classNode, interfaceName); | ||
| 546 | - } | ||
| 547 | - catch (IOException ex) | ||
| 548 | - { | ||
| 549 | - ex.printStackTrace(); | ||
| 550 | - } | 640 | + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); |
| 641 | + method.instructions.add(new InsnNode(Opcodes.ARETURN)); | ||
| 551 | } | 642 | } |
| 552 | 643 | ||
| 644 | + /** | ||
| 645 | + * Recurse down the interface inheritance hierarchy and inject methods to handle each interface | ||
| 646 | + * | ||
| 647 | + * @param classNode | ||
| 648 | + * @param interfaceName | ||
| 649 | + * @throws IOException | ||
| 650 | + */ | ||
| 553 | private void injectInterfaceMethods(ClassNode classNode, String interfaceName) throws IOException | 651 | private void injectInterfaceMethods(ClassNode classNode, String interfaceName) throws IOException |
| 554 | { | 652 | { |
| 555 | - ClassReader interfaceReader = new ClassReader(this.getInterfaceBytes(interfaceName)); | 653 | + ClassReader interfaceReader = new ClassReader(HandlerListClassLoader.getInterfaceBytes(interfaceName)); |
| 556 | ClassNode interfaceNode = new ClassNode(); | 654 | ClassNode interfaceNode = new ClassNode(); |
| 557 | interfaceReader.accept(interfaceNode, 0); | 655 | interfaceReader.accept(interfaceNode, 0); |
| 558 | 656 | ||
| @@ -568,6 +666,12 @@ public class HandlerList<T> extends LinkedList<T> | @@ -568,6 +666,12 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 568 | } | 666 | } |
| 569 | } | 667 | } |
| 570 | 668 | ||
| 669 | + /** | ||
| 670 | + * Inject the supplied interface method into the target class an populate it with method calls to the list members | ||
| 671 | + * | ||
| 672 | + * @param classNode | ||
| 673 | + * @param method | ||
| 674 | + */ | ||
| 571 | private void populateInterfaceMethod(ClassNode classNode, MethodNode method) | 675 | private void populateInterfaceMethod(ClassNode classNode, MethodNode method) |
| 572 | { | 676 | { |
| 573 | Type returnType = Type.getReturnType(method.desc); | 677 | Type returnType = Type.getReturnType(method.desc); |
| @@ -577,13 +681,13 @@ public class HandlerList<T> extends LinkedList<T> | @@ -577,13 +681,13 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 577 | Type[] args = Type.getArgumentTypes(method.desc); | 681 | Type[] args = Type.getArgumentTypes(method.desc); |
| 578 | method.access = Opcodes.ACC_PUBLIC; | 682 | method.access = Opcodes.ACC_PUBLIC; |
| 579 | 683 | ||
| 580 | - for (int i = 0; i < this.size; i++) | 684 | + for (int handlerIndex = 0; handlerIndex < this.size; handlerIndex++) |
| 581 | { | 685 | { |
| 582 | LabelNode lineNumberLabel = new LabelNode(new Label()); | 686 | LabelNode lineNumberLabel = new LabelNode(new Label()); |
| 583 | method.instructions.add(lineNumberLabel); | 687 | method.instructions.add(lineNumberLabel); |
| 584 | - method.instructions.add(new LineNumberNode(++this.lineNumber, lineNumberLabel)); | 688 | + method.instructions.add(new LineNumberNode(100 + handlerIndex, lineNumberLabel)); |
| 585 | method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); | 689 | method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); |
| 586 | - method.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, "handler$" + i, "L" + this.typeRef + ";")); | 690 | + method.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, HandlerListClassLoader.HANDLER_VAR_PREFIX + handlerIndex, "L" + this.typeRef + ";")); |
| 587 | this.invokeInterfaceMethod(method, args); | 691 | this.invokeInterfaceMethod(method, args); |
| 588 | } | 692 | } |
| 589 | 693 | ||
| @@ -591,6 +695,12 @@ public class HandlerList<T> extends LinkedList<T> | @@ -591,6 +695,12 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 591 | } | 695 | } |
| 592 | } | 696 | } |
| 593 | 697 | ||
| 698 | + /** | ||
| 699 | + * Inject instructions into the supplied method to invoke the same method on the supplied interface | ||
| 700 | + * | ||
| 701 | + * @param method | ||
| 702 | + * @param args | ||
| 703 | + */ | ||
| 594 | private void invokeInterfaceMethod(MethodNode method, Type[] args) | 704 | private void invokeInterfaceMethod(MethodNode method, Type[] args) |
| 595 | { | 705 | { |
| 596 | int argNumber = 1; | 706 | int argNumber = 1; |
| @@ -603,27 +713,28 @@ public class HandlerList<T> extends LinkedList<T> | @@ -603,27 +713,28 @@ public class HandlerList<T> extends LinkedList<T> | ||
| 603 | method.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, this.typeRef, method.name, method.desc, true)); | 713 | method.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, this.typeRef, method.name, method.desc, true)); |
| 604 | } | 714 | } |
| 605 | 715 | ||
| 606 | - private String getNextClassName() | 716 | + /** |
| 717 | + * @param baseName | ||
| 718 | + * @param typeName | ||
| 719 | + * @return | ||
| 720 | + */ | ||
| 721 | + private static String getNextClassName(String baseName, String typeName) | ||
| 607 | { | 722 | { |
| 608 | - return String.format("%s$%s$%s", Obf.HandlerList.name, this.type.getSimpleName(), HandlerListClassLoader.handlerIndex++); | 723 | + return String.format("%s$%s%d", baseName, typeName, HandlerListClassLoader.handlerIndex++); |
| 609 | } | 724 | } |
| 610 | 725 | ||
| 611 | - private byte[] getInterfaceBytes(String name) throws IOException | 726 | + /** |
| 727 | + * @param name | ||
| 728 | + * @return | ||
| 729 | + * @throws IOException | ||
| 730 | + */ | ||
| 731 | + private static byte[] getInterfaceBytes(String name) throws IOException | ||
| 612 | { | 732 | { |
| 613 | byte[] bytes = Launch.classLoader.getClassBytes(name); | 733 | byte[] bytes = Launch.classLoader.getClassBytes(name); |
| 614 | 734 | ||
| 615 | - final List<IClassTransformer> transformers = Launch.classLoader.getTransformers(); | ||
| 616 | - | ||
| 617 | - for (final IClassTransformer transformer : transformers) | 735 | + for (final IClassTransformer transformer : Launch.classLoader.getTransformers()) |
| 618 | { | 736 | { |
| 619 | - try | ||
| 620 | - { | ||
| 621 | - bytes = transformer.transform(name, name, bytes); | ||
| 622 | - } | ||
| 623 | - catch (Exception ex) | ||
| 624 | - { | ||
| 625 | - ex.printStackTrace(); | ||
| 626 | - } | 737 | + bytes = transformer.transform(name, name, bytes); |
| 627 | } | 738 | } |
| 628 | 739 | ||
| 629 | return bytes; | 740 | return bytes; |