English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

java 프로그래밍에서 동적 컴파일 및 코드 로드를 공유하는 방법

요약

이 클래스는 javax.tools.ToolProvider가 제공하는 JavaCompiler를 사용하여 컴파일하고, IO의 File 및 NIO의 Files를 사용하여 경로 생성, 읽기 및 복사를 수행하며, 패키지 이름과 디렉토리의 변환을 위해 정규 표현식을 사용합니다. 저는 이러한 것들을 오류 tolerance 통합하였고, 기술적인 내용은 없으며, 편리함을 위해 만들었습니다.

모듈 API

class DynamicReactor://비 파라미터 생성자 
public Class<?> dynamicCompile(String srcPath);//지정된 소스 파일 경로를 입력하면, 컴파일 및 복사가 성공하면 해당 클래스의 Class 인스턴스를 반환합니다 
private String changePacketToDic(String packageName);//합법한 패키지 이름을 해당 JavaClassPath 경로로 변환합니다(저는 eclipse를 사용하기 때문에 bin 디렉토리를 추가해야 합니다. 다른 컴파일러를 사용하는 경우, 적절한 실행 환경 설정을 참조하여 수정하십시오) 
private String getPackage(String srcPath);//합법한 java 파일 경로를 통해 패키지 이름을 얻으려고 시도합니다 

소스 코드

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
/** 
 * DynamicReactor은 소스 파일을 컴파일하고, 해당 패키지에 복사하고, 클래스를 로드하는 등의 과정을 담당하는 동적 컴파일 모듈입니다(JDK 1.7) 
 * @author 삼향보드砖 
 * */
public class DynamicReactor {
	JavaCompiler compiler;
	Pattern packagePattern;
	static final String regEx = "(?<=package\\s).*(?=;)";
	public DynamicReactor() 
	  {
		compiler = ToolProvider.getSystemJavaCompiler();
		packagePattern = Pattern.compile(regEx);
	}
	/** 
   * 지정된 소스 파일을 동적으로 컴파일합니다 
   * @param srcPath 소스 파일 경로 
   * @return Class 
   *   <br>성공시 해당 클래스의 Class 인스턴스를 반환합니다 
   *   <br>실패시 null을 반환합니다 
   * */
	public Class<?> dynamicCompile(String srcPath) 
	  {
		Class<?> result = null;
		//지정된 경로의 소스 파일을 얻습니다 
		String packName = getPackage(srcPath);
		if(packName == null) 
		    {
			System.out.println("DynamicRector: Load packageName Error!");
			return null;
		}
		//compiler를 호출하여 지정된 소스 파일을 컴파일합니다 
		int res = compiler.run(null, null, null,srcPath);
		if(res != 0) 
		    {
			System.out.println("DynamicRector:Compile Java Source Error!");
			return null;
		}
		//패키지 이름에对应的 경로를 얻고, 경로가 존재하지 않으면 생성하고, 지정된 class 파일이 존재하면 덮어쓰기 
		String packageDst = changePacketToDic(packName);
		File dstDir = new File(packageDst);
		if(!dstDir.exists()) 
		    {
			dstDir.mkdirs();
		}
		Path pathFrom = Paths.get(srcPath.split("\\.java")[0] + ".class");
		Path pathTo = Paths.get(packageDst,pathFrom.getFileName().toString());
		try {
			Files.move(pathFrom, pathTo, StandardCopyOption.REPLACE_EXISTING);
		}
		catch (IOException e) {
			System.out.println("DynamicRector:Move File Fail!");
			e.printStackTrace();
		}
		try {
			result = Class.forName(packName+"."+pathFrom.getFileName().toString().split("\\.class")[0]);
		}
		catch (ClassNotFoundException e) {
			System.out.println("DynamicRector:Class Not found in Final!");
		}
		return result;
	}
	//이 메서드는 유효한 패키지 이름을 해당 경로로 변환합니다 
	private String changePacketToDic(String packageName) 
	  {
		String[] dirs = packageName.split("\\.");
		String res = ".\\bin";
		for (int i = 0;i < dirs.length;i++) 
		    {
			res += "\\"+dirs[i];
		}
		return res;
	}
	//이 메서드는 주어진 경로의 소스 파일에서 패키지 이름을 얻습니다. 
	private String getPackage(String srcPath) 
	  {
		String result = null;
		BufferedReader br;
		try {
			br = new BufferedReader(new FileReader(srcPath));
			String data = br.readLine();
			while(data != null) 
			      {
				if(data.indexOf("package") != -1) 
				        {
					Matcher m = packagePattern.matcher(data);
					if(m.find()) 
					          {
						result = m.group();
					}
					break;
				}
				data = br.readLine();
			}
			br.close();
		}
		catch (IOException e) {
			System.out.println("DynamicRector: 파일 열림 중 오류 "+srcPath);
		}
		return result;
	}
}

결론

이것이 java 프로그래밍에 대해 동적 컴파일 및 로드 코드를 공유하는 전체 내용입니다. 많은 도움이 되었기를 바랍니다. 관심이 있는 분들은 이 사이트의 다른 관련 주제를 계속 참조할 수 있습니다. 불충분한 부분이 있을 경우, 댓글을 통해 지적해 주시기 바랍니다. 이 사이트에 대한 지지를 해주신 분들에게 감사합니다!

고지사항: 이 문서의 내용은 인터넷에서 가져왔으며, 저작권자는 모두에게 있습니다. 내용은 인터넷 사용자가 자발적으로 기여하고 업로드한 것이며, 이 사이트는 소유권을 가지지 않으며, 인공 편집 처리를 하지 않았으며, 관련 법적 책임도 부담하지 않습니다. 저작권 위반 내용이 있을 경우, 이메일을 notice#w로 보내 주시기 바랍니다.3codebox.com(이메일을 보내면, #을 @으로 변경하십시오. 신고를 하고, 관련 증거를 제공하십시오. 실제로 확인되면, 이 사이트는 즉시 위반된 내용을 삭제합니다.)

추천해드립니다