【发布时间】:2020-04-30 21:51:25
【问题描述】:
我目前正在尝试添加一个 URLStreamHandler,以便可以使用自定义协议处理 URL。这在本地运行时工作正常。当部署到 AWS Lambda 时,我得到:
java.net.MalformedURLException: unknown protocol: baas
我正在关注"Handler" approach to registering the URLStreamHandler。
我什至从URL.getURLStreamHandler(String) 复制代码并将日志添加到我自己的由 Lambda 运行的代码中:
(注意:这是来自 Java 8 源 - 我现在意识到这可能不具有代表性,因为 AWS Lambda 使用 Java 11 运行时)。
URLStreamHandler handler = null;
String packagePrefixList = null;
packagePrefixList
= java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"java.protocol.handler.pkgs",""));
if (packagePrefixList != "") {
packagePrefixList += "|";
}
// REMIND: decide whether to allow the "null" class prefix
// or not.
packagePrefixList += "sun.net.www.protocol";
LOG.debug("packagePrefixList: " + packagePrefixList);
StringTokenizer packagePrefixIter =
new StringTokenizer(packagePrefixList, "|");
while (handler == null &&
packagePrefixIter.hasMoreTokens()) {
String packagePrefix =
packagePrefixIter.nextToken().trim();
try {
String clsName = packagePrefix + "." + "baas" +
".Handler";
Class<?> cls = null;
LOG.debug("Try " + clsName);
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
if (cls != null) {
LOG.debug("Instantiate " + clsName);
handler =
(URLStreamHandler)cls.newInstance();
}
} catch (Exception e) {
// any number of exceptions can get thrown here
LOG.debug(e);
}
}
这会打印(在 Cloudwatch 日志中):
packagePrefixList: com.elsten.bliss|sun.net.www.protocol (BaasDriver.java:94, thread main)
Try com.elsten.bliss.baas.Handler (BaasDriver.java:108, thread main)
Instantiate com.elsten.bliss.baas.Handler (BaasDriver.java:118, thread main)
com.elsten.bliss.baas.Handler constructor (Handler.java:55, thread main)
因此,当从我自己的代码在 Lambda 中运行时,它可以工作。
但是,下一行日志记录:
java.lang.IllegalArgumentException: URL is malformed: baas://folder: java.lang.RuntimeException
java.lang.RuntimeException: java.lang.IllegalArgumentException: URL is malformed: baas://folder
...
Caused by: java.net.MalformedURLException: unknown protocol: baas
at java.base/java.net.URL.<init>(Unknown Source)
at java.base/java.net.URL.<init>(Unknown Source)
at java.base/java.net.URL.<init>(Unknown Source)
因此,在URL 中运行相同的代码失败似乎很奇怪。我能想到的主要区别是用于加载URL 的父类加载器和我的代码不同,因此存在某种类加载问题。
SPI approach 无法使用,因为Lambda doesn't extract META-INF folders!
【问题讨论】:
标签: java aws-lambda classloader