Java Web Start為什麼能載入pack.gz

瓜瓜東西發表於2014-06-04
我們每次給國外更新的時候,都只是更新了 .jar.pack.gz, 不用更新jar。只知道這樣可以,不知道為什麼可以,每次出問題我們也會考慮,會不會載入成老的jar包了。
今天到官網上找了找,發現了原因:
以JBOSS為例,在webstart.war\WEB-INF\lib下面有jnlp-servlet.jar,我們點選介面上jnlp的連結後,會與jnlp-servlet.jar中的JnlpDownloadServlet互動,在根據jnlp上的resource查詢jar時,也會找以 .pack.gz或 .gz 結尾的同名檔案,見程式碼:
// pack200 compression
if (encoding != null && _mimeType != null &&
(_mimeType.compareTo(JAR_MIME_TYPE) == 0 || _mimeType.compareTo(JAR_MIME_TYPE_NEW) == 0) &&
encoding.toLowerCase().indexOf(DownloadResponse.PACK200_GZIP_ENCODING) > -1){
search_path = orig_path + pack.gz";
_resource = context.getResource(search_path);

// gzip compression
if (found == false && encoding != null &&
encoding.toLowerCase().indexOf(DownloadResponse.GZIP_ENCODING) > -1){
search_path = orig_path +".gz";
_resource = context.getResource(search_path);

程式碼:
public JnlpResource(ServletContext context, 
String name, 
String versionId, 
String[] osList, 
String[] archList, 
String[] localeList,
String path,
String returnVersionId,
String encoding) { 
// Matching arguments
_encoding = encoding;
_name = name;
_versionId = versionId; 
_osList = osList;
_archList = archList;
_localeList = localeList;

_returnVersionId = returnVersionId;

/* Check for existance and get last modified timestamp */
try {
String orig_path = path.trim();
String search_path = orig_path;
_resource = context.getResource(orig_path); 
_mimeType = getMimeType(context, orig_path);
if (_resource != null) {

boolean found = false;
// pack200 compression
if (encoding != null && _mimeType != null &&
(_mimeType.compareTo(JAR_MIME_TYPE) == 0 || _mimeType.compareTo(JAR_MIME_TYPE_NEW) == 0) &&
encoding.toLowerCase().indexOf(DownloadResponse.PACK200_GZIP_ENCODING) > -1){
search_path = orig_path + pack.gz";
_resource = context.getResource(search_path);
// Get last modified time
if (_resource != null) {
_lastModified = getLastModified(context, _resource, search_path);
if (_lastModified != 0) {
_path = search_path;
found = true;
} else {
_resource = null;
}
}
}

// gzip compression
if (found == false && encoding != null &&
encoding.toLowerCase().indexOf(DownloadResponse.GZIP_ENCODING) > -1){
search_path = orig_path +".gz";
_resource = context.getResource(search_path);
// Get last modified time
if (_resource != null) {
_lastModified = getLastModified(context, _resource, search_path);
if (_lastModified != 0) {
_path = search_path;
found = true;
} else {
_resource = null;
}
}
}

if (found == false) {
// no compression
search_path = orig_path;
_resource = context.getResource(search_path);
// Get last modified time
if (_resource != null) {
_lastModified = getLastModified(context, _resource, search_path);
if (_lastModified != 0) {
_path = search_path;
found = true;
} else {
_resource = null;
}
}

}
} catch(IOException ioe) {
_resource = null;

}

因為它還會判斷.jar是否存在,所以不能說只有 .pack.gz沒有 .jar也行
程式碼:
JnlpResource jnlpres = new JnlpResource(getServletContext(), dreq.getPath());
if (!jnlpres.exists()) { 
throw new ErrorResponseException(DownloadResponse.getNoContentResponse());
}

程式碼:
public boolean exists() { return _resource != null; }

程式碼:
_resource = context.getResource(orig_path);

orig_path就是以.jar結尾的檔案路徑。
而且jws是通過.jar的name來找 .pack.gz或 .gz的

最後說說為什麼會用.pack.gz?
其實原因很簡單,就是包會越來越大,不壓縮的話,下載的速度會很慢,對使用者和網費都是很大的考驗。所以在java5.0後提供了pack 200, 能將包壓縮到之前的10~15%。這樣下載就會相對好多了

jnlp-servlet.jar的原始碼在JDK的。。。/sample/jnlp/servlet目錄下面

相關文章