專案需定期呼叫外部 HTTP API 監控服務狀態。開發環境 (Tomcat) 使用 Apache Commons HttpClient 3.1 運作正常;部署至 Oracle IAS (OC4J) 卻拋出 NoClassDefFoundError,堆疊指向 HttpMethodBase.writeRequestLine。
commons-httpclient-3.1.jar, commons-codec-1.3.jar 版本、大小、MD5 完全相同。class-loader 設定、打包進 EAR/lib、設定 imported-shared-libraries 均未果,OC4J 父優先載入機制難以打破。HttpURLConnection考量:
import java.io.*;
import java.net.*;
import java.util.logging.Logger;
public class UrlMonitor {
private static final Logger LOG = Logger.getLogger(UrlMonitor.class.getName());
private static final int TIMEOUT_MS = 10_000;
private static final int BUFFER_SIZE = 4096;
/**
* 呼叫 URL 並檢查回應內文是否包含 successFlag
* @return true=成功且包含關鍵字, false=失敗/不含關鍵字
*/
public boolean visitUrl(String urlStr, String successFlag) {
HttpURLConnection conn = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(TIMEOUT_MS);
conn.setReadTimeout(TIMEOUT_MS);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setUseCaches(false);
try (InputStream in = conn.getInputStream()) {
byte[] buf = new byte[BUFFER_SIZE];
int len;
while ((len = in.read(buf)) != -1) {
baos.write(buf, 0, len);
}
}
String response = baos.toString("UTF-8"); // 依實際編碼調整
LOG.fine("Response: " + response);
if (response.contains(successFlag)) {
LOG.info("Visit URL [" + urlStr + "] SUCCESS");
return true;
} else {
LOG.warning("Visit URL [" + urlStr + "] missing flag: " + successFlag);
return false;
}
} catch (MalformedURLException e) {
LOG.severe("Invalid URL: " + urlStr + " - " + e.getMessage());
} catch (IOException e) {
LOG.severe("Transport error: " + e.getMessage());
} finally {
if (conn != null) conn.disconnect();
try { baos.close(); } catch (IOException ignored) {}
}
return false;
}
}
| 項目 | 處理方式 |
|---|---|
| 連線/讀取超時 | setConnectTimeout / setReadTimeout 防止卡死 |
| 編碼處理 | 明確指定 baos.toString("UTF-8"),避免平台預設編碼亂碼 |
| 資源釋放 | try-with-resources (JDK 7+) 自動關閉 InputStream;finally 確保 disconnect |
| 大回應處理 | 若回應可能超大,改用 BufferedReader 逐行檢查,避免記憶體暴漲 |
| HTTPS 支援 | JDK 內建支援,若憑證自簽需配置 TrustManager |
移除專案所有 HttpClient 相關 JAR,重新打包部署至 OC4J,排程任務執行正常,錯誤日誌歸零。
class-loader 子優先或打包為共享庫,維護成本高。