简体   繁体   English

Java - 使用实例化反射来防止字段分配?

[英]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. 我在第三方库中有一个java类,其私有成员在类实例化时分配。

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. 我的问题是defaultCacheResolverFactory的赋值由于选择了错误的构造函数而导致异常。

If I try to subclass CacheLookupUtil , this assignment is still done in the parent class, so I'm no further ahead. 如果我尝试将CacheLookupUtil子类CacheLookupUtil ,那么这个赋值仍然在父类中完成,所以我没有更进一步。

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? 有没有我可以在Java反射中使用的机制允许我构造/实例化对象,但是阻止了defaultCacheResolverFactory的赋值,并允许我通过反射设置值?

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? DefaultCacheResolverFactory是库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. 最后但并非最不重要的是,您可以使用AspectJ Load-Time Weaving在类加载时操作字节码。 But this requires that you always start your code with Load-Time Weaving. 但这要求您始终使用Load-Time Weaving启动代码。 See Load-Time Weaving . 请参阅加载时编织

So I personally would prefer option 1 or 2. 所以我个人更喜欢选项1或2。

Check the version of library that contains CacheLookupUtil (I understand that its a thirdparty class). 检查包含CacheLookupUtil的库的版本(我理解它是第三方类)。 For example, let it be jar-A . 例如,让它成为jar-A

Then check the version of jar that contains DefaultCacheResolverFactory . 然后检查包含DefaultCacheResolverFactory的jar版本。 If its also jar-A , this effectively means that this library doesn't work at this version, so you should upgrade. 如果它也是jar-A ,这实际上意味着这个库在这个版本上不起作用,所以你应该升级。 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. 如果它在某个jar-B中 ,那么检查jar-A本身的pom.xml ,需要什么版本的jar-B依赖,可能你会覆盖这个jar的版本。

Then adjust the version so that jar-A 's expectations from the version of jar-B will match :) 然后调整版本,以便jar-Ajar-B版本的期望匹配:)

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. 一个技巧可以是创建自己的CacheLookupUtil副本并将其放入同一个包中,具体取决于类加载器策略(您没有指定在哪个环境中运行,所以我假设是普通的java)它可能首先加载并有效地加载从jar中“替换” CacheLookupUtil

Of course the same can be done with DefaultCacheResolverFactory (so that you could fix the no-op constructor there) 当然可以使用DefaultCacheResolverFactory完成同样的操作(这样你就可以在那里修复no-op构造函数)

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. 如果您认为它是一个真正的错误,另一个需要考虑的选择是从“buggy”库中分叉并使用修复程序创建自己的版本。 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. 当然,你最好让原始库的开发人员修复这个bug,这样你最终可以回到正式版本,在开源世界,有时这样的解决方案,只要许可允许这样做。

If it doesn't help, then Byte Code manipulation is the only way to fix as @PowerStat already mentioned. 如果它没有帮助,那么Byte Code操作是已经提到的@PowerStat修复的唯一方法。 this I believe, Java Agent, class loading patching, AspectJ, and so forth. 我相信,Java代理,类加载修补,AspectJ等等。 Hopefully you won't get there only because of this issue :) 希望你不会因为这个问题而到达那里:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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