byte-buddy
byte-buddy copied to clipboard
can I wrap a final static field value
we want to enhance field with annotation @WrapExecutorService:
before enhance:
@WrapExecutorService private static final ExecutorService executorService1 = Executors.newSingleThreadExecutor();
after enhance:
private static final ExecutorService executorService = NewExecutorService.of(Executors.newSingleThreadExecutor());
full example is following:
public class Main4 {
public static void main(String[] args) {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {TYPE,FIELD})
public @interface WrapExecutorService {
}
public static class Example{
@WrapExecutorService
private static final ExecutorService executorService1 = Executors.newSingleThreadExecutor();
private static final ExecutorService executorService2 = NewExecutorService.of(Executors.newSingleThreadExecutor());
}
public static class NewExecutorService implements ExecutorService {
private ExecutorService executorService;
public static ExecutorService of(ExecutorService executorService){
NewExecutorService newExecutorService = new NewExecutorService();
newExecutorService.executorService= executorService;
return newExecutorService;
}
@Override
public void shutdown() {
}
@Override
public List<Runnable> shutdownNow() {
return null;
}
@Override
public boolean isShutdown() {
return false;
}
@Override
public boolean isTerminated() {
return false;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public <T> Future<T> submit(Callable<T> task) {
return null;
}
@Override
public <T> Future<T> submit(Runnable task, T result) {
return null;
}
@Override
public Future<?> submit(Runnable task) {
return null;
}
@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
return null;
}
@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
return null;
}
@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
return null;
}
@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return null;
}
@Override
public void execute(Runnable command) {
}
}
}
You would intercept via .executable(isTypeInitializer())
and in the code you add, you would read the field and write back a modified value.
@raphw
field assigned with a fixed value by invokable(ElementMatchers.isTypeInitializer())
, can you show me how to read the old field value and create a new value by old field value .
public class Main4_github {
public static void main(String[] args) {
Instrumentation instrumentation = ByteBuddyAgent.install();
new AgentBuilder.Default()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.RedefinitionStrategy.Listener.StreamWriting.toSystemError())
.with(AgentBuilder.Listener.StreamWriting.toSystemError().withTransformationsOnly())
.with(AgentBuilder.InstallationListener.StreamWriting.toSystemError())
.type(ElementMatchers.declaresField(isAnnotatedWith(WrapExecutorService.class))
)
.transform(new AgentBuilder.Transformer() {
@Override //
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription,
ClassLoader classLoader, JavaModule module,
ProtectionDomain protectionDomain) {
FieldDescription.InDefinedShape inDefinedShape = typeDescription.getDeclaredFields().get(0);
ExecutorService executorServiceOld = Executors.newFixedThreadPool(2);
ExecutorService executorServiceNew = NewExecutorService.of(executorServiceOld);
return builder
.invokable(ElementMatchers.isTypeInitializer())
.intercept(FieldAccessor.of(inDefinedShape).setsValue(executorServiceNew));
}
})
.installOn(instrumentation);
System.out.println("Example.executorService3:" + Example.executorService3);
}
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {TYPE, FIELD, TYPE_USE})
public @interface WrapExecutorService {
}
@TtlEnable
public static class Example {
@WrapExecutorService
public static ExecutorService executorService3 =
new ThreadPoolExecutor(
1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static class NewExecutorService implements ExecutorService {
private ExecutorService executorService;
public static ExecutorService of(ExecutorService executorService) {
NewExecutorService newExecutorService = new NewExecutorService();
newExecutorService.executorService = executorService;
System.out.println("ExecutorService.of(..)-->" + executorService);
return newExecutorService;
}
@Override
public void shutdown() {
}
@Override
public List<Runnable> shutdownNow() {
return null;
}
@Override
public boolean isShutdown() {
return false;
}
@Override
public boolean isTerminated() {
return false;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public <T> Future<T> submit(Callable<T> task) {
return null;
}
@Override
public <T> Future<T> submit(Runnable task, T result) {
return null;
}
@Override
public Future<?> submit(Runnable task) {
return null;
}
@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
return null;
}
@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
return null;
}
@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
return null;
}
@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return null;
}
@Override
public void execute(Runnable command) {
}
}
}