• 主页
  • 不能使用“处理程序”方法在AWS Lambda中添加URLStreamHandler

不能使用“处理程序”方法在AWS Lambda中添加URLStreamHandler

我目前正在尝试添加一个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!

转载请注明出处:http://www.jxbyjx.net/article/20230429/2220951.html