无法使用“ Handler”方法在AWS Lambda中添加URLStreamHandler

问题描述 投票:1回答:1

我目前正在尝试添加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
1个回答
0
投票

起初,我认为应该避免使用旧的META-INF方法,但是事实证明,在最近的Java版本中,这种方法已经得到了改进,因此我又回到了这一点。

特别是,如果提供的自定义选项无法处理流,则能够将流处理为URL.setURLStreamHandlerFactory(URLStreamHandlerFactory)URLStreamHandlerFactoryhttp等的默认回退https用作回退。

尽管这是一种解决方法-知道为什么无法加载该类很有趣。

© www.soinside.com 2019 - 2024. All rights reserved.