如何修改编译器优化选项选项以生成行号属性

Java编译时生成调试信息选项详解(javac -g)_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Java编译时生成调试信息选项详解(javac -g)
来源:Linux社区&
作者:daimojingdeyu
先说一下为什么写这一篇小文章,最近不少同事是在问一个问题,为什么Ant编译出的代码在日志里的出错异常栈看不到行号信息,每次如果在定位问题,都需要用eclipse重新将相应的jar包编译一下,再放到问题环境上重现一下,这样再看日志才可以。而且使用ant生成的包就算是远程调试也不可用,断点总是打不上。&
一般的开发都会有一套持续集成的环境,用作每日构建,用ant或是其他工具,开发人员一般用Eclipse或其他的IDE做开发,所以经常会遇见上面的问题。&
ant的javac任务里有对debug信息输出的设置,不过默认是不输出。&
javac中设置调试信息级别的选项为-g,其详细含义如下,英文太简单,偶会详细介绍一下:&
Generate all debugging information, including local variables. By default, only line number and source file information is generated.
在Class文件中生成所有调试信息。也就是将会包含下面介绍的3类调试信息的所有。&&
Do not generate any debugging information.
Class文件中不包含任何调试信息,这个是Ant在编译时默认使用的。&&
-g:{keyword list}
Generate only some kinds of debugging information, specified by a comma separated list of keywords. Valid keywords are:
&& & & & &source
Source file debugging information
Class文件中固定长度的SourceFile属性,编译时如果选择了生成此属性,则会将它写到Class文件中。它用来提供产生Class文件的源文件名称。
如果不生成此属性,那么在调试时就会提示“Source not found.”。
有图有真像,我们用Eclipse来演示一下此调试开关的作用,帮助大家理解。
先设置一下eclipse编译时的选项,关闭Source file属性开关,编译选项的修改只针对此测试用的工程,所以在我们测试的工程右键-&properties,在弹出的对话框中,按下图进行选择:
图1(给这个图命个名,后面还会用到)
上图中,1处表示单独调整本工程的编译选项,2处的最后一行则是是否生成Source file调试信息的开关,这里我们按上图去选中,则生成Class文件中不会有源文件的名称。
下一步,在Eclipse对应的工程中建立一个简单的Main.java用于测试,可以看出在Main.java文件中,我们还有另一个类Test,对于Test类来说,如果在生成Test.class文件没有Source file属性,那调试器就无法知道Test.class实际是对应的源文件是Main.java,那么我们把断点打在Test类的sayHello方法的第一行,调试时会发生什么?
public&class&Main&{ &&
&&&&public&static&void&main(String[]&args)&{ &&
&&&&&&&&Test&t&=&new&Test(); &&
&&&&&&&&t.sayHello(); &&
class&Test &&
&&&&public&Test()&{ &&
&&&&&&&& &&
&&&&public&void&sayHello() &&
&&&&&&&&&SPAN&style="COLOR:&#ff0000"&int&a&=&10;&&&
&&&&&&&&int&b&=&a++; &&
&&&&&&&&System.out.println("b:"&+&b); &&
&&&&&&&&String&hello&=&"Test&say"; &&
&&&&&&&&hello&+=&"&hello"; &&
&&&&&&&&System.out.println(hello); &&
}&&public class Main {
public static void main(String[] args) {
Test t = new Test();
t.sayHello();
class Test
public Test() {
public void sayHello()
int a = 10; // 断点将打在此行
int b = a++;
System.out.println("b:" + b);
String hello = "Test say";
hello += " hello";
System.out.println(hello);
好了,我们在Eclipse中启动调试Main.java,你将会得到下图中的信息:
是的,找不到源文件。
现在你应该已经理解这个调试选项的含义了。
&& & & & &lines
Line number debugging information
将源文件中的行号信息写到Class文件中,此属性用于在Class文件中生成方法字节码流偏移量和源代码行号之间的映射关系。就像我们引子中所看到的,打印出的异常栈中看不到行号,就是因为生成Class中没有此属性导致,而远程调试时打不上断点也是这个原因。
同样的,我们在Eclipse中测试此调试选项的含义,其设置位置跟Source file属性在同一个界面,也在我们图1中设置,图1位置2的第2行,就是此选项,去选中此项,其他选项均选中,重新编译。还是用上面的Main.java来调试,看一下,会出现什么。
是的,出错了,断点无法插入成功,提示信息也很明确,让我们修改编译选项以便生成调试信息。
&& & & & &
&& & & & &vars
Local variable debugging information
Local variable属性建立了方法的栈帧中局部变量部分内容与源代码中局部变量名称和描述符之间的映射关系。简单一点说,如果没有此属性的信息,那我们在调试时将无法看到变量值。
我们还是在Eclipse中去掉此编译选项,不要我讲,你应该已经知道在哪里了,还是图1中的位置2,第一行就是此属性的开关,同样去选而打开其他编译开关,重新编译。再来调试一下我们的Main.java,想通过“Watch”,“Inspect”查看变量b的值,或是hello的值,你将会得到如下信息:
“b cannot be resolved”或是“hello cannot be resolved”。
是呀无法被解析,因为无法找到栈帧中的变量与源码中变量名之间的对应关系,无法将此运行时的信息和我们代码关联引来。
以上javac选项英文描述出自:,本文只关注调试信息相关选项,其他可自行参考。
OK,算是介绍完了,相信大家对这几个参数的含义应该也理解了。
另外在最后想说一下:Eclipse编译使用编译器并不是jdk自带的javac,而是Eclipse JDT自己的编译器。虽然本文的演示是用的Eclipse,但对于javac生成类文件时的调试信息选项的含义和用法也不一样的,Eclipse的JDT编译器和javac是兼容的。
如果想了解Eclipes的JDT编译器和javac编译器的不同可以参考以下文档:
这里介绍了一个小例子,说明这两个编译器间的差别。
这个是Eclipse的帮助里的东东,介绍Eclipse的JDT编译器的使用,(当然你可以通过本地Eclipse的帮助查看)
这里面的编译方法偶在本地试过了,很好用,你也可以试式用JDT的编译器编译个文件玩一下。Eclipse 3.5的示例用法如下:
D:\Program Files\eclipse\plugins&java -jar org.eclipse.jdt.core_3.5.2.v_981_R35x.jar -d F:\Study\eclipsepro\Study\src\eclipse -g F:\Study\eclipsepro\Study\src\*.java
相关资讯 & & &
& (11/30/:52)
& (07/08/:10)
& (04/22/:27)
& (11/21/:48)
& (05/21/:16)
& (07/09/:16)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款ant javac标签的debug属性 - 老天忘了给我翅膀,于是我用梦想飞翔 - ITeye技术网站
博客分类:
ant里javac的属性
debug: 当值未为true时产生调试信息
当使用ant脚本编译java文件时,需要注意,设置javac命令的属性debug属性为true。
如果出现Unknown Source这样的问题,估计是编译的时候debug设置的false。
Unknown Source,顾名思义,就是未知的源文件。因为我们最终解释运行的是class文件,所以出现这个问题的原因很简单,就是class文件中没有源文件的相关调试信息。那为什么class文件会没有调试信息呢?答案更简单,当然是我们在用javac命令进行编译的时候没有指定调试信息呗。因为现在很多人都习惯用eclipse等一些现成的ide进行编写代码,所以很少人熟悉jdk自己的javac,java,jdb等一些命令的详细参数(jdk的一些命令和eclipse自带的一些命令可能不同)。哈哈,不过如果你经常在linux下玩java的话,命令肯定会非常熟悉。那么让我们看看javac的一些重要参数:
&&& -g-Generate all debugging information, including local variables. By default, only line number and source file information is generated.在class文件中生成所有调试信息,包括局部变量的信息。默认的话,只写入源码的行号和源文件信息。
&&& -g:none-Do not generate any debugging information.不生成任何调试信息。
&&& -g:(lines,vars,source)-只生成部分调试信息(源码行号,变量,源文件信息)。那我们在分别介绍下lines,vars,source的含义。
&&&&&&&& lines:将源文件中的行号信息写到Class文件中,此属性用于在Class文件中生成方法字节码流偏移量和源代码行号之间的映射关系。如果我们不指定此属性的话,我们将在堆栈异常信息中看不到打印的行号。
&&&&&&&& vars:Local variable属性建立了方法的栈帧中局部变量部分内容与源代码中局部变量名称和描述符之间的映射关系。有了这个属性,调试时,我们才可以看到变量的值。
&&&&&&&& source:编译时指定了这个属性,会把源文件的属性信息如源文件名称写入class文件。
&&&& 说了这么多,初学者可能会迷糊,为什么编译要指定这些调试信息呢?哈哈,如果编译不指定这些调试信息的话,你怎么调试呢?如果你不指定行号信息的话,你在ide中都无法插入断点。这些调试信息在我们调试程序的时候非常重要。不过这些编译选项通常在ide中如eclipse中早已默认了。有的人可能还不相信,打开eclipse,依次打开菜单选项:Window-&Preferences-&Java-&Compiler,可以看到页面的下方有一个Classfile Generation,默认是四个选项都选的。
&&& 那这个Unknown Source到底是编译的时候没有指定哪一项呢?经过测试,我发现是javac编译的时候没有没有指定source选项,必定出Unknown Source这个问题。
浏览: 113638 次
来自: 湖南@深圳
感谢 这个对CellProcessor的介绍很容易理解。
嗯啊,谢了,有用
有用,谢谢

我要回帖

更多关于 hive生成行号 的文章

 

随机推荐