背景资料:
我有这个java框架,用于运行外部脚本.为此,我使用类加载器和系统java编译器的组合来编译.java在我的项目的构建路径中不存在的"脚本"文件.所有这些工作,编译器黑魔法和所有.
外部加载代码的固有复杂性是难以调试.我已经通过使用java运行时的远程调试功能解决了这个问题.
所以,我有一个附加到我的可执行jar的调试配置,它在源查找路径上有外部java脚本的目录.这实际上已经工作了一段时间.实际上,它从来没有正常工作,我只是偶然在我的构建路径上有脚本.令人困惑的是,我可以在脚本中放置断点,并且调试器实际上在那里STOPS(一致的行号,-verbose:class日志记录和所有).但是,了解eclipse如何找到源文件会有所帮助.毕竟,大多数eclipse文档都包含用户手册.
我怀疑的是我不小心复制了某些脚本文件,因此将源查找与不同步的源文件混淆了.事实并非如此,我已经删除了重复的文件,而eclipse仍然无法找到源代码.
我试过的
解决方法
这里唯一的解决方法是将脚本文件添加到项目的构建路径中,这对我来说是不可接受的.
我现在在做什么
我正在慢慢爬过eclipse开源项目库存储库寻找答案.事实证明,Eclipse是一个非常大的项目.
题
任何人都可以提供Eclipse源查找工作原理的准确算法表示吗?
知道了这一点,我可能想出一种方法来强制Eclipse调试器使用反射来使用正确的路径.据我所知,没有技术限制阻止动态编译的代码被调试.我知道这是因为我的断点正在暂停我的线程,因为我期望它们,源代码似乎不想加载:(
相关研究:
似乎这可能与如何使用null CodeSource位置定义类相关联,但显然在将代码动态编译到内存中时要做的就是给出null arg ... 问题仍然是如何/为什么这对eclipse的调试器很重要.
更新4/22 3:30:
所以我追求CodeSource上面链接的解决方案.现在,我看到我的类正在使用-verbose:class交换机从正确的文件路径位置加载,但源查找仍然失败.断点仍然被正确抓住,但我会看到熟悉的Source not found红色字体.
更新5/6 3:15:
我追求javap安德鲁的答案中讨论的解决方案.事实证明,我的.class字节码中的源文件属性与我的源查找路径上存在的文件完全匹配.这让我感到困惑,因为这暗示了对源查找有影响的文件夹层次结构.但是,我创建了"幻像"包层次结构,表示"真正的"包(在我的.java文件的顶部定义)并将我的源文件移动到那些文件夹,但是当我将这些路径添加到源时,源查找仍然失败我的源查找路径.关于在源查找中使用哪些其他因素的任何其他见解将是巨大的.
我已经毫无疑问地使用final关键字多年来表示在实例/类的生命周期内不应更改的字段.突然这发生在我身上......
所以给出这个例子:
public class TestFinalGC{
private TestFinalGC(){}
private final Object obj = new Object();
public static void main(String []args){
TestFinalGC instance = new TestFinalGC();
// instance Ref -> actual instance ->? obj ref-> actual obj
System.out.println(instance.obj);
instance = null;
//say GC makes sweep here... what happens?
//lets assume theres more code, obj would obviously be eligible for GC on app exit.
}
}
Run Code Online (Sandbox Code Playgroud)
obj会员怎么不泄漏?final字段是否自动WeakReferences,以便如果对父项的强引用为空,它们是否有资格进行垃圾回收?
更新:
因此,我的这个问题建立在"可达性"和强/弱参考密切相关的前提之上.有关于这个可达性混乱的Oracle文档,导致我相信,嵌套引用应该永远是"强可到达".因此,我在所有对象中都取消了嵌套对象引用,但看起来显然不应该是我收到的所有注释的情况.
那么关于"可达性",那么,如果父引用不再可达,那么仅仅是嵌套对象引用不再被视为"可达"吗?
这可能是真的,这个问题的前提是不正确的,但仍然有耐人寻味的信息在这里巩固.
我正在调试eclipse远程调试动态编译加载类时无法加载源代码的原因。我看到的论点-verbose:class是我的动态编译的类文件来自__JVM_DefineClass__. 我认为这意味着它们来自 JVM 堆空间本身,因为我让编译器将编译后的字节输出到“文件管理器”中,该文件管理器将编译后的字节缓存在内存中。
似乎调试时源代码可查看的唯一方法是,如果我在源代码查找路径中指定实际加载的类来自的位置...并且如果我指定该类所在的目录,则似乎不起作用正在编译类。我觉得如果我将编译的字节保存到磁盘,源加载可能会起作用。
那么,什么__JVM_DefineClass__意思呢?我的假设正确吗?
关于负数模的问题,我已经看到很多答案.每个答案都是标准
(a/b)*b + a%b等于a
说明.我可以使用这种方法计算任何模数,并且我理解它必须使用模数函数,如果模数为负,则将b添加到%b的值.
我试图用外行的方式理解这一点.负数的模数是多少?我读到某个地方,你可以手工计算负数的正确模数,一些外行人只是将数字加在一起的方法.这会有所帮助,因为a/b*b + a%b方法有点单调乏味.
为了澄清,正数的模数可以用外行的术语解释为除数后的余数.显然在负数的情况下不是这样,所以你如何正确地"理解"结果呢?
为什么将"this"传递给Thread构造函数是一种不安全的构造技术?如果是那么替代方案是什么?它与测试或调试有关吗?我找到了一些答案,但没有完全理解.
class NewThread implements Runnable {
Thread t;
NewThread(){
t = new Thread(this,"My new Thread");
}
}
Run Code Online (Sandbox Code Playgroud) java ×4
eclipse ×2
c++ ×1
classloader ×1
debugging ×1
external ×1
final ×1
jvm ×1
memory-leaks ×1