以编程方式使用java源文件和类文件

时间:2013-01-14 17:02:33

标签: java compilation system-console

我将把这个问题分成两个问题尽可能简洁。前段时间我开始制作一个用于教育目的的文本编辑器,并且已经在这里和那里添加它。一路走来,我决定要编译并运行java程序。我使用JavaCompiler类进行编译,并使用简单的exec()方法来执行命令以在控制台中运行程序。源代码变得混乱,可能因为它是用无组织的随机代码块编写的,所以我最近决定重写它。在重写程序时,我在文本区域下面添加了一个控制台窗口,以显示编译器的控制台输出以及运行时抛出的异常等。

在编写代码以显示JavaCompiler的输出或通过BufferedInputStream显示控制台输出时,我意识到我正在做这两件事,我一直认为它们的方式非常不同。我的第一个问题主要是询问你的意见,我不知道Java中的类会像简单的IDE一样运行java程序,因此执行控制台命令是我知道这样做的唯一方法,同样可能是完成使用javac命令编译代码,我很好奇使用JavaCompiler类是否有任何好处?

最后,我一直在为这件事添加一些简洁的功能。因为我正在编译和运行java程序,所以我希望能够跟踪和组织java项目。我希望能够告诉任何给定文件属于哪个项目,以及能够告诉项目中的包和目录之间的区别,以便我可以查看包文件夹内部来编译源文件并执行正确的运行命令从二进制文件夹运行它,Java是否提供了这样做的方法,或者我将不得不做一些事情,比如创建从文件继承但是有其他字段来确定文件类型(目录或包)的自定义类?或者有更好的方法来实现它吗?

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

你有两个问题。让我们从元数据开始。了解如何跟踪IDE的项目元数据的最佳方法是查看已经建立的项目是如何尝试的。

Eclipse和Netbeans都使用在项目根目录内创建的项目文件夹来保存元数据(Eclipse中为.settings,Netbeans中为.nbproject)。元数据(如源文件夹,编译器目标目录,源级别等)保存在元数据文件中,主要是XML。

您可能希望遵循类似的内容,然后考虑添加常见的项目原型,例如/src/classes/src/main/java/target。这导致了问题的第二部分,即编译。

Netbeans本身不直接使用编译器。 Eclipse确实如此,但这是因为Eclipse有自己的内部编译器实现,以提供默认编译器中不可用的额外警告和配置。对于您的IDE,我将了解Netbeans如何管理其项目并编译它们。 Netbeans使用Ant和内部javac文件,而不是调用build.xml。如果您不熟悉Ant,它只是一个工具,允许您在XML中设置由Ant解释和运行的任务。例如,您可以使用Ant来编译Java源代码,生成文档和创建分发JAR。它是一个非常强大的工具,允许您将整个构建过程自动化为一种脚本。

你可以遵循同样的想法。 IDE中的新项目将具有默认的build.xml文件,该文件将使用一些默认的Ant目标构建其项目。您也可以从build.xml访问属性文件,这样您就可以在属性文件中存储有关源目录的信息,以及要在构建脚本中使用的任何其他可自定义信息,并在构建中导入它们。脚本。这是一个示例设置。

文件结构:

| Project root/
|   .myideproject/
|     build.xml
|     project.properties
|     ui.properties
|   classes/
|     <compiled .class files>
|   doc/
|     <generated javadoc files>
|   lib/
|     <3rd-party .jar files needed for compilation>
|   src/
|     <user .java files>

build.xml文件是IDE用来编译的东西。您可以要求用户安装Ant(快速且无痛的过程),也可以像Netbeans一样捆绑它(更适合您)。在任何一种情况下,如果您将build.xml嵌套在.myideproject目录中,您的构建文件将如下所示:

<project name="<User's project name>" default="compile" basedir="..">
    <!-- ... -->
</project>

注意事项:

  1. “用户的项目名称”由用户在创建项目时提供。
  2. “default”属性将指向构建文件中的目标。
  3. “basedir”属性将重新定义构建过程,使其指向项目根目录中的目录,而不是.myideproject
  4. 接下来,您需要导入project.properties文件(ui.properties用于保存与UI相关的数据,而不是用于构建脚本,project.properties包含构建脚本需要的所有内容运行正常)。这是将属性导入Ant项目的方法:

    <project ... >
        <import file=".myideproject/project.properties" />
        <!-- ... -->
    </project>
    

    这将使用指令project.properties使${propname}中的所有属性可用。现在,srcclassesproject.properties文件中的可配置目录,我们可以在compile目标中使用它们,如下所示:

    <target name="compile">
        <javac srcdir="${src}"
            destdir="${target}"
            classpath="${classpath}"
            source="${src.jdk}"
            target="${target.jdk}"
            debug="on"
            debugLevel="lines,vars,source" />
    </target>
    

    对于上述目标,属性文件可能如下所示:

    # delimits source directories containing .java files using ':'
    src=src1:src2
    # only 1 directory, it's where the .class files go
    target=classes
    # ':'-delimited list of jars or globs which are needed for compilation
    classpath=lib/*
    # Determines the -source value on the javac process
    src.jdk=1.6
    # Determines the -target value on the javac process
    target.jdk=1.6
    

    这些评论只是为了清楚起见。此属性文件将使用用户输入从IDE的UI构建,因此,如果他们添加或删除源文件夹,则属性文件中的src值会自动更改,然后他们可以重建该过程。

    这应该足以让你入门。有些事情需要考虑:

    • 您将需要一个run目标,该目标使用java任务以及IDE设置的属性来告诉它使用哪个类作为主方法。
    • 您可能还想考虑对Maven项目的支持,这有助于用户自动解决依赖关系。这对你来说会更有用,你应该等到你完成Ant支持
    • 您需要将标准输出/错误/输入从Ant进程重定向到用户可以与之交互的内容。您不必支持标准输入,但至少应支持标准输出/错误

    根据您的评论的最后评论:您将要使用JTree扩展DefaultMutableTreeNode的自定义节点类来创建视图,但它不必是视图文件结构只是一个项目的视图,所以也许它可能是这样的:

    + Project 1 Name
    | + Source Folder 1
    |     <.java files>
    | + Source Folder 2
    |     <.java files>
    | + Source Folder 3
    |     <.java files>
    + Project 2 Name
    | + Source Folder 1
    |     <.java files>
    | + Source Folder 2
    |     <.java files>
    | + Source Folder 3
    |     <.java files>
    

    结构可以基于文件系统,但只显示用户需要的信息,例如他的源目录。你可以从那里扩展这个想法。

    祝你好运,听起来像一个有趣的项目。希望我的建议有所帮助,可以帮助你。如果有任何需要澄清,请告诉我。