我快速浏览了Guava源代码和文档,似乎都没有提到版本.我想知道是否有办法在运行时获得Guava的版本信息.
如果实际上没有这样的东西,则不必通过任何getter访问此版本信息; 如果它藏在某个地方某个地方,当Guava加载时没有得到GC,这就足够了.
这个版本信息是否在运行时可用?
我有一个非常具体的用途.我的工作很大一部分是分析Java堆转储,以识别和修复代码中导致内存使用过高的地方.对于这个任务,我使用fasthat,这是一个经过大量修改的jhat版本,具有对我的工作有用的特殊功能.
其中一个功能是显示容器的内容.我已经为这样的人实现了这个ArrayList,HashMap,ConcurrentHashMap,等(我的需求实现类型的打印机,基于我在我们的堆转储遇到的问题.)目前,我执行番石榴的一个类型的打印机CustomConcurrentHashMap.
由于结构的布局可以在不同版本之间进行更改,因此我的代码会根据正在使用的版本调整其解包行为.例如,在工作中,我们曾经使用JRuby 1.2,但最近切换到JRuby 1.6,因此我为这两个版本都有类型打印机,并根据它在堆转储中找到的版本信息选择版本.
那么,这就是问题第二段的要点:如果版本信息在堆转储中的任何地方,那就是我所需要的.
在任何人问之前:堆转储数据不是"实时",所以你不能简单地打电话toString等.你真的必须走数据结构来提取出来,你真的必须使用实现细节到第n度.;-)
这更像是一种解决方法,但我想如果没有更简单的方法来访问 Guava 版本,您可以这样做:
在大多数 Guava 版本中,添加/删除了类/字段/方法。您可以尝试在堆转储中查找它们,并根据它们的存在来确定 Guava 版本。
就像是:
/**
* A {@link Predicate} that checks whether a class exists in the given {@link HeapDump}
*/
public class ClassExistsPredicate implements Predicate<String> {
private final HeapDump heapDump;
public ClassExistsPredicate(HeapDump heapDump) {
this.heapDump = heapDump;
}
@Override
public boolean apply(String fullyQualifiedClassName) {
// checks whether the given class exists in the heap dump
return true;
}
}
public enum GuavaVersion {
R01,
R02 {
@Override
Set<String> getAddedClasses() {
return ImmutableSet.of("com.google.common.base.Foo");
}
},
R03 {
@Override
Set<String> getAddedClasses() {
return ImmutableSet.of("com.google.common.collect.ForwardingFooIterator");
}
},
R04 {
@Override
Set<String> getAddedClasses() {
return ImmutableSet.of("com.google.common.collect.FooFoo2");
}
};
/**
* @return a {@link Set} of added class names that uniquely identify this version from the preceding one (not
* necessarily <b>all</b> classes!)
*/
Set<String> getAddedClasses() {
return ImmutableSet.of();
}
public static GuavaVersion getGuavaVersionFor(HeapDump heapDump) {
ClassExistsPredicate classExists = new ClassExistsPredicate(heapDump);
for (GuavaVersion version : Lists.reverse(Arrays.asList(GuavaVersion.values()))) {
if (Iterables.all(version.getAddedClasses(), classExists)) {
return version;
}
}
throw new RuntimeException("Unable to determine Guava version...");
}
}
Run Code Online (Sandbox Code Playgroud)
显然,您应该缓存 Guava 版本号,因为计算可能会很慢......可以扩展该方法以考虑添加的方法/字段。
这种方法也适用于其他项目。
| 归档时间: |
|
| 查看次数: |
1429 次 |
| 最近记录: |