更新時(shí)間:2021-05-25 15:24:55 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1080次
Java是一個(gè)開放的平臺(tái),對(duì)于除發(fā)布編譯器/解釋器/基礎(chǔ)類庫(kù)之外,該語(yǔ)言的負(fù)責(zé)機(jī)構(gòu)更多的是制定一系列標(biāo)準(zhǔn),任何符合標(biāo)準(zhǔn)的廠商產(chǎn)品均可用于市場(chǎng)投放。甚至包括其編譯器及解釋器。
(比如Hibernate提供了JPA實(shí)現(xiàn);Tomcat實(shí)現(xiàn)了Java EE服務(wù)器標(biāo)準(zhǔn),其Servlet容器通過了Java認(rèn)證;各數(shù)據(jù)庫(kù)或中間件廠商也根據(jù)JDBC接口開發(fā)驅(qū)動(dòng)。說白了,Java基本就是都提供接口,然后讓廠商開發(fā)實(shí)現(xiàn),因此有時(shí)候我會(huì)罵,邊罵邊編碼!)
GCC有java編譯器,可以看看。
我們主要主要介紹Eclipse自己開發(fā)和使用的針對(duì)Java的編譯器:(ecj)the Eclipse Compiler for Java。Eclipse沒有使用JDK自帶的編譯器,而是自己開發(fā)的,ecj也通過了java的驗(yàn)證。
除了Eclipse之外,Tomcat也用到了Ecj,用于動(dòng)態(tài)編譯jsp文件。我們安裝Tomcat后可在lib文件夾下找到ecj:
現(xiàn)在問題來了:怎么取得ecj源碼呢?
別急,我們從tomcat源碼中查看一下:
下面是我下載好后倒入項(xiàng)目文件后截圖:
這個(gè)文件報(bào)錯(cuò),不過可以把他刪除了看,我先沒有刪除,因?yàn)檫@個(gè)文件是ecj與ant的橋梁。從源碼可以看出這個(gè)JDTCompilerAdapter是繼承自ant的DefaultCompilerAdapter,用于ant的編譯器適配器。個(gè)人感覺ecj從代碼(技術(shù))上并沒有耦合任何一個(gè)調(diào)用者,這里的ant也只是一個(gè)適配器,你刪除或者留著沒有任何影響。Tomcat里也沒有使用ant。
我從這里主要是想看看高層怎么調(diào)用ecj來編譯代碼,我們看看關(guān)鍵代碼:
private static String compilerClass = "org.eclipse.jdt.internal.compiler.batch.Main"; //$NON-NLS-1$
/**
* Performs a compile using the JDT batch compiler
* @throws BuildException if anything wrong happen during the compilation
* @return boolean true if the compilation is ok, false otherwise
*/
public boolean execute() throws BuildException {
this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.usingJDTCompiler"), Project.MSG_VERBOSE); //$NON-NLS-1$
Commandline cmd = setupJavacCommand();
try {
Class c = Class.forName(compilerClass);
Constructor batchCompilerConstructor =
c.getConstructor(new Class[] {
PrintWriter.class,
PrintWriter.class,
Boolean.TYPE,
Map.class});
Object batchCompilerInstance =
batchCompilerConstructor.newInstance(new Object[] {
new PrintWriter(System.out),
new PrintWriter(System.err),
Boolean.TRUE,
this.customDefaultOptions});
Method compile =
c.getMethod("compile", new Class[] {String[].class}); //$NON-NLS-1$
Object result =
compile.invoke(batchCompilerInstance, new Object[] {
cmd.getArguments()});
final boolean resultValue = ((Boolean) result).booleanValue();
if (!resultValue && this.logFileName != null) {
this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.error.compilationFailed", this.logFileName)); //$NON-NLS-1$
}
return resultValue;
} catch (ClassNotFoundException cnfe) {
throw new BuildException(AntAdapterMessages.getString("ant.jdtadapter.error.cannotFindJDTCompiler")); //$NON-NLS-1$
} catch (Exception ex) {
throw new BuildException(ex);
}
}
我把代碼換了下行,大家看13和26行,可以看出這里使用了
org.eclipse.jdt.internal.compiler.batch.Main#compile(String[])方法來進(jìn)行編譯,我們可以稍微看看:
從源碼上來看1664是配置,1684可能是編譯,不過我們先不細(xì)看。
我們?cè)倏纯碩omcat怎么使用ecj的,我們查看org.apache.jasper.compiler.JDTCompiler源碼(我貼出了源碼,不過有點(diǎn)長(zhǎng)):
從427可以知道,Tomcat使用了org.eclipse.jdt.internal.compiler.Compiler#compile(ICompilationUnit[])
當(dāng)然,在這之前使用了很多代碼來進(jìn)行配置。
以上就是動(dòng)力節(jié)點(diǎn)小編介紹的"Java編譯器eclipse的主要分析",希望對(duì)大家有幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為您服務(wù)。
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)