全部产品

Java 运行环境

更新时间:2019-05-07 16:02:40

函数计算目前支持以下 Java 运行环境:

  • OpenJDK 1.8.0 (runtime = java8)

对于 Java 运行环境的基本使用请参考Java 函数入口。以下将介绍 Java 运行环境相关特性:

使用context

context 是函数计算在运行时生成的一个对象,其中包含一些运行时的信息,用户在代码中可以使用这些信息。其定义如下,具体实现可以在 这里 找到:

  1. package com.aliyun.fc.runtime;
  2. public interface Context {
  3. public String getRequestId();
  4. public Credentials getExecutionCredentials();
  5. public FunctionParam getFunctionParam();
  6. public FunctionComputeLogger getLogger();
  7. }

可以看到 context 中包含了4个信息:

  1. RequestId: 本次调用请求的唯一 id,用户可以把它记录下来在出现问题的时候方便调查
  2. FunctionParam: 当前调用的函数的一些基本信息如函数名/函数入口/函数内存/超时时间
  3. ExecutionCredentials: 函数计算服务通过扮演用户提供的 服务角色获得的一组临时密钥,其有效时间是 5 分钟。用户可以在代码中使用它去访问相应的服务(例如 OSS),这就避免了用户把自己的 AK 信息写死在函数代码里。
  4. Logger: 函数计算封装过的 logger,见下面的 使用logging

例如下面的代码使用临时密钥,向 OSS 中上传了一个文件:

  1. package example;
  2. import com.aliyun.fc.runtime.Context;
  3. import com.aliyun.fc.runtime.Credentials;
  4. import com.aliyun.fc.runtime.StreamRequestHandler;
  5. import com.aliyun.oss.OSSClient;
  6. import java.io.ByteArrayInputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.io.OutputStream;
  10. public class HelloFC implements StreamRequestHandler {
  11. @Override
  12. public void handleRequest(
  13. InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
  14. String endpoint = "oss-cn-shanghai.aliyuncs.com";
  15. String bucketName = "my-bucket";
  16. Credentials creds = context.getExecutionCredentials();
  17. OSSClient client = new OSSClient(
  18. endpoint, creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken());
  19. client.putObject(bucketName, "my-object", new ByteArrayInputStream(new String("hello").getBytes()));
  20. outputStream.write(new String("done").getBytes());
  21. }
  22. }

使用logging

用户的函数通过 context.getLogger() 打印的内容会被收集到用户在创建 Service 时指定的 LogStore 中:

  1. package example;
  2. import com.aliyun.fc.runtime.Context;
  3. import com.aliyun.fc.runtime.StreamRequestHandler;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. public class HelloFC implements StreamRequestHandler {
  8. @Override
  9. public void handleRequest(
  10. InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
  11. context.getLogger().info("hello world");
  12. outputStream.write(new String("hello world").getBytes());
  13. }
  14. }

上面的代码输出的日志内容是:

  1. message:2017-07-05T05:13:35.920Z a72df088-f738-cee3-e0fe-323ad89118e5 [INFO] hello world

使用 context.getLogger().warncontext.getLogger().error 分别可以打包 WARN/ERROR 级别的日志。

使用自定义的模块

如果用户需要使用自定义的模块,则需要在打包 jar 时,将它们与代码一起打包。以下演示如何将 OSS Java SDK 打包到项目中。

  1. 在 pom.xml 中添加 OSS java SDK:

    1. <dependencies>
    2. <dependency>
    3. <groupId>com.aliyun.fc.runtime</groupId>
    4. <artifactId>fc-java-core</artifactId>
    5. <version>1.2.1</version>
    6. </dependency>
    7. <dependency>
    8. <groupId>com.aliyun.oss</groupId>
    9. <artifactId>aliyun-sdk-oss</artifactId>
    10. <version>2.6.1</version>
    11. </dependency>
    12. </dependencies>
  2. 执行通用打包流程

    请参考 Java 代码打包

错误处理

用户的函数在执行过程如果抛出异常,那么函数计算会把异常捕获并将异常信息返回。例如下面的代码:

  1. package example;
  2. import com.aliyun.fc.runtime.Context;
  3. import com.aliyun.fc.runtime.StreamRequestHandler;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. public class HelloFC implements StreamRequestHandler {
  8. @Override
  9. public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
  10. throw new IOException("oops");
  11. }
  12. }

调用时收到的响应为:

  1. >>> invk hello-java -f /tmp/a.json
  2. {
  3. "errorMessage" : "oops",
  4. "errorType" : "java.io.IOException",
  5. "errorCause" : "oops",
  6. "stackTrace" : [ "example.HelloFC.handleRequest(HelloFC.java:15)" ]
  7. }
  8. Error: Request id: 45dd8d90-6b78-cce3-087c-8bf4ebc6c9af. Error type: UnhandledInvocationError

发生异常时,函数调用的响应的HTTP header中会包含X-Fc-Error-Type: UnhandledInvocationError