用了易语言拖放组件对象 组件 无法静态编译 是什么情

 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
第8章 文字字段与组件
下载积分:80
内容提示:第8章 文字字段与组件
文档格式:DOC|
浏览次数:19|
上传日期: 15:18:45|
文档星级:
全文阅读已结束,如果下载本文需要使用
 80 积分
下载此文档
该用户还上传了这些文档
第8章 文字字段与组件
官方公共微信《易语言所有命令》_互联网_IT/计算机_专业资料。――― 环境操作命令示例子...取文件时间 返回指定文件的创建或是最后一次被修改的时间。注意:如果文件不存在...
意为:系统被修改,请恢复这些修改,运行终止(操作系统受损的一种) 1、是否添加...没有文件关联…… 可以重装 E 楼主,怂么我想用易诧言打开一个电脑 exe 的...
用CE和易语言修改植物大战僵尸详细步骤代码编写_计算机软件及应用_IT/计算机_专业资料。用CE易语言修改植物大战僵尸详细步骤及代码编写 ...
易语言5.3破解补丁_计算机软件及应用_IT/计算机_专业资料。制作易语言 5.3 ...文本替换 (局部_文本, “;linker=”, “linker=”, , 1, 真) 写到文件 ...
【源码】易语言查看程序目录下所有文件源码下载地址_计算机软件及应用_IT/计算机_专业资料。【源码】易语言查看程序目录下所有文件 非常简单的源码,群里的人问了,我...
(而不可执行文件) “-ecl_name=&liigo&”, 指定的编译后的类库名称(请您务必把其中的“liigo”替换成您自己的名字, 因为这是您编译的第一个易语言类库啊,很...
自动更换墙纸的小程序易语言源码_IT/计算机_专业资料。易语言的自动更换墙纸的小...并修改 INI 文件 ' SystemParametersInfo SPI_SETDESKWALLPAPER, 0, bmpfile, ...
易语言支持库安装说明书_IT/计算机_专业资料。易语言支持库安装说明书警告:为避免支持库在使用过程中发生错误及不稳定情况,请不要反编译,修改及破解 支持库文件。...
易语言 ACCESS 数据库记录的简单修改 7、易语言 ACCESS 数据库记录的高级修改 ...代码如下,就是加了一个判断而已,用了一个“当前位置”的属性,帮助文件中的...
写到文件 (取运行目录 () +“1.kn”, #皮肤) 易皮肤_载入皮肤 (取运行...'修改 IE 主页 xxx = 子文本替换 (编辑框 1.内容, “,”, “。 , , ...利用 JDK6 动态编译组件搭建 OSGi 运行时编译环境 - 为程序员服务
利用 JDK6 动态编译组件搭建 OSGi 运行时编译环境
然则我们晓得,在垦荒 OSGi 情形下的 Bundle 时最费事的步骤之一就是搭建编译情形。即便行使 Eclipse 这样高效的垦荒对象,因为 Bundle 个数的重除夜和不合 Bundle 的版本多样性,珍重一个编译情形变得异常繁琐。经常我们需求对一个 OSGi 的 Bundle 中止二次垦荒时,仅仅一个很小的修改都需求花除夜量的时辰去搭建专为这套轨范的编译情形。我们迫切进展可以有一个运转时的编译情形来简化这些步骤,行使情形既有的依托项来对代码中止编译。
本篇文章引见 OSGi 的运转特色,Bundle 间运转时的依托体式格式和 JDK6 所供应静态编译功用,接着一步步引见若何行使这些特色搭建可以运转时编译的垦荒情形,最初经由进程 IBM System Director 作为示例,将垦荒 Bundle 安装在上面上演示以给读者一个直不雅观不雅观的体验。本文假定读者具有一定的 OSGi 根蒂根抵常识和 java 根蒂根抵常识。读完本文后,假定读者有一个 OSGi 的运转情形和想要编译的运转在这个情形上的 java 源代码,就可以自行搭建出行使这个运转情形编译出字节码文件出来以供宣布及二次垦荒行使的模块。
图 1 描写了传统基于 OSGi 的运用轨范架构:
图 1. 基于 OSGi 的运用轨范架构
要完成文章所引见的功用,运用轨范只需知足以下零星需求:
基于随意率性 OSGi4 的完成版本,如 Knopflerfish 或 Equinox。
运转 JDK 版本 6.0 或以上。
图 2 归结综合描写了本文所要描写的目的:
图 2. 运转时编译情形模子
个中 Bundle1、2 等等分离是 OSGi 运转情形中既存的 Bundle,即 OSGi 已将它们对应的 jar 包或是字节码文件加载了出去。棕色框图则是我们要制作的 OSGi 运转时静态编译 Bundle。
用户输出 Java 源代码(以敕令行或是文件方法)
静态编译模块扫描一切 Bundle,将运转时情形里一切的 jar 及 class 文件作为编译时依托留存。
行使 JDK6 供应的静态编译组件进举动态编译
编写本人的 JavaFileObject 对象,而且指定 StandardJavaFileManager 的编译目的地(这些都是 JDK6 静态编译组件的相关内容会在后续具体声名),即可编译出 Java 字节码文件
[ 可选 ] 发送 class 文件到指定邮箱完成悉数运转时编译进程。
接上去就让我们来看看若何行使 JDK6 静态编译组件和 OSGi 供应的相关功用来搭建这个运转时编译 Bundle。不内在这之前,照样有需求意见下 Bundle 之间的通讯体式格式。
Bundle 间通讯体式格式
人人都晓得 OSGi 是以 Bundle 为轨范模块单元组成的。每一个 Bundle 自力垦荒,各自成章,有本人分配的内存空间和性命周期。Bundle 也分许多品种型,有些 Bundle 只供应功用 Service,有些 Bundle 消费 Service 并出现给用户(好比 UI Bundle),还有些 Bundle 本人不零丁启举动为其他 Bundle 的 fragment Bundle 存在(好比成本文件 Bundle)等等。
Bundle 的形态也有许多种,启动胜利的 Active 形态,解析胜利守候启动的 Resolved 形态(多是启动丢失落败),安装胜利守候启动的 Installed 形态等等,关于 Bundle 的类型,性命周期及对应的形态信息这里不做具体论述,读者可以拜见 OSGi 官方声名文档。
既然 Bundle 是 OSGi 的功用单元,干事供应者和消费者 Bundle 之间,功用包供应者和消费者之间虽然需求中止互相通讯。归结综合有以下三种通讯体式格式:
Import Package 体式格式,在干事供应 Bundle 用 Export Package 导出。需求经由进程设置配备铺排 MANIFEST.MF 来完成。
Required Bundle 体式格式,在干事供应 Bundle 用 Export Package 导出。需求经由进程设置配备铺排 MANIFEST.MF 来完成。
Register Service 体式格式,在干事供应 Bundle 经由进程 BundleContext 中止 Service 注册,在消费者 Bundle 经由进程 ServiceTracker 获得 Service,需求经由进程写代码来完成。
其他假定是新垦荒 Bundle,还可以收受接管声明式体式格式获得 Service,声明式体式格式获得 service 的方法经由进程庞杂设置配备铺排能异常随意地获得 Service,垦荒者只需关注本人的逻辑,而没需求关心 OSGi 较为庞杂的查找 Service 方法。
的链接来意见更多关于 Declarative Services 尺度的具体内容。
现在我们对 OSGi Bundle 之间的通讯依托体式格式有了根抵意见之后,就可以来意见下若何静态编译了。好在 JDK6 供应了一套专门用于静态编译文件的组件来帮我们简化责任,我们只需连续庞杂的根蒂根抵类就可以完成内存中静态编译出 class 文件(好比 javac 敕令)的功用来了。
JDK6 静态编译组件
Java SE 6 之后自己集成了运转时编译的组件:javax.tools,寄存在 tools.jar 包里,可以完成 Java 源代码编译,匡助扩展年夜静态运用轨范。该包中供应次要类可以从 Java String、StringBuffer 或其他 CharSequence 中获得源代码并中止编译。
接上去经由进程代码一步步讲述若何行使 JDK6 特色进走运转时编译。
清单 1. JDK6 静态编译代码片断
// 经由进程 ToolProvider 获得 JavaCompiler 对象,JavaCompiler 对象是静态编译对象的次要对象
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// 经由进程 JavaCompiler 获得尺度 StandardJavaFileManager 对象,StandardJavaFileManager 对象次要担负
// 编译文件对象的树立,编译的参数等等,我们只对它做些根抵设置好比编译 CLASSPATH 等。
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
// 因为是从内存中读取 Java 源文件,所以需求树立我们的本人的 JavaFileObject,即 InMemoryJavaFileObject
JavaFileObject fileObject = new InMemoryJavaFileObject(className, codeString);
Iterable&? extends JavaFileObject& files = Arrays.asList(fileObject);
// 编译效果信息的记载
StringWriter sw = new StringWriter();
// 编译目的地设置
Iterable options = Arrays.asList("-d", classOutputFolder);
// 经由进程 JavaCompiler 对象获得编译 Task
pilationTask task =
compiler.getTask(sw, fileManager, null, options, null, files);
// 挪用 call 敕令实行编译,假定不胜利输出缺陷信息
if (!task.call()) {
String failedMsg = sw.toString();
System.out.println(“Build Error:” + failedMsg);
// 自界说 JavaFileObject 完成了 SimpleJavaFileObject,指定 string 为 java 源代码,这样就不必将源代码
// 存在内存中,直接从变量中读入即可。
public static class InMemoryJavaFileObject extends SimpleJavaFileObject {
private String contents =
public InMemoryJavaFileObject(String className, String contents) {
super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension),
Kind.SOURCE);
this.contents =
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
声名:正文具体声名了每步的浸染,经由进程 JDK 供应的 API,我们可以很庞杂也很无邪的进举动态运转时编译。
JRE 运转情形中若何进举动态编译
JRE 情形不像 JDK 情形,不带 javac 敕令,也省略了 tools.jar 功用组件,所以自然也不具有运转时编译的功用。假定是这样读者可以用以下体式格式来处置这个成就:
找到 tools.jar,手动导入到 bundle 中并在 MANIFEST.MF 中添加依托。
更改 JavaCompiler 的获得体式格式:
因为 ToolProvider.getSystemJavaCompiler() 照样经由进程运转时情形获得,JRE 情形下为 null,所以需求更改成直接从 Bundle-ClassPath 实例化:
JavaCompiler compiler = new com.sun.tools.javac.api.JavacTool();
这样就可以正常获得 JavaCompiler 进走运转时编译了。
搭建运转时 OSGi 编译运转情形
现在我们可以谈论若何行使 JDK6 的静态编译对象在 OSGi 特定的情形情形下进举动态编译了。想要编译 OSGi 运用轨范内随意率性 Java Code,会碰着以下的编译依托成就:
若何获得 OSGi 容器内正外行使的 Bundle 的作为 CLASSPATH 的一部份。
若何扫描获得 OSGi 情形下一切的 jar 包以作为 CLASSPATH 的一部份。
若何获得某些 jar 包打包在特定 jar 包中的那些依托项目作为 CLASSPATH 的一部份。
下节我们就来具体谈论若何处置这些个编译依托成就。
处置编译依托
我们都晓得外行使 javac 敕令中止编译时最为庞杂的就是设置 CLASSPATH 了,随意率性一个 jar 包或是 class 文件找不到就会抛出 ClassNotFoundException。Eclipse IDE 中为我们省去了这一繁琐的步骤,只需略微设置配备铺排 Build Path 就可以编译进项目一切的 class 文件来。
不幸的是,我们需求制作的静态编译 Bundle 不晓得依托项是什么,也是需求我们本人来设置 CLASSPATH,而且因为我们不晓得往后会编译什么样的文件,会用到什么样的依托,所以若何设置,设置若干就成了一个难题。
在这里笔者提出了一个处置计划,就是 扫描运用程叙文件夹中一切的 Bundle和 挪用 OSGi 中一切的 BundleLocation连络作为 CLASSPATH 来知足编译依托的无缺性。其他还要知足划定礼貌以下表所示:
表 1. 静态编译时依托项优先级划定礼貌
优先级排序
添加运转时获得的 Bundle Location 作为 CLASSPATH
JDK 在查找依托项时会 递次查找 CLASSPATH 中的类界说,假定找到了同类名的文件就行使该版本且住手查找并用此文件作为依托中止编译。假定这个版本过老,可以会抛出找不到方法的缺陷。而我们的静态编译 Bundle 的目的是“编译当前 OSGi 情形下的代码”,所以理应优先添加从 BundleContext 中找到依托项目。这样编译时就会优先依托当前情形高下文的依托项了。
扫描 OSGi 文件夹下的一切的 jar 包作为 CLASSPATH
然后,因为并非一切的依托都寄存在 BundleContext 中,有些 lib 只是作为 jar 存在于情形中。所以也需求经由进程遍历查找文件夹把这些文件作为依托项添加进 CLASSPATH。
深度扫描指定的某些 jar 包,将其包括的一切的 jar 包作为 CLASSPATH
再次,较为特殊的是,有些 jar 包中还包括着 jar 包,而这些 jar 包也是编译时需求用到的依托项。斟酌到功效成就,弗成能对悉数 jar 中止查找,这就需求用户设置配备铺排指定特殊 jar 包名来添加额定查找项了。
因为查找到悉数的这些 jar 文件的时辰视 OSGi 运用轨范的局限巨细而定,所以尽量在完成时将其留存于静态变量中以糜掷重复操作时辰。在演示章节中会示例在一个除夜型项目中各个阶段的具体所消费的时辰。
上面给出各个阶段的示例代码。
清单 2. 获得运转时 Bundle Location 的依托项
//将一切找到的Bundle Location添介入List&File&中
private static List&File& allReferences = new ArrayList&File&();;
//从BundleContext对象中获得一切的bundles
Bundle[] bundles = bundleContext.getBundles();
//遍历一切的Bundle,获得其location
for (Bundle bundle : bundles) {
//获得location的示例String以下:
//initial@reference:file:plugins/org.eclipse.core.jobs_3.4.1.R34x_v.jar/
//update@plugins/org.eclipse.core.net_1.1.0.I.jar
String bundleLocation = bundle.getLocation();
//需求中止字符串截取方能找到真实的绝对途径:
String[] splitAt = bundleLocation.split("@");
bundleLocation = splitAt[splitAt.length - 1];
String[] splitColon = bundleLocation.split(":");
bundleLocation = splitColon[splitColon.length - 1];
//拼上运转时途径就可以生成其File对象了
File f = new File("./eclipse/" + bundleLocation);
//添加至依托List
allReferences.add(f);
声名:留存下 allReferences 对象,连续添加第二第三阶段的依托项。
清单 3. 扫描 OSGi 运转目录下一切的 jar 包作为依托项
// 获得一切的 jar 文件绝对途径,而且遴选版本最新的生成 File 对象添加到 CLASSPATH 中
List&String& allJarFiles = searchFiles("..", ".jar");
for (String jarFile : allJarFiles) {
File addFile = new File(jarFile);
for (File existFile : allReferences) {
if (isElderVersion(addFile.getName(), existFile.getName())) {
allReferences.add(addFile);
// 记载一切 jar 文件的绝对途径 String
static List&String& allFiles = new ArrayList&String&();
// 前往一切 jar 文件绝对途径的 List
public static synchronized List&String& searchFiles(String startPath, String suffix) {
allFiles = new ArrayList&String&();
// start to recurse
recurse(startPath, suffix);
return allF
// 行使递归来获得一切 .jar 收尾的文件
private static void recurse(String startPath, String suffix) {
File dir = new File(startPath);
File[] files = dir.listFiles();
if (files == null)
for (int i = 0; i & files. i++) {
if (files[i].isDirectory()) {
recurse(files[i].getAbsolutePath(), suffix);
String strFileName = files[i].getAbsolutePath().toLowerCase();
if (null == suffix || "".equals(suffix)) {
allFiles.add(files[i].getAbsolutePath());
} else if (strFileName.endsWith(suffix)) {
allFiles.add(files[i].getAbsolutePath());
// 剖断能否是 allReferences 已存在了比其更新的 jar,假定有更新的就前往 false 不再添加了。
private static boolean isElderVersion(String addFile, String existFile) {
if (!isSameJarFile(addFile, existFile)) {
String addVersion = getVersionString(addFile);
String existVersion = getVersionString(existFile);
if (addVersion == null || existVersion == null) {
String[] addVs = addVersion.split("//.");
String[] existVs = existVersion.split("//.");
int length = addVs.length & existVs.length ? existVs.length : addVs.
for (i = 0; i & i++) {
int addDigit = Integer.parseInt(addVs[i]);
int existDigit = Integer.parseInt(existVs[i]);
if (addDigit & existDigit) {
} else if (addDigit & existDigit) {
if (addVs.length & existVs.length) {
} catch (Exception ex) {
声名:阶段二查找当前 OSGi 运转文件夹下一切 jar 文件作为 CLASSPATH 一部份添加,个中过滤了同文件的旧版本。在三个步骤中,阶段二较为暴力也最为费时,但因为用户可以会编译与 OSGi 容器及代码相关的随意率性文件,所以为了担保依托项的无缺性而捐躯第一次加载的时辰也是有需求的。
清单 4. 深度扫描指定的 jar 包,将其包括一切的 jar 文件也作为 CLASSPATH 的一部份
import java.util.jar.JarE
import java.util.jar.JarF
List&String& deepSearchJarNames = new ArrayList&String&();
// deepSearchJarNames 是用户设置配备铺排的需求中止深度查找的 jar 包名。
deepSearchJarNames.add("com.mycompany.libs");
// 遍历已添加的一切 reference 找到需求中止深度查找的 jar 包
for (File jarFile : allReferences) {
for (String deepJarName : deepSearchJarNames) {
if (jarFile.getName().startsWith(deepJarName)) {
JarFile jarF = new JarFile(jarFile);
Enumeration&JarEntry& jarEntries = jarF.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
if (jarEntry.getName().endsWith(".jar")) {
String filePath = jarFile.getAbsolutePath();
// 将 jar 文件解膨胀到 temp 文件夹中
if (tempOutputFolder != null && !"".equals(tempOutputFolder)) {
// Make folder if dest folder not existed.
File destF = new File(tempOutputFolder);
if (!destF.exists()) {
destF.mkdirs();
String classFile = tempOutputFolder + File.separator + jarEntry.getName();
File f = new File(classFile);
if (!f.getParentFile().exists()) {
f.getParentFile().mkdirs();
InputStream is = jarF.getInputStream(jarEntry);
FileOutputStream fos = new java.io.FileOutputStream(f);
byte[] buf = new byte[1024];
while ((len = is.read(buf)) & 0) {
fos.write(buf, 0, len);
fos.close();
is.close();
// 添加至依托 List
allReferences.add(f);
} catch (Exception ex) {
声名:阶段三将凭证用户指定的 jar 包名(可以 hard coding 也可以从设置配备铺排文件中读取),在已整理好的allReferences中中止查找。并将个中一切的 jar 文件解膨胀到暂时目录并添加进依托 List 中。
至此,我们的依托 List:allReferences 就完成了,将这个 List 作为 CLASSPATH 编译选项中止编译,只需源代码中一切的依托都在容器内,就不会泛起编译依托缺丢失落的成就了。
在检查最终代码前我们再看看还有什么可以做的。
添加发送邮件功用
这是一个额定的功用。用户虽然可以经由进程设定的 classOutputFolder 中本人去取编译好的 class 文件。我们也可以做的更自动化点,让对象在编译后为我们发送到指定的邮箱。虽然这需求用户指定 smtp 干事器。
清单 5. 发送邮件示例代码
import javax.mail.M
import javax.mail.MessagingE
import javax.mail.M
import javax.mail.S
import javax.mail.T
import javax.mail.internet.InternetA
import javax.mail.internet.MimeBodyP
import javax.mail.internet.MimeM
import javax.mail.internet.MimeM
public static boolean sendMail(String host, String from, String to, List&File& files) {
Properties props = System.getProperties();
// 设置 smtp 干事器地址
props.put("mail.smtp.host", host);
// 获得 Mail Session
Session session = Session.getInstance(props, null);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("Compiled bytecode files from DirectorDebugTool");
MimeBodyPart messageBodyPart = new MimeBodyPart();
// 填充邮件内容
StringBuffer sb = new StringBuffer();
sb.append("Compiled successfully!!
Fetch the attachments for compiled bytecode files./n/n/n/n");
sb.append("This mail is sent automatically by DirectorDebugTool,
please do not reply. Any question or problem please contact caimin@.");
messageBodyPart.setText(sb.toString());
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// 添加附件
if (files != null && files.size() & 0) {
for (File fileAttachment : files) {
if (fileAttachment.isFile()) {
messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(fileAttachment);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(fileAttachment.getName());
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
// 发送邮件
Transport.send(message);
} catch (MessagingException mex) {
声名:代码示例了假定用 javax.mail 发送邮件并把编译后的 class 文件作为附件添加到邮件中。
最终运转时编译模块
除夜功乐成了。我们完成了 JDK 静态编译的功用模块,也找到了一切编译要用到的依托项。这样就可以凭证用户输出的源代码进走运转时编译,而且发送到用户指定的邮箱了。
经由调解的静态编译模块最终示例代码以下所示:
清单 6. 静态编译部份的最终代码
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
//设置编译依托的CLASSPATH。
//setLocation的value为Iterable&? extends File&,只需将allReferences前往即可完成设置编译依托。
fileManager.setLocation(StandardLocation.CLASS_PATH, Utils.getCompileClassPath());
JavaFileObject fileObject = new InMemoryJavaFileObject(className, codeString);
Iterable&? extends JavaFileObject& files = Arrays.asList(fileObject);
StringWriter sw = new StringWriter();
Iterable options = Arrays.asList("-d", classOutputFolder);
pilationTask task =
compiler.getTask(sw, fileManager, null, options, null, files);
if (!task.call()) {
String failedMsg = sw.toString();
System.out.println(“Build Error:” + failedMsg);
//获得classOutputFolder中一切的.class文件,并作为参数挪用发送邮件模块
File dir = new File(classOutputFolder);
File[] allClassFiles = dir.listFiles();
List&File& sendAttachments = new ArrayList&File&();
for (File file : allClassFiles) {
if (file.getName().endsWith(".class")) {
sendAttachments.add(file);
//发送邮件
Utils.sendMail(host, "DynamicCompileTool", to, sendAttachments);
OSGi 运转时编译组件小试牛刀
以上列出了基于 OSGi 的运转时静态编译组件的次要代码。笔者也花了一些时辰垦荒完成了一个特定的 Bundle,它包括 GUI 用来领受用户输出(复制)源代码,也包括了一切上述的源代码,并将它安装到已宣布的 IBM System Director 产物中理想行使了起来,效果比拟理想。接上去将凭证这个特定的场景演示下这个运转时编译组件是若何行使的。
演示情形:IBM System Director
IBM Systems Director 是一款综合的零星治理平台,为庞杂的 IT 情形供应单点治理和自动化功用。它基于 OSGi 平台的 Equinox 完成,经由几年的垦荒珍重,今朝已有跨越 800 个 Bundle,零星目录数千个 jar 包。在这里作为一个示例,看看这个本人垦荒的运转时编译组件在成熟的企业级 OSGi 产物情形中显示若何。
注:关于 IBM Systems Director 的具体信息可
在 IBM System Director 运转时编译源代码并发送邮件
将 Bundle 宣布到 IBM System Director 中随情形启动。我们可以掀开以下的用户交互界面:
图 3. 对象主界面
这里可以看到一个 TextArea 用于输出源代码,Email 和 Mail Server 的 TextBox 用于设置配备铺排发送邮件功用。
考试考试编译源代码,这里行使对象 Bundle 里的 Utils.java 来做演示。
图 4. 运转时编译源代码
点击 Compile and Mail Class 按钮后提醒编译胜利,仅编译部份花了 2.5s。邮件发送到了 caimin@,去看看 .class 文件能否是作为附件发送了过来。
图 5. 运转时编译源代码
邮件已收到。信息内容无误而且编译后的 class 字节码文件和内部类都发送了过来。运转时编译对象胜利得完成了容器内编译进程,帮我们省下了搭建情形的时辰。不外还没完,让我们来整理下 log 看看在第一次实行时汇集一切依托项的功效若何。
表 2. 生成依托项各阶段所消费的时辰
扫描运转时的 Bundle Location
扫描 OSGi 文件夹下的一切的 jar 包
深度扫描指定的指定的 jar 包
注:总共生成 1790 个依托项。
可以留意到第二阶段递归扫描一切 jar 包最为耗时,但正如前文所说,因为用户可以会编译随意率性文件,为了担保依托项的无缺性这是必需消费的时辰。好在只需 OSGi 不重启,这样的查找操作只会实行一次,往后的编译中就不会再消费这么多时辰了。
本文先是引见了 OSGi 的运用轨范架构和 Bundle 间依托关系。再是引见了 JDK6 中供应的静态编译功用,并供应了示例代码。在您有了呼应的配景常识后,提出了在 OSGi 运转时容器内静态编译的概念,并供应意见决编译依托项的处置计划,将这些功用组件连络,理论上就可以在随意率性 OSGi 容器内进走运转时编译了。再次连络了发送邮件功用,在 IBM System Director 上演示了对象的行使效果,给读者更直不雅观不雅观的熟习。
本文仅针对编译单个 Java 文件,您完整可以凭证本人项目情形,连络 ant 或 maven,垦荒可以在容器内编译和安装悉数项目的对象。同时适用局限也可以加以拓展,不只是 OSGi 情形,一切基于 Java 平台的都可以进走运转时静态编译。进展本文能给读者带来启示,也守候能与读者进一步交流商酌相关延迟领域的手艺。
原文地址:, 感谢原作者分享。
您可能感兴趣的代码

我要回帖

更多关于 iis伪静态组件 的文章

 

随机推荐