IF , you don’t want to change the source code, one of the possible solutions is to copy the source code from the library, whose class has the until(Function) method in your source code. and then adding the remote code until(Predicate) to the source code. final code as below:
package ???;//the package of the library which class have `until` method class ??? {//the class copied from the library which have `until` method <T> boolean until(Predicate<T> predicate){ return until(new Function<T,Boolean>(){ public Boolean apply(T value){ return predicate.apply(value); } }); } <T,R> R until(Function<T,R> function){ // the source code from the library } //... other source code from the library }
ClassLoader load your class copied from the library, not from the library. since ClassLoader uses the delegation model to search for classes / resources, and AppClassLoader will always find the class in the classpath, and then external banners in turn:
The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader . When asked to search for a class or resource, an instance of ClassLoader delegates the search for the class or resource to its parent class loader before trying to find the class or resource itself. The virtual machine’s built-in class loader, called the bootstrap class loader, itself does not have a parent, but can serve as the parent of an instance of ClassLoader .
Another option is to write your own ClassLoader and then write a proxy to access your library class. this is useful if you cannot copy the outer class of the library, since it depends on many inner classes. for example, let's say you have a library class as shown below:
public class Library<T> { private final List<T> items; public Library(T... items) { this.items = Arrays.asList(items); } public boolean exists(Function<? super T, Boolean> condition) { return items.stream().anyMatch(condition::apply); } }
It then declares an interface to match the library class as follows:
public interface LibraryAccess<T> { boolean exists(Function<? super T, Boolean> condition); }
Last write your own class, overwrite the library class as shown below:
public class Library<T> { private final LibraryAccess<T> library; public Library(T... items) { // create library from external jars by your own ClassLoader & reflect api library = LibraryAccess.newInstance(items); } public boolean exists(Predicate<? super T> condition) { return library.exists(condition::test); } public boolean exists(Function<? super T, Boolean> condition) { return library.exists(condition); } }
all source and test code i checked in github.