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. 标识环境和资源名称。您可以在错误消息中找到此信息。例如,在以下错误中,环境为 testResourceURL> 元素中使用的资源名称为 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 代理级别上传的所有资源。在此示例中,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. 标识环境和资源名称。您可以在错误消息中找到此信息。例如,在以下错误中,环境名称为 testResourceURL> 元素中使用的资源名称为 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 代理编辑器的“Navigator”窗格中的“Resources”标签页,然后点击资源旁边的“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. 如果重新上传资源不起作用,则受影响的消息处理器需要重启。如果您在 Cloud 中使用 Apigee Edge,请与 Apigee 支持团队联系。如果您是 Private Cloud 用户,请参阅启动、停止、重启和检查 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. 检查特定 JAR 文件是否已在 API 代理、组织或环境级别上传。如果 JAR 文件未上传到任何级别,请转到“解决方法”。
  3. 如果 JAR 文件已上传,请转到原因:JAR 文件损坏

分辨率

  1. 如果 JAR 文件已损坏或仅上传了部分内容,请重新构建 JAR 并在适当的级别(API 代理级别、组织级别或环境级别)上传 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. 检查 Message Processor 日志(/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"