常常在網路上爬文,看到關於FireWire火線外接設備比其他USB的貴,總是摸不著道理所在。
手上有一部舊款的MacBook小白,前些日子硬碟掛了,在換上新的之後開始要安裝OSX Tiger;
不過,這是緊張時刻的開始,因為小白的CDROM已老化會有咬片的情形;而且試兩次之後,確實也傷痕累累,深怕手上原版光碟給毀了。
在用功爬文(Melvin1976與BNW)之後,發現可以用FireWire將另一部MacBoo Pro的CDROM,"借"給小白來用;
於是乎照表操課著手進行演練,有圖為證:
從圖看來,MackBook小白run的是MacBook Pro上的OSX Snow Leopard;
當然接著是選擇CDROM為啟動光碟,重新開機後來進行安裝。
原來~~~FireWire有這樣存在的價值啊!
這次經驗後,也才知道備份安裝光碟有多重要啊!而且使用Disk Utility就可以做了,不用花錢的。
2012年6月6日
2012年5月29日
Groovy Category(Mixin)初探
今天參加了第四屆 Scala Taipei 聚會,由Walter主講Typeclass in Scala;現場展示了traits與implicit功能,展現了物件的type-safe及subtyping(polymorphism)威力,並可隨心所欲的創造不同subtype的object;真是收獲良多!
於是乎讓我連想到了在很多領域都具有相同的功能:mix-in概念,諸如:Ruby的module、Objective-C的Category。當然,身為Groovy的使用者,也不能放過號稱dynamic language的Groovy。
在Groovy中使用了Category這個名稱,實作上則分成兩種典型:
也就是不要宣告型別,否則會發生 Caught: groovy.lang.MissingMethodException: No signature of method: ...錯誤。
所以要如下範例:
於是乎讓我連想到了在很多領域都具有相同的功能:mix-in概念,諸如:Ruby的module、Objective-C的Category。當然,身為Groovy的使用者,也不能放過號稱dynamic language的Groovy。
在Groovy中使用了Category這個名稱,實作上則分成兩種典型:
- use() method(範列如:Categorize me this)
- mixin() method(範例如:Use a mixin)
也就是不要宣告型別,否則會發生 Caught: groovy.lang.MissingMethodException: No signature of method: ...錯誤。
所以要如下範例:
// current file def config = new ConfigSlurper().parse(new File('/tmp/my.properties').toURI().toURL()) use( MyCategory ) { config.append() } // another file import groovy.util.ConfigObject class MyCategory { static def append(conf) { conf.params << [YEAR: '2012', MONTH: '05', DAY: '29'] } }而mixin() method則用在instance method上;但groovy script的實作上與groovy class有些不同;因為每個script有各自的class loader,所以使用到別的script的method時,要先載入該script(Load script from groovy script)。如下所示:
// current file def script = new GroovyScriptEngine( 'src/groovy' ).with { loadScriptByName( 'MyCategory.groovy' ) } this.metaClass.mixin script def config = new ConfigSlurper().parse(new File('/tmp/my.properties').toURI().toURL()) append(config) // another file import groovy.util.ConfigObject class MyCategory { def append(conf) { conf.params << [YEAR: '2012', MONTH: '05', DAY: '29'] } }
2012年5月21日
自ZIP或JAR file中載入class執行
對於從事多年的應用系統開發,通常會選擇web application方式來進行;多半因為可以用http方式來取代自行設計有關socket的程式。
但,每每專案中或多或少會做些有用的utility供其他程式使用,在系統不大的情形下,少有將這些utility做成JAR file(放在WEB-INF/lib目錄)的需要;所以,就試想「如果可以像JAR file那樣,直接拿WAR file來使用就好了,如:
可是,大家都知道WAR file與JAR file結構不同,要達到這個目的就得先知道MANIFEST的結構;例如,指定一個main class:
但WAR file中,class不是在WEB-INF/classes中,就是在WEB-INF/lib中;所以還需指定 classpath:
多半按上述方法完成後,如同這篇說明一樣,測試的結果會是:
顯然,Class-Path不是這樣子用的。
不過,該說明的解答中提到,可以模仿Hudson.war一般:自製main class。另外,因為WAR file無異於其他的ZIP file,於是請教了谷歌大神之後,找到這篇教如何自ZIP或JAR file中載入class。
最後就完成了我的需求「即是WAR file,又可以執行某一class」:
程式如下:
不過,這個Main class記得要包在WAR file中的根目錄下。
java -jar myapp.war
可是,大家都知道WAR file與JAR file結構不同,要達到這個目的就得先知道MANIFEST的結構;例如,指定一個main class:
Manifest-Version: ... Ant-Version: ... Created-By: ... Main-Class: Main
但WAR file中,class不是在WEB-INF/classes中,就是在WEB-INF/lib中;所以還需指定 classpath:
... Class-Path: WEB-INF/classes ...
多半按上述方法完成後,如同這篇說明一樣,測試的結果會是:
java.lang.NoClassDefFoundError
顯然,Class-Path不是這樣子用的。
不過,該說明的解答中提到,可以模仿Hudson.war一般:自製main class。另外,因為WAR file無異於其他的ZIP file,於是請教了谷歌大神之後,找到這篇教如何自ZIP或JAR file中載入class。
最後就完成了我的需求「即是WAR file,又可以執行某一class」:
java -jar myapp.war "some-parameter-for-launching-SomeUtil"
程式如下:
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import my.util.SomeUtil; public class Main extends ClassLoader { private static final String DELEGATE = "my.util.SomeUtil"; private final ZipFile file; public Main(String filename) throws IOException { this.file = new ZipFile(filename); } @Override public Class findClass(String name) throws ClassNotFoundException { ZipEntry entry = this.file.getEntry( (this.file.getName().endsWith("war") ? "WEB-INF/classes/" : "") + name.replace(".", "/") + ".class" ); if (entry == null) { throw new ClassNotFoundException(name); } try { byte[] array = new byte[1024]; InputStream ins = this.file.getInputStream(entry); ByteArrayOutputStream out = new ByteArrayOutputStream(array.length); int length = ins.read(array); while (length > 0) { out.write(array, 0, length); length = ins.read(array); } return defineClass(name, out.toByteArray(), 0, out.size()); } catch (IOException exception) { throw new ClassNotFoundException(name, exception); } } /** * @param args */ public static void main(String[] args) { if(args != null) { try { Main classLoader = new Main(args[0]); classLoader.findClass(DELEGATE); System.out.println(SomeUtil.doSomething(args[1])); } catch (Exception e) { e.printStackTrace(); } } } }
不過,這個Main class記得要包在WAR file中的根目錄下。
2012年4月15日
訂閱:
文章 (Atom)