以编程方式编译存储在任意子文件夹中的包中的 Java 类

发布于 2024-08-20 15:00:55 字数 838 浏览 6 评论 0原文

我正在寻找用 Java 编译一个应用程序,该应用程序由一定数量的包中的各种数量的 java 类组成。在命令行中,我可以更改为包含根包的文件夹并输入:

javac rootpackage/subpackage/*.java

javac rootpackage/*/*.java

编译根包的所有主子包中的所有 java 类。

不过我希望能够在 Java 应用程序中执行此操作。 (我们的想法是,我们向学生提供一个包含单元测试的应用程序。单元测试需要针对他们的代码运行,然后应用程序创建一个包含源文件的 JAR 文件,这些文件已带有测试结果的“水印”。这工作正常,但我们希望确保测试的类文件是从提交的源文件创建的,因此以编程方式编译 java 源的想法)。

问题在于每个学生都将他们的根包存储在任意位置,而我似乎无法将文件的位置传递给JavaCompiler(javax.tools)。

是否可能,如果可以,有人可以给出一些关于如何正确编译任意放置的根包的提示。

干杯

理查德

更多信息:

学生有一个文件夹结构:

/home/student/work/java/myproject/

其中包含根包。他们启动应用程序(可能存储在这个文件夹中 - 因此没有问题 - 但很可能存储在其他地方),该应用程序要求他们提供包含根包的文件夹。输入后,学生单击创建 JAR 按钮,该按钮会编译包中的文件,对新编译的文件运行测试,然后创建 JAR。

在思考这个问题时,解决方案可能是告诉学生将我们的“创建 JAR”应用程序安装在包含其根包的文件夹中。

I am looking to compile an application in Java, made up of a various number of java classes in a certain number of packages. At the command line, I can change to the folder containing the root package and type:

javac rootpackage/subpackage/*.java

or

javac rootpackage/*/*.java

to compile all the java classes in all the primary subpackages of my rootpackage.

However I would like to be able to do this within a Java application. (The idea is that we provide an application to students which contains unit tests. The unit tests need to be run against their code, the application then creates a JAR file containing their source files which have been 'watermarked' with the test results. All this works ok, but we would like to make sure that the class files tested are created from the source files submitted, hence the idea to compile programmatically the java sources).

The problem comes in that each student stores their root package in an arbitrary position, and I cannot seem to pass the location of the file to JavaCompiler (javax.tools).

Is it possible, and if so, can someone give some hints on how to have an arbitrary placed root package compiled properly.

Cheers

Richard

More Info:

a student has a folder structure:

/home/student/work/java/myproject/

which contains the root package. They launch the application (possibly stored in this folder - and thus no problems- however more than likely stored elsewhere) which asks them for the folder that contains the root package. After entering, the students click a create JAR button, that compiles the files in their packages, runs the tests on the newly compiled files and then creates the JAR.

Whilst thinking through this problem, it is possible that the solution is to tell the students to install our 'create JAR' application in the folder containing their root package.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

榕城若虚 2024-08-27 15:00:56

JavaCompiler.getTask() 的最后一个参数是 Iterable包含要传递给编译器的编译单元。提供的 JavaFileObject 实现之一是 SimpleFileJavaObject (http: //java.sun.com/javase/6/docs/api/javax/tools/SimpleJavaFileObject.html)。这是用 java.net.URI 对象构造的,可以从 File 对象轻松创建该对象。将它们放在一起,执行如下操作:

List<JavaFileObject> javaFiles = new ArrayList<JavaFileObject>();
File javaFile = new File(rootPackageDirFromUser, fileNameInRootDir);
URI javaURI = javaFile.toURI();
javaFiles.add(new SimpleJavaFileObject(javaURI, JavaFileObject.Kind.SOURCE));
JavaCompiler.CompilationTask task =
    ToolProvider.getSystemJavaCompiler().getTask(..., javaFiles);

其中 rootPackageDirFromUser 由用户给出,他告诉您他们存储文件的位置,而 fileNameInRootDir 是该目录中的 java 源文件的名称。如果您事先不知道文件名,则需要迭代 rootPackageDirFromUser 来构造一个列表。

我还没有对此进行测试,但这应该可以让您有个大概的了解。

The last argument to JavaCompiler.getTask() is an Iterable<? extends JavaFileObject> containing the compilation units to pass to the compiler. One of the provided implementations of JavaFileObject is SimpleFileJavaObject (http://java.sun.com/javase/6/docs/api/javax/tools/SimpleJavaFileObject.html). This is constructed with a java.net.URI object, which can be created easily from a File object. Putting it all together, do something like this:

List<JavaFileObject> javaFiles = new ArrayList<JavaFileObject>();
File javaFile = new File(rootPackageDirFromUser, fileNameInRootDir);
URI javaURI = javaFile.toURI();
javaFiles.add(new SimpleJavaFileObject(javaURI, JavaFileObject.Kind.SOURCE));
JavaCompiler.CompilationTask task =
    ToolProvider.getSystemJavaCompiler().getTask(..., javaFiles);

where rootPackageDirFromUser is given by the user, who tells you where they stored the files, and fileNameInRootDir is the name of a java source file in that dir. If you don't know the file names in advance, you'll need to iterate over the rootPackageDirFromUser to construct a list.

I haven't tested this, but that should give you the general idea.

逆光飞翔i 2024-08-27 15:00:55

您能否查看每个 .java 文件的顶部是否有以下行开头:

package com.blah.blah.assignment;

即查找包名称的开头,然后查找您的包中的第一个目录搜索以 com 开头的路径(在本例中),然后将此路径提供给 JavaCompiler 对象,或者我误解了您的问题?

刚刚查看了 javax.tools 包,为什么不为 javaFilemanager 创建一个复合包装器,它包装了一个 ForwardingjavaFileManager,它将对 getFileForInput 或 getJavaFileForInput 等方法的所有请求转发到学生源目录中适当的起始目录(如所决定的)通过对第一个 .java 文件的初步解析来确定其源路径的根)

Could you peek at the top of each .java file for the line beginning:

package com.blah.blah.assignment;

i.e. look for the start of the package name and then look for the first directory in your search path beginning com (in this example), and then give this path to the JavaCompiler object, or have I misunderstood your question?

Having just looked at the javax.tools package, why not create a composite wrapper for the javaFilemanager which wraps a ForwardingjavaFileManager which will forward all requests for the methods such as getFileForInput or getJavaFileForInput down to the appropriate starting directory in the student's source directory (as decided by your preliminary bit of parsing of the first .java file to determine the root of their sourcepath)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文