当前页面: 开发资料首页 → Netbeans 专题 → 高级自由形式项目配置
摘要: 高级自由形式项目配置 反馈 对于使用 Ant 脚本构建和运行应用程序的 Java 开发人员,NetBeans IDE 中的自由形式项目为他们提供了一个功能非常强大的工具。 如果您愿意使用 Ant,则可...
对于使用 Ant 脚本构建和运行应用程序的 Java 开发人员,NetBeans IDE 中的自由形式项目为他们提供了一个功能非常强大的工具。
如果您愿意使用 Ant,则可以编辑 Ant 脚本和 IDE 项目配置文件,以实现 NetBeans IDE 和构建过程之间更紧密地集成。
本文假设您已经完成自由形式项目设置的前几步。参见本指南关于设置自由形式标准项目的内容和本指南关于设置自由形式 web 项目的内容。
本文包括以下信息:
您也可以下载 Sample Ant Targets。
可以使用三种方法将 IDE 命令映射到 Ant 脚本中的目标:
Project Properties 对话框是在 IDE 中配置自由形式项目的主要工具。若要打开对话框,请在 Projects 窗口中右键单击自由形式项目节点(图标),并选择 Properties。在 Build and Run 页中,可以设置一些 Ant 目标,使之在使用以下命令时运行:
注意:如果 Ant 脚本使用 import 语句导入另一个 Ant 脚本的目标,则这些目标不会显示在 Project Properties 对话框的下拉列表中。若要将命令映射到这些目标,必须将这些目标的名称键入下拉列表中。
在 Custom Menu Items 列表中,也可以将 Ant 脚本中任何目标的快捷键添加到项目节点的上下文菜单中。
每个 IDE 项目都有一个 project.xml 文件,包含了有关项目内容的重要元数据、项目 Ant 脚本的位置、为 IDE 命令运行的目标和其他信息。如果要在 IDE 中映射适用于当前所选文件的命令,或者要将命令映射到独立 Ant 脚本中的目标,则必须手动编辑 project.xml 文件。在 Files 窗口中,展开项目的根文件夹和 nbproject 文件夹,然后双击 project.xml。
ide-actions 元素包含 IDE 命令的映射。可以输入任意标准 IDE 操作的 action 元素,然后定义脚本以及要将命令映射到的目标。
可以使用的标准 IDE 操作如下:
例如,下面将 Debug Project 映射到项目 Ant 脚本的 debug-nb 目标:
<action name="debug"> <target>debug-nb</target> </action>
映射 NetBeans IDE 命令的 Ant 目标所在的 Ant 脚本不必与构建和运行项目时使用的 Ant 脚本相同。这对于不能修改其 Ant 脚本的用户是很有用的。下面将 Debug Project 映射到独立 Ant 脚本中的 debug-nb 目标:
<action name="debug"> <script>path/to/my/nbtargets.xml</script> <target>debug-nb</target> </action>
注意: <script> 必须位于 <target> 之前。
也可以配置一个命令运行多个目标。这些目标按照它们在操作中出现的顺序运行。例如,Clean and Build Project 命令的映射如下所示:
<action name="rebuild"> <target>clean</target> <target>compile</target> </action>
project.xml 还有一个 context-menu 元素,用于控制项目节点上下文菜单的内容。如果手动添加项目中运行的操作,请确保也在 <context-menu> 中注册了操作名称。如果使用 Project Properties 对话框来配置标准项目命令,IDE 会自动将命令添加到项目的上下文菜单中。
每个 IDE 项目都有一个 project.xml 文件,其中包括有关项目的重要信息,例如:
可以在 project.xml 文件内定义属性,或将属性存储在单独的 .properties 文件中。project.xml 文件与 Ant 脚本中的信息保持同步的一种方法是,将 Ant 脚本所使用的来自同一个 .properties 文件中的属性导入 project.xml。
但是,请注意在默认情况下,project.xml 中的所有文件路径是项目文件夹的相对路径。如果 Ant 脚本不在项目文件夹中,则 classdir 属性(指向 build/classes/)不会指向 Ant 脚本和 project.xml 文件所在的同一个目录。(项目文件夹包含 nbproject 文件夹,但它不是 nbproject 文件夹本身。默认情况下,新建自由形式的项目向导会将 Ant 脚本的父文件夹做为项目文件夹)
通过为重要路径(如 project.dir)定义属性,然后将这些属性用于更确切的位置(例如 classdir=${project.dir}/build/classes)来解决上述问题。
若要在 project.xml 中创建并导入属性,请在 name 元素和 folders 元素之间输入下面内容:
<properties> <property name="name">value</property> <property-file>my-properties-file.properties</property-file> <property-file>another-properties-file.properties</property-file> </properties>
请注意,该语法与 Ant 脚本中使用的语法是不同的。还请注意,虽然可以按任意顺序添加属性,但这些属性只能引用先前在 project.xml 中定义的其他属性。属性文件路径本身也可以使用属性替代。
IDE 与自由形式 project.xml 文件的 XML 架构捆绑在一起,在每次进行编辑和保存时,IDE 都会自动验证自由形式 project.xml 文件。您可以在以下位置查看自由形式 project.xml 文件的 XML 架构:
与编译、运行命令类似,调试命令依赖于各种信息,如源位置,已编译类和其他项在类路径上的位置、项目主类的名称。
在自由形式项目中,IDE 不“知道”上述信息。在 IDE 中运行命令(例如 Build Project)时,IDE 只调用构建脚本中的目标,让脚本来处理命令。因此,要使调试正常运行,您还必须具有一个调试的构建脚本目标。IDE 提供一些自定义 Ant 任务与调试器一起使用,也可以生成基本调试目标,该目标尝试提供基于脚本中的其他目标的重要细节。
若要在自由形式项目中设置调试,您需要进行以下操作:
如果没有为项目编写 debug 目标,则在首次尝试调试项目时,IDE 会为您生成一个基本目标。然后可以查看该目标,并按照项目特定需要对目标进行自定义。
注意:在生成调试目标之前,最好首先确保已将目标映射到 Run Project 命令。IDE 生成调试目标时,会在已映射到 Run Project 命令的目标中到查找相关信息,以确定运行类路径和项目主类等。如果已将某个目标映射到 Run Project 命令,最好的选择是不需要进一步自定义就可以使用生成的调试目标。
创建自由形式项目的调试目标的步骤:
在名为 ide-targets.xml 的文件中创建了一个名为 debug-nb 的目标。所生成的 ide-targets.xml 文件是一个用于导入主 build.xml 文件的构建脚本,因此调试对象可以使用由主构建脚本设置或引用的目标或属性。
另外,还会在 project.xml 文件中创建该目标的映射,这样只要您选择 IDE 中的 Debug Project 命令,就会调用该目标。如果您从头编写目标,则您还需要自己创建该映射。请参见手动将目标映射到菜单项。
创建目标后,您就可以开始调试了。开始调试的步骤:
会运行目标,并开始执行程序。运行目标的进度会显示在 Output 窗口中,编辑器的状态会显示在 Output 窗口底部的状态栏中。
生成的 Ant 目标执行以下操作:
注意:也可以在 java 任务中添加任何其他 JVM 参数或程序参数。
所生成的调试目标(IDE 可以推测到其运行时类路径)如下所示(其中 斜体 项的具有特定于项目的值):
<?xml version="1.0" encoding="UTF-8"?> <project basedir=".." name="YourProjectName"> <import file="../build.xml"/> <!-- TODO: edit the following target according to your needs --> <!-- (more info: http://www.netbeans.org/kb/articles/41/freeform-config.html#debugj2se) --> <target name="debug-nb"> <nbjpdastart addressproperty="jpda.address" name="NameOfProject" transport="dt_socket"> <classpath path="ClasspathSpecifiedInYourRunTarget"/> </nbjpdastart> <java classname="MainClassSpecifiedInRunTarget" classpath="ClasspathSpecifiedInYourRunTarget" fork="true"> <jvmarg value="-Xdebug"/> <jvmarg value="-Xnoagent"/> <jvmarg value="-Djava.compiler=none"/> <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/> </java> </target> </project>
如果尚未映射运行目标或者 IDE 无法确定项目的类路径或主类,则生成的调试目标会包含“TODO”占位符用于填写这些值,如下面例子所示。
<?xml version="1.0" encoding="UTF-8"?> <project basedir=".." name="YourProjectName"> <!-- TODO: edit the following target according to your needs --> <!-- (more info: http://www.netbeans.org/kb/articles/41/freeform-config.html#debugj2se) --> <target name="debug-nb"> <path id="cp"> <!-- TODO configure the runtime classpath for your project here: --> </path> <nbjpdastart addressproperty="jpda.address" name="NameOfProject" transport="dt_socket"> <classpath refid="cp"/> </nbjpdastart> <!-- TODO configure the main class for your project here: --> <java classname="some.main.Class" fork="true"> <classpath refid="cp"/> <jvmarg value="-Xdebug"/> <jvmarg value="-Xnoagent"/> <jvmarg value="-Djava.compiler=none"/> <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/> </java> </target> </project>
若要指定运行时类路径,请在 path 元素中插入 pathelement 元素,并将这些元素指向包含类路径中各项的目录。例如,可以使用 pathelement 的 location 属性,以指定类路径项相对于项目目录的位置。项目目录通常是包含项目的 build.xml 文件的目录。下面是一个示例:
<path id="cp"> <pathelement location="libs"> <pathelement location="build"> </path>
使用 IDE 生成目标后,IDE 会自动提供该目标与 IDE 命令的菜单项之间的映射。但是,如果您手动创建了目标,您还需要手动创建映射。
将 Debug Project 命令映射到外部 Ant 脚本中目标的步骤:
<action name="debug"> <script>path_to_Ant_script</script> <target>target_name</target> </action>
<ide-action name="debug"/>
IDE 将 Debug Project 操作映射到项目 Ant 脚本中指定的目标。
现在,我们看一个将调试器连接到 web 应用程序的目标。首先,选择 Run > Debug Main Project (F5)。如果未将目标映射到 Debug 命令,会提示您让 IDE 在 nbproject/ide-targets.xml 文件中生成特定于 IDE 的调试目标。单击 Generate,会生成 debug-nb 目标,及支持调试目标的 -load-props、-check-props、-init 和 debug-display-browser 目标。这些目标显示在 Source Editor 中,如下所示:
(注意: 这些目标不是在 IDE 中生成的。因此,您需要更改所生成的代码,如下所示。)
<target name="-load-props"> <property file="nbproject/project.properties"/> </target> <target name="-check-props"> <fail unless="session.name"/> <fail unless="jpda.host"/> <fail unless="jpda.address"/> <fail unless="jpda.transport"/> <fail unless="web.docbase.dir"/> <fail unless="debug.sourcepath"/> <fail unless="client.url"/> </target> <target depends="-load-props, -check-props" name="-init"/> <target depends="-init" name="debug-nb" description="Debug Project"> <nbjpdaconnect address="${jpda.address}" host="${jpda.host}" name="${session.name}" transport="${jpda.transport}"> <sourcepath> <path path="${debug.sourcepath}"/> </sourcepath> </nbjpdaconnect> <antcall target="debug-display-browser"/> </target> <target name="debug-display-browser"> <nbbrowse url="${client.url}"/> </target>
jpda.session.name=MyProject jpda.host=localhost # Sun Java System Application Server using shared memory (on Windows) # jpda.address=localhost4848 # jpda.transport=dt_shmem # Sun Java System Application Server using a socket # jpda.address=9009 # jpda.transport=dt_socket # Tomcat using shared memory (on Windows) jpda.address=tomcat_shared_memory_id jpda.transport=dt_shmem # Tomcat using a socket #jpda.address=11555 #jpda.transport=dt_socket src.folders=src web.docbase.dir=web # you can change this property to a list of your source folders debug.sourcepath=${src.folders}:${web.docbase.dir} # Client URL for Tomcat client.url=http://localhost:8084/MyProject # Client URL for Sun Java System Application Server # client.url=http://localhost:8080
属性 | 值 | 说明 |
---|---|---|
jpda.session.name | 调试项目时,Sessions 窗中指定的显示名称。 | |
jpda.host | 要进行调试的应用程序连接到调试器时所使用的主机,例如 localhost。 | |
jpda.address | 在默认情况下,对于绑定的 Tomcat Web Server,套接字连接为 11555,共享内存连接为 tomcat_shared_memory_id。 | 若要设置不同的地址,在 Runtime 窗口中右键单击 Tomcat 节点,并选择 Properties。在 Properties 表中,更改 Debugging Port 属性(对于套接字连接)或 Name 属性(对于共享内存连接)。然后关闭 Properties 表。如果已启动 Tomcat Web Server,请立即停止并重新启动它。 |
jpda.transport | dt_socket(用于套接字连接)或 shmem(用于共享内存连接) | 若要设置不同的传输,在 Runtime 窗口中右键单击 Tomcat 节点,并选择 Properties。在 Properties 表中,更改 Debugging Type。然后关闭 Properties 表。如果已启动 Tomcat Web Server,请立即停止并重新启动它。 |
web.docbase.dir src.folders |
web 根 (web.docbase.dir) 和 Java 源文件 (src.folders) 的位置。 | 通过使用“:”分隔符,可以将多个源根包括在源路经中。请注意,在 Project Properties 对话框的 Java Sources 面板中,必须将 Java 源文件夹指定为 Source Package Folders。(右键单击项目,选择 Properties,然后单击 Project Properties 对话框中的 Java Sources。) |
client.url | 应该在 IDE 默认浏览器中打开的 URL,例如 http://localhost:8084/MyProject。 |
有关示例值,请参见把现有 Web 应用程序导入到 NetBeans IDE 5.0 中文档的“调试应用程序”部分。
请注意,debug-nb 目标将自动映射到 Debug Project 命令。但是,如果将该目标保留在不同的 Ant 脚本中,则需打开项目的 project.xml 文件,并更改 ide-actions 部分中的 script 元素:
<action name="debug"> <script>path-to-my-debug-target.xml</script> <target>debug-nb</target> </action>
在可以使用调试目标前,您必须部署应用程序。因此,请启动服务器并运行应用程序部署命令。请注意,在每次会话中,首次运行应用程序时,Tomcat Web Server 会要求您输入用户名和密码。唯一可接受的用户名和密码是具有“管理员”角色用户所使用的用户名和密码。这在 Tomcat Web Server 基目录的 conf/tomcat-users.xml 文件中进行了定义。若要确定该目录的位置,在 Runtime 窗口中右键单击 Tomcat Web Server 实例节点,并选择 Properties。在 Properties 对话框中,请将 Base Directory 属性指向 Tomcat Web Server 的基目录。
部署应用程序后,请停止服务器并以调试模式重新启动服务器。完成上述操作的方式取决于服务器:
catalina jpda start
在调试模式下启动服务器后,选择 Run > Debug Main Project (F5)。部署应用程序并连接到调试器。调试器在第一个断点停止,然后可以进入 (F7) 或越过 (F8) 代码。
即使 IDE 已经尽最大努力为您生成完整的调试目标,但对于为特定环境定制的属性,您还是应该经常分析并微调调试进程。当您在 NetBeans IDE 中使用 Ant 调试目标遇到困难时,请检查下列问题。
检查是否已部署 web 应用程序:
检查代理设置是否正确。根据代理类型执行以下操作:
检查是否在调试模式下启动服务器:
检查在 debug.properties 中设置的 jpda.address 是否与服务器设置匹配:
检查在 debug.properties 中设置的 jpda.transport 是否与服务器设置匹配:
如果无法逐行调试代码,而只能逐个断点执行,但是 IDE 找不到源代码。这是因为您没有正确指定源代码。
请注意,调用 javac 任务时,用于编译 servlets 的目标必须指定 debug="true"。如果在没有调试信息的情况下编译 servlet,则调试器不会在断点处停止。
请注意,如果在指定上下文路径之前,设置了断点,则必须在指定上下文路径后移除并重新设置断点。也就是说,必须先设置上下文路径。
还要确保在 debug.properties 文件和 debug-nb 目标中正确指定源。请注意,如果 nbproject 文件夹没有位于源文件夹所在的文件夹中,则应为 src.folder 和 web.docbase.folders 属性设置以下属性:
<?xml version="1.0" encoding="UTF-8"?> <project basedir=".." name="MyProjectName"> <!-- TODO: edit the following target according to your needs --> <!-- (more info: http://www.netbeans.org/kb/41/freeform-config.html#compilesingle) --> <target name="compile-selected-files-in-src"> <fail unless="files">Must set property 'files'</fail> <!-- TODO decide on and define some value for ${build.classes.dir} --> <mkdir dir="${build.classes.dir}"/> <javac destdir="${build.classes.dir}" includes="${files}" source="1.5" srcdir="src"/> </target> </project>在所生成的目标中,您需要指定放置一个或多个编译的类所在的目录。可以通过指定所生成目标中的 build.classes.dir 属性值来实现。例如,可以将下面一行添加到 <target name="compile-selected-files-in-src"> 条目上面的一行中:
<property name="build.classes.dir" value="build"/>
也可以替换提供的 build.classes.dir 值,或完全重写目标。
includes 参数的值是生成的 files 属性的值。IDE 使用该属性来存储当前所选择的一个或多个文件的名称。
注意:可以配置多个 compile.single 操作以重载 F9 快捷键和具有不同功能的菜单命令(取决于所选择的文件)。例如,可以为 JUnit 测试类设置单独的 compile-selected-files 目标,然后将 compile.single 映射到 JUnit 测试类中所有源的该目标上。也可以将模式更改为 \.xml$,并将 F9 映射到所有 XML 文件的 Validate XML 目标。
IDE 没有为 Run File、Debug File、Test File 和 Debug Test for File 命令生成目标,但是您可以创建自己的目标并将他们映射到下列预定义操作:
每个操作都包含一个 context 元素,该元素可获取对当前所选文件的引用,并将其存储在所选择的属性中。可以在 Ant 目标中使用该属性,以指定要处理的文件。
我们来演示一下在运行类时,是如何使用此目标的。运行项目的典型目标如下所示:
<target name="run2" depends="..."> <java fork="true" classname="MyMainClass" classpath="MyRunClasspath" /> </target>
该目标运行由 classname 指定的文件。若要在 IDE 中运行当前所选文件,您需要将上述目标修改如下:
<target name="run-selected-file" depends="compile" description="Run Single File"> <fail unless="runclass">Must set property 'classname'</fail> <java classname="${runclass}"> <classpath refid="run.classpath"/> </java> </target>
一旦有一个 Ant 目标用于运行所选文件,必须在 IDE 中获取对该文件的引用,并将其存储在某个属性中。例如,上述 run-selected-file 目标在 runclass 属性中查找当前所选文件。
将该引用存储在将构建目标 (run-selected-file) 映射到 IDE 操作所在的相同位置中。首先,我们来看一下如何实现上述操作,然后再进行详细讲解:
<action name="run.single"> <target>run-single</target> <context> <property>runclass</property> <folder>${src.dir}</folder> <pattern>\.java$</pattern> <format>java-name</format> <arity> <one-file-only/> </arity> </context> </action>
runclass 属性是一个新定义的属性,用来保存要运行且被 java 任务引用的文件。
现在,我们看一下它是如何运行的。
<action name="run.single"> <target>run-selected-file</target>
<context> <property>runclass</property>
,
该过程与编写目标以调试并运行单个文件的过程基本相同。debug-selected-files 目标应该如下所示:
<target name="debug-selected-files" depends="compile" if="netbeans.home" description="Debug a Single File"> <fail unless="classname">Must set property 'classname'</fail> <nbjpdastart name="${classname}" addressproperty="jpda.address" transport="dt_socket"> <classpath refid="run.classpath"/> <!-- Optional - If source roots are properly declared in project, should work without setting source path. <sourcepath refid="debug.sourcepath"/> --> </nbjpdastart> <java classname="${classname}" fork="true"> <jvmarg value="-Xdebug"/> <jvmarg value="-Xnoagent"/> <jvmarg value="-Djava.compiler=none"/> <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/> <classpath refid="run.classpath"/> </java> </target>
然后,将 debug-selected-files 目标映射到 debug.single 操作:
<action name="debug.single"> <target>debug-selected-files</target> <context> <property>classname</property> <folder>${src.dir}</folder> <pattern>\.java$</pattern> <format>java-name</format> <arity> <one-file-only/> </arity> </context> </action>
Apply Code Changes 命令允许您在调试会话期间对代码进行更改,并继续调试已更改的代码,而无需重新启动应用程序。IDE 包含一个 nbjpdareload 任务,用于编写 Apply Code Changes 命令的目标。
fix 命令的典型目标如下所示:
<target name="debug-fix"> <javac srcdir="${src.dir}" destdir="${classes.dir}" debug="true" > <classpath refid="javac.classpath"/> <include name="${fix.file}.java"/> </javac> <nbjpdareload> <fileset dir="${classes.dir}"> <include name="${fix.file}.class"/> </fileset> </nbjpdareload> </target>
若要将该目标与 Apply Code Changes 命令(与 IDE 先前版本中的 Fix 命令一样)相关联,请在 project.xml 的 <ide-actions> 中定义下面操作:
<action name="debug.fix"> <target>debug-fix</target> <context> <property>fix.file</property> <folder>${src.dir}</folder> <pattern>\.java$</pattern> <format>relative-path-noext</format> <arity> <one-file-only/> </arity> </context> </action>