简体   繁体   中英

Java - prevent field assignment using reflection on instantiation?

I have a java class in a 3rd party lib with a private member which is assigned at class instantiation.

public class CacheLookupUtil extends AbstractCacheLookupUtil<InvocationContext> {
  @Inject
  private BeanManagerUtil beanManagerUtil;

  private CacheKeyGenerator defaultCacheKeyGenerator = new DefaultCacheKeyGenerator();
  private CacheResolverFactory defaultCacheResolverFactory = new DefaultCacheResolverFactory();

  ...
  ...
}

My problem is that the assignment of defaultCacheResolverFactory is causing an exception due to the wrong constructor having been chosen.

If I try to subclass CacheLookupUtil , this assignment is still done in the parent class, so I'm no further ahead.

Is there any mechanism I can use in Java reflection that would allow me to construct/instantiate the object, but prevent the assignment of defaultCacheResolverFactory , and allowing me to set the value via reflection?

I know this is an ugly solution, but to be honest, I cannot visualize any other way to proceed.

Is DefaultCacheResolverFactory part of your libraries jar?

  1. If not I would guess that this is a version problem.

  2. Otherwise you should lookout for a bugfix version of your library or open a ticket.

  3. Last but not least you could use AspectJ Load-Time Weaving to manipulate the bytecode at class loading time. But this requires that you always start your code with Load-Time Weaving. See Load-Time Weaving .

So I personally would prefer option 1 or 2.

Check the version of library that contains CacheLookupUtil (I understand that its a thirdparty class). For example, let it be jar-A .

Then check the version of jar that contains DefaultCacheResolverFactory . If its also jar-A , this effectively means that this library doesn't work at this version, so you should upgrade. If its in some jar-B , then check pom.xml of jar-A itself, what version of dependency on jar-B is required, probably you override the version of this jar.

Then adjust the version so that jar-A 's expectations from the version of jar-B will match :)

For me its the best solution.

Now as for dirty tricks. One trick can be to create your own copy of CacheLookupUtil and put it into the same package, depending on class-loaders policy (you haven't specified in which environment do you run, so I assume plain java) it might load first and effectively "substitute" CacheLookupUtil from the jar.

Of course the same can be done with DefaultCacheResolverFactory (so that you could fix the no-op constructor there)

If you believe its a real bug, an another option to consider is to fork from the "buggy" library and create your own version of it with a fix. Of course you better make the developers of the original library to fix this bug so that eventually you could get back to the official version, in the world of open source, sometimes solutions like this work as long as the licencing permits doing so.

If it doesn't help, then Byte Code manipulation is the only way to fix as @PowerStat already mentioned. this I believe, Java Agent, class loading patching, AspectJ, and so forth. Hopefully you won't get there only because of this issue :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM