Java_java动态编译整个项目,解决jar包找不到问题

Java_java动态编译整个项目,解决jar包找不到问题

java动态编译整个项目,解决jar包找不到问题
原文:http://itzyx.com/index.php/javac/

动态将java文件编译为class文件解决方案:
将temp\sdl\src目录中的java源文件编译成class文件,并存放到temp\sdl\classes目录中

java中早就提供了用java方式去动态编译java源文件的接口,有关java动态编译的API都在javax.tools包中。使用jdk1.6以上版本提供的JavaCompiler工具来动态编译java源文件。
我们可以通过ToolProvider类的静态方法getSystemJavaCompiler得到JavaCompiler对象实例。
// 获取编译器实例 
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

得到JavaCompiler对象实例后,我们可以调用该工具的getTask(Writer out, JavaFileManager fileManager, DiagnosticListener<? super JavaFileObject> diagnosticListener, Iterable<String> options, Iterable<String> classes, Iterable<? extends JavaFileObject> compilationUnits) 方法获取一个编译任务对象。

CompilationTask compilationTask = compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits);

该方法的第一个参数为文件输出,这里我们可以不指定,我们采用javac命令的-d参数来指定class文件的生成目录。
第二个参数为文件管理器实例

// 获取标准文件管理器实例 
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);

 

该文件管理器实例的作用就是将我们需要动态编译的java源文件转换为getTask需要的编译单元。

// 获取要编译的编译单元 
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList);

 

第三个参数DiagnosticCollector<JavaFileObject> diagnostics是在编译出错时,存放编译错误信息。
第四个参数为编译命令选项,就是javac命令的可选项,这里我们主要使用了-d和-sourcepath这两个选项。

复制代码

/** 
* 编译选项,在编译java文件时,编译程序会自动的去寻找java文件引用的其他的java源文件或者class。 -sourcepath选项就是定义java源文件的查找目录, -classpath选项就是定义class文件的查找目录,-d就是编译文件的输出目录。 
*/ 
Iterable<String> options =Arrays.asList("-encoding",encoding,"-classpath",jars,"-d", targetDir, "-sourcepath", sourceDir); 

复制代码

 

 

第五个参数为类名称
第六个参数为上面提到的编译单元,就是我们需要编译的java源文件
当我们得到CompilationTask compilationTask编译任务后,我们就可以调用compilationTask.call()方法进行编译工作

// 运行编译任务 
compilationTask.call()

 

 

复制代码

package com.lkb.autoCode.util;

import javax.tools.*;
import javax.tools.JavaCompiler.CompilationTask;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class DynamicCompilerUtil {
    private String jars = "";
    private String targetDir = "";

    /**
     * 判断字符串是否为空 有值为true 空为:false
     */
    public boolean isnull(String str) {
        if (null == str) {
            return false;
        } else if ("".equals(str)) {
            return false;
        } else if (str.equals("null")) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 编译java文件
     *
     * @param encoding    编译编码
     * @param jars        需要加载的jar
     * @param filePath    文件或者目录(若为目录,自动递归编译)
     * @param sourceDir   java源文件存放目录
     * @param targetDir   编译后class类文件存放目录
     * @param diagnostics 存放编译过程中的错误信息
     * @return
     * @throws Exception
     */
    public boolean compiler(String encoding, String jars, String filePath, String sourceDir, String targetDir, DiagnosticCollector<JavaFileObject> diagnostics)
            throws Exception {
        // 获取编译器实例
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        // 获取标准文件管理器实例
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        try {
            if (!isnull(filePath) && !isnull(sourceDir) && !isnull(targetDir)) {
                return false;
            }
            // 得到filePath目录下的所有java源文件
            File sourceFile = new File(filePath);
            List<File> sourceFileList = new ArrayList<File>();
            this.targetDir = targetDir;
            getSourceFiles(sourceFile, sourceFileList);
            // 没有java文件,直接返回
            if (sourceFileList.size() == 0) {
                System.out.println(filePath + "目录下查找不到任何java文件");
                return false;
            }
            // 获取要编译的编译单元
            Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList);
            /**
             * 编译选项,在编译java文件时,编译程序会自动的去寻找java文件引用的其他的java源文件或者class。 -sourcepath选项就是定义java源文件的查找目录, -classpath选项就是定义class文件的查找目录。
             */
            Iterable<String> options = Arrays.asList("-encoding", encoding, "-classpath", jars, "-d", targetDir, "-sourcepath", sourceDir);
            CompilationTask compilationTask = compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits);
            // 运行编译任务
            return compilationTask.call();
        } finally {
            fileManager.close();
        }
    }

    /**
     * 查找该目录下的所有的java文件
     *
     * @param sourceFile
     * @param sourceFileList
     * @throws Exception
     */
    private void getSourceFiles(File sourceFile, List<File> sourceFileList) throws Exception {
        if (sourceFile.exists() && sourceFileList != null) {//文件或者目录必须存在
            if (sourceFile.isDirectory()) {// 若file对象为目录
                // 得到该目录下以.java结尾的文件或者目录
                File[] childrenFiles = sourceFile.listFiles(new FileFilter() {
                    public boolean accept(File pathname) {
                        if (pathname.isDirectory()) {
                            try {
                                new CopyDirectory().copyDirectiory(pathname.getPath(), targetDir + pathname.getPath().substring(pathname.getPath().indexOf("src") + 3, pathname.getPath().length()));
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            return true;
                        } else {
                            String name = pathname.getName();
                            if (name.endsWith(".java") ? true : false) {
                                return true;
                            }
                            try {
                                new CopyDirectory().copyFile(pathname, new File(targetDir + pathname.getPath().substring(pathname.getPath().indexOf("src") + 3, pathname.getPath().length())));
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            return false;
                        }
                    }
                });
                // 递归调用
                for (File childFile : childrenFiles) {
                    getSourceFiles(childFile, sourceFileList);
                }
            } else {// 若file对象为文件
                sourceFileList.add(sourceFile);
            }
        }
    }

    /**
     * 查找该目录下的所有的jar文件
     *
     * @param jarPath
     * @throws Exception
     */
    private String getJarFiles(String jarPath) throws Exception {
        File sourceFile = new File(jarPath);
        // String jars="";
        if (sourceFile.exists()) {// 文件或者目录必须存在
            if (sourceFile.isDirectory()) {// 若file对象为目录
                // 得到该目录下以.java结尾的文件或者目录
                File[] childrenFiles = sourceFile.listFiles(new FileFilter() {
                    public boolean accept(File pathname) {
                        if (pathname.isDirectory()) {
                            return true;
                        } else {
                            String name = pathname.getName();
                            if (name.endsWith(".jar") ? true : false) {
                                jars = jars + pathname.getPath() + ";";
                                return true;
                            }
                            return false;
                        }
                    }
                });
            }
        }
        return jars;
    }

    public static void main(String[] args) {
        try {
            // 编译F:\\亚信工作\\SDL文件\\sdl\\src目录下的所有java文件
            String filePath = "E:\\workspace\\COD-MS\\src";
            String sourceDir = "E:\\workspace\\COD-MS\\src";
            String jarPath = "E:\\workspace\\COD-MS\\WebRoot\\WEB-INF\\lib";
            String targetDir = "E:\\java\\project\\bin";
            DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
            DynamicCompilerUtil dynamicCompilerUtil = new DynamicCompilerUtil();
            boolean compilerResult = dynamicCompilerUtil.compiler("UTF-8", dynamicCompilerUtil.getJarFiles(jarPath), filePath, sourceDir, targetDir, diagnostics);
            if (compilerResult) {
                System.out.println("编译成功");
            } else {
                System.out.println("编译失败");
                for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
                    // System.out.format("%s[line %d column %d]-->%s%n", diagnostic.getKind(), diagnostic.getLineNumber(),
                    // diagnostic.getColumnNumber(),
                    // diagnostic.getMessage(null));
                    System.out.println(diagnostic.getMessage(null));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

复制代码

 

复制代码

package com.lkb.autoCode.util;

import java.io.*;

/**
 * 复制文件夹或文件夹
 */
public class CopyDirectory {
    // 源文件夹
    String url1 = "E:\\workspace\\DeployeTest";
    // 目标文件夹
    String url2 = "E:\\java\\project\\bin";

    public static void main(String args[]) throws IOException {
        CopyDirectory copyDirectory = new CopyDirectory();
        // 创建目标文件夹
        (new File(copyDirectory.url2)).mkdirs();
        // 获取源文件夹当前下的文件或目录
        File[] file = (new File(copyDirectory.url1)).listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 复制文件
                copyDirectory.copyFile(file[i], new File(copyDirectory.url2 + file[i].getName()));
            }
            if (file[i].isDirectory()) {
                // 复制目录
                String sourceDir = copyDirectory.url1 + File.separator + file[i].getName();
                String targetDir = copyDirectory.url2 + File.separator + file[i].getName();
                copyDirectory.copyDirectiory(sourceDir, targetDir);
            }
        }
    }

    /**
     * 复制文件
     *
     * @param sourceFile 源文件
     * @param targetFile 目标文件
     * @throws IOException
     */
    public void copyFile(File sourceFile, File targetFile)
            throws IOException {
        // 新建文件输入流并对它进行缓冲
        FileInputStream input = new FileInputStream(sourceFile);
        BufferedInputStream inBuff = new BufferedInputStream(input);

        // 新建文件输出流并对它进行缓冲
        FileOutputStream output = new FileOutputStream(targetFile);
        BufferedOutputStream outBuff = new BufferedOutputStream(output);

        // 缓冲数组
        byte[] b = new byte[1024 * 5];
        int len;
        while ((len = inBuff.read(b)) != -1) {
            outBuff.write(b, 0, len);
        }
        // 刷新此缓冲的输出流
        outBuff.flush();

        // 关闭流
        inBuff.close();
        outBuff.close();
        output.close();
        input.close();
    }

    /**
     * 复制文件夹
     *
     * @param sourceDir 源文件夹路径
     * @param targetDir 目标文件夹路径
     * @throws IOException
     */
    public void copyDirectiory(String sourceDir, String targetDir)
            throws IOException {
        // 新建目标目录
        (new File(targetDir)).mkdirs();
        // 获取源文件夹当前下的文件或目录
        File[] file = (new File(sourceDir)).listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 源文件
                File sourceFile = file[i];
                // 目标文件
                File targetFile = new File(new File(targetDir)
                        .getAbsolutePath()
                        + File.separator + file[i].getName());
                copyFile(sourceFile, targetFile);
            }
            if (file[i].isDirectory()) {
                // 准备复制的源文件夹
                String dir1 = sourceDir + "/" + file[i].getName();
                // 准备复制的目标文件夹
                String dir2 = targetDir + "/" + file[i].getName();
                copyDirectiory(dir1, dir2);
            }
        }
    }
}

复制代码

 

摘自百度文库:http://wenku.baidu.com/link?url=hFsuio_UxS4_vkt7ov8grKZp40rxJ8AR_ktzhNReoG4MGXFKf-dP_wVodVsErD737eKvaaNhVY9yEBdyXG1IEgiZeukpGU93pxCBTIbXvq3###

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 当我们将Java项目打包成jar文件时,有时会遇到不到或无法加载主类main的问题解决这个问题的方法如下: 1. 确保项目中存在一个包含main方法的主类。这个类是程序执行的入口点,必须包含一个这样的方法。确保这个类被定义为public并且在正确的包中。 2. 检查项目的构建配置是否正确。在IDE中,我们需要配置项目的构建方式,确保生成的jar文件包含所有必要的依赖和资源文件。如果配置不正确,编译器将无法到主类。 3. 检查jar文件的目录结构。jar文件是一个压缩文件,其中包含了所有的编译好的类文件和资源文件。确保main类位于正确的位置,并且在jar文件中的MANIFEST.MF文件中正确地声明了main类。 4. 如果使用外部库或依赖项,确保这些库也被正确地打包进jar文件中。在jar的构建过程中,我们需要将这些库文件加入到classpath中,以便程序能够正确加载这些类。 5. 检查操作系统或环境变量的设置。有时,不到或无法加载主类main的问题可能是由于操作系统或环境变量没有正确配置导致的。确保Java的相关路径设置正确,并且JRE或JDK的版本与项目要求的兼容。 通过以上的步骤,我们应该能够解决不到或无法加载主类main的问题,成功运行打包好的jar文件。如果问题仍然存在,我们可能需要进一步检查代码、构建配置和环境设置,以问题的根本原因。 ### 回答2: 在使用idea打包jar文件时,有时会遇到不到或无法加载主类 main的问题。这个问题通常是由于项目设置的不正确或依赖包未正确加载所致。我们可以按照以下步骤来解决这个问题。 首先,我们要确保项目的配置正确。可以通过以下步骤进行检查和修正: 1. 确保在项目的工程结构设置中,已正确指定了主类。可以在File -> Project Structure -> Project中查看和修改。 2. 检查项目的模块配置,确保主类已正确指定。可以在File -> Project Structure -> Modules中查看和修改。 3. 确保项目的运行配置正确。可以在Run -> Edit Configurations中查看和修改。 4. 检查项目的依赖配置,确保依赖包已正确加载。可以在File -> Project Structure -> Libraries中查看和修改。 如果以上步骤都已经核对无误,但问题仍然存在,我们可以尝试执行以下操作: 1. 清理和重新编译项目。可以在Build -> Rebuild Project中进行操作。 2. 在项目的out目录下手动删除旧的jar文件。 3. 删除.idea目录和.iml文件,并重新导入项目。 如果问题仍然存在,可能是由于其他问题引起的。可以尝试以下操作: 1. 检查项目的源代码,确保没有语法错误或逻辑错误。 2. 检查项目的运行环境,确保所需的Java版本已经安装和配置正确。 3. 检查项目的依赖包,确保依赖包的版本和兼容性正确。 综上所述,通过检查项目配置、重新编译、清理旧文件以及检查源代码和依赖包等方面,我们可以解决idea打包jar文件时出现不到或无法加载主类 main的问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值