JavaCallout 政策运行时错误问题排查

您正在查看 Apigee Edge 文档。
前往 Apigee X 文档。
信息

ResourceDoesNotExist

错误消息

通过 Edge 界面或 Edge Management API 部署 API 代理失败并显示以下错误消息:

Error Deploying Revision <var>revision_number</var> to <var>environment</var>
Resource with name <var>ResourceURL</var> and type java does not exist.

错误消息示例

Error Deploying Revision 1 to test
Resource with name myresource.jar and type java does not exist.

错误屏幕截图示例

原因

如果 JavaCallout 政策的 <ResourceURL> 元素中指定的资源在 API 代理、环境或组织级别不存在,则 API 代理的部署将失败。

诊断

  1. 标识环境和资源名称。您可以在错误消息中找到此信息。例如,在以下错误中,环境为 test,ResourceURL> 元素中使用的资源名称为 myresource.jar。

    Error Deploying Revision 1 to test
    Resource with name myresource.jar and type java does not exist.
    
  2. 确定使用上述第 1 步中标识的资源的 JavaCallout 政策。

    例如,以下政策将 ResourceURL> 的值指定为 myresource.jar,该值与错误消息中的值相匹配:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <JavaCallout name="hello-java">
        <ClassName>com.apigeesample.HelloJava</ClassName>
        <ResourceURL>java://myresource.jar</ResourceURL>
    </JavaCallout>
    
  3. 确定资源是属于失败的 API 代理,还是在环境或组织级别上传的。如果不是,则这是错误原因。

    • 导航到 API 代理编辑器导航窗格中的“资源”标签页,以查看在 API 代理级别上传的所有资源。在此示例中,API 代理未上传任何资源。

    • 资源可在环境级或组织级提供。如需了解详情,请参阅资源文件。

      • 如需确定资源是否存在于环境级,请使用 curl 发出以下 API 调用: curl -v -u <strong>email </strong>"https://api.enterprise.apigee.com/v1/organizations/myorg/environments/myenv/resourcefiles/java/myresource.jar"

      • 如需确定资源是否存在于组织级,请使用 curl 发出以下 API 调用,并省略环境详细信息: curl -v -u email "https://api.enterprise.apigee.com/v1/organizations/myorg/resourcefiles/java/myresource.jar"

      如果您收到 404 状态代码作为这些 API 的响应,那么组织和环境级别都缺少资源。

    如果资源在 API 代理、组织和环境级不可用,则会返回部署错误:

    Resource with name myresource.jar and type java does not exist.
     ```
    

分辨率

确保在 <ResourceURL> 元素中指定的资源在 API 代理、环境或组织级别存在。如需了解详情,请参阅资源文件。

如需更正上面所示的 JavaCallout 政策示例,请在适当的级别(API 代理、组织或环境级别)上传 JAR 文件。

NoResourceForURL

错误消息

通过 Edge 界面或 Edge Management API 部署 API 代理失败并显示以下错误消息:

Error in deployment for environment <var>environment</var>
The revision is deployed, but traffic cannot flow. Could not locate a resource with URL <var>ResourceURL</var>

错误消息示例

Error in deployment for environment test
The revision is deployed, but traffic cannot flow. Could not locate a resource with URL java://myresource.jar

错误屏幕截图示例

原因

即使资源文件在 API 代理、环境或组织级别显示为存在,也可能已损坏或部分上传,在这种情况下可能会发生此错误。

诊断

  1. 标识环境和资源名称。您可以在错误消息中找到此信息。例如,在以下错误中,环境名称为 test,ResourceURL> 元素中使用的资源名称为 myresource.jar。

    Error in deployment for environment test
    The revision is deployed, but traffic cannot flow. Could not locate a resource with URL java://myresource.jar
    
  2. 确保资源已在 API 代理、环境或组织级别上传。在以下示例中,您可以看到在 API 代理级别上传了资源 myresource.jar。

    资源可在环境级或组织级提供。如需了解详情,请参阅资源文件。

    如需确定资源是否存在于环境级,请使用 curl 发出以下 API 调用: curl -v -u <strong>email </strong>"https://api.enterprise.apigee.com/v1/organizations/myorg/environments/myenv/resourcefiles/java/myresource.jar"

    如需确定资源是否存在于组织级层,请使用 curl 发出以下 API 调用,并省略环境详细信息: curl -v -u email "https://api.enterprise.apigee.com/v1/organizations/myorg/resourcefiles/java/myresource.jar"

    如果您收到 404 状态代码作为这些 API 的响应,那么组织和环境级别都缺少资源。

分辨率

  1. 如果您确定资源存在于 API 代理、组织或环境级层,请按照第 2 步中的说明删除该资源并重新上传。否则,请跳到第 3 步。
  2. 如需删除 API 代理级层的资源,请前往 API 代理编辑器的“导航器”窗格中的“资源”标签页,然后点击资源旁边的“X”按钮,如下所示。

    如需在环境或组织级删除资源,请对之前在诊断步骤中使用的 API 调用使用 DELETE 动词。例如,如需删除环境级资源,请输入以下命令: curl -X DELETE -v -u <strong>email </strong>"https://api.enterprise.apigee.com/v1/organizations/myorg/environments/myenv/resourcefiles/java/myresource.jar"

  3. 在适当的级别(API 代理、组织或环境级别)上传 JAR 文件。

  4. 如果重新上传资源无法解决问题,则需要重启受影响的消息处理器。如果您使用的是云端 Apigee Edge,请与 Apigee 支持团队联系。 如果您是私有云用户,请参阅启动、停止、重启和检查 Apigee Edge 的状态。

JavaCalloutInstantiationFailed

错误消息

通过 Edge 界面或 Edge Management API 部署 API 代理失败并显示以下错误消息:

Error in deployment for environment <var>environment</var>
The revision is deployed, but traffic cannot flow. Failed to instantiate the JavaCallout Class <var>class_name</var>

或

Error in deployment for environment <var>environment</var>.
The revision is deployed and traffic can flow, but flow may be impaired. Failed to instantiate the JavaCallout Class <var>class_name</var>

错误消息示例

Error in deployment for environment test
The revision is deployed, but traffic cannot flow. Failed to instantiate the JavaCallout Class my.class

错误屏幕截图示例

原因

下面是此错误的典型原因

原因 说明
缺少 JAR 文件 系统不会上传包含错误中所标识的 Java 类的 JAR 文件。
JAR 文件已损坏 包含错误中所标识的 Java 类的 JAR 文件已损坏/部分上传。
缺少类文件 错误消息中标识的 Java 类文件不属于 >ResourceURL< 或相关 JAR 文件中指定的 JAR 文件。
Java 代码问题 代码存在错误,如缺少构造函数、代码依赖项问题或其他问题。

常用诊断步骤

  1. 标识环境名称和无法导入的类。例如,在以下错误消息中,环境名称为 test,类名称为 my.class:

    Error in deployment for environment test
    The revision is deployed, but traffic cannot flow. Failed to instantiate the JavaCallout Class my.class
    
    

    原因:缺少 JAR 文件

诊断

  1. 确定应包含类(在上述第 1 步中标识)且不能实例化的 JAR 文件。
  2. 检查是否在 API 代理、组织或环境级别上传了特定 JAR 文件。如果 JAR 文件未上传到任何级别,请转到“解决方法”。
  3. 如果 JAR 文件已上传,请转到原因:JAR 文件损坏。

分辨率

  1. 如果 JAR 文件已损坏或部分上传,则在相应级别(API 代理、组织或环境级别)重新构建 JAR 并上传 JAR 文件。
  2. 重新部署 API 代理。

原因:JAR 文件损坏

诊断

  1. 确定应包含类(在上述第 1 步中标识)且不能实例化的 JAR 文件。
  2. 检查特定 JAR 文件是否已损坏。例如,如果您由于文件已损坏或部分上传而无法解压缩文件。如果已损坏,请转到“解决方法”。
  3. 如果 JAR 文件未损坏,请转到原因:缺少类文件。

分辨率

  1. 重新构建已损坏的 JAR 文件,并在相应级别(API 代理、组织或环境级别)上传 JAR 文件。
  2. 重新部署 API 代理。

原因:缺少类文件

诊断

  1. 检查特定的 Java 类文件(上面第 1 步中标识)是否属于在 >ResourceURL< 或任何相关 JAR 文件中指定的 JAR 文件。
  2. 如果任何 JAR 文件中都不存在类文件,则表示您已确定错误原因。转到“解决方法”。
  3. 如果类文件存在于在 JavaCallout 政策中指定的一个 JAR 文件中,则是 Java 代码或依赖类引发此错误。 a. 如果您是公共云用户,请与 Apigee 支持团队联系。 b. 如果您是 Private Cloud 用户,请前往原因:Java 代码问题。

分辨率

  1. 使用缺少的类文件重新构建 JAR,并在相应级别(API 代理、组织或环境级别)上传 JAR 文件。
  2. 重新部署 API 代理。

原因:Java 代码问题

仅适用于私有云用户的诊断步骤

诊断

  1. 检查消息处理器日志(/opt/apigee/var/log/edge-message-processor/system.log 和 /opt/apigee/var/log/edge-message-processor/configurations.log)。
  2. 您可能会看到类似于以下示例的异常:

    2019-07-05 05:40:13,240 org:myorg env:staging target:/organizations/myorg/apiproxies/MyAPI/revisions/5 action:add context-id: mode: Apigee-Main-53 ERROR CONFIG-CHANGE - AbstractConfigurator.add() : Add null to Step failed, reason: {}
    com.apigee.kernel.exceptions.spi.UncheckedException: Failed to instantiate the JavaCallout Class <class name>
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition.newInstance(JavaCalloutStepDefinition.java:116)
    at com.apigee.messaging.runtime.StepDefinition.getStepDefinitionExecution(StepDefinition.java:218)
    …<snipped>
    Caused by: java.lang.reflect.InvocationTargetException: null
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition.access$100(JavaCalloutStepDefinition.java:41)
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition$CallOutWrapper.initialize(JavaCalloutStepDefinition.java:131)
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition$CallOutWrapper.<init>(JavaCalloutStepDefinition.java:126)
    ... 42 common frames omitted
    Caused by: <Reason>
    
    ...<snipped>
    
    
  3. 仔细阅读异常,了解失败原因。通常,这可能表示您的 Java 代码存在一些问题。

分辨率

  1. 根据失败的原因,您可能需要修复 Java 代码中的问题。
  2. 使用缺少的类文件重新构建 JAR,并在相应级别(API 代理、组织或环境级别)上传 JAR 文件。
  3. 重新部署 API 代理。

上传 JAR 文件

确保资源元素(包含所有必需的类)存在于 API 代理、环境或组织级别。如需了解详情,请参阅资源文件。

  1. 如需在 API 代理级别上传资源,请点击“资源”标签页上的 +(加号),选择导入文件,然后从本地机器上传文件。文件名应与 >ResourceURL< 元素匹配,但不含 java:// 前缀。

  2. 如果您希望某个资源可用于同一环境中的多个 API 代理,请将相应资源上传到该环境中。您需要使用 Edge API,如资源文件中所述。

    例如,从本地机器输入以下 API 调用,以在环境级别上传指定的文件:

    curl -v -u email -H "Content-Type: application/octet-stream" \
    -X POST --data-binary @{classes.jar} \
    "http://{mgmt_server}:{port}/v1/organizations/myorg/environments/myenv/resourcefiles?name=myresouce.jar&type=java"
    

    从文件所在的目录中发出 API 调用。

  3. 如需使文件可用于组织的所有环境内的所有 API 代理,您可以省略基本路径中的环境详细信息。例如:

    curl -v -u email -H "Content-Type: application/octet-stream" \
    -X POST --data-binary @{classes.jar} \
    "http://{mgmt_server}:{port}/v1/organizations/myorg/resourcefiles?name=myresouce.jar&type=java"