When you use Java for programming in Function Compute, you must define a Java function as a handler. This topic describes the structure and features of Java event functions.
Background information
Function Compute supports the Java 8 runtime environment. Unlike scripting languages such as Python and Node.js, Java code must be compiled before it can be run on a Java virtual machine (JVM). Therefore, Java has the following limits:
- No support for code upload: You can upload only developed and compiled ZIP packages or JAR packages. Function Compute does not support Java-based compilation.
- No support for online editing: You cannot edit code online because code cannot be uploaded. You can submit code only by uploading JAR packages or using Object Storage Service (OSS).
Event function handlers
When you use Java for programming, you must implement the predefined handlers provided by Function Compute. For event handler functions, the following two predefined handlers can be used:
-
This handler uses the Stream type to process the input
event
data and return the execution result. You must read the input data from input streams and then write the execution result to output streams. -
This handler uses the plain old Java object (POJO) type, which allows you to customize the input and output of the handler. Both the input and output must be of the POJO type.
StreamRequestHandler
The following code defines a simple handler function, which is an event function:
package example;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class HelloFC implements StreamRequestHandler {
@Override
public void handleRequest(
InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
outputStream.write(new String("hello world").getBytes());
}
}
- Package and class names
Java is different from other languages in execution methods due to its packages. The execution method in the sample code is
example.HelloFC::mainHandler
, whereexample
specifies the Java package,HelloFC
specifies the class, andmainHandler
specifies the class method.This method can be assigned arbitrary package and class names. However, the package and class names must match the Function Handler parameter that is used to create the function. In the preceding example, the package name is
example
, and the class name isHelloFC
. Therefore, the value of thehandler
parameter that is specified during function creation isexample.HelloFC::handleRequest
, which is in the format of{package}.{class}::{method}
. - Implemented handler
Your code must implement the predefined handlers provided by Function Compute. In the preceding example, the
StreamRequestHandler
is implemented. The inputStream parameter of the handler is the input parameter when you invoke a function and the outputStream parameter is used to return the execution result. - context parameter
The context parameter contains the runtime information of a function, such as the request ID and the temporary AccessKey pair. This parameter is of the
com.aliyun.fc.runtime.Context
type. - Return value
A function that implements the
StreamRequestHandler
returns the execution result by using theoutputStream
parameter. - Handler repository
The dependency of the
com.aliyun.fc.runtime
package can be referenced in the followingpom.xml
file:<dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-core</artifactId> <version>1.4.0</version> </dependency>
You can visit the Maven repository to obtain the latest version of the
fc-java-core
package.
fc-java-core
into a JAR package. For more information about how to compress the code and its dependency,
see Use custom modules.
hello world
code in the example is compressed into a JAR package. You can use the sample code package to conduct the test.
You can run the related commands provided by Serverless Devs to initialize, build, and deploy a project. You can perform the following steps:
Log on to the Function Compute console to view the status of the function and invoke the function.
PojoRequestHandler
The following code defines a simple handler function, which is a processing function: The object of SimpleRequest is an object that can be serialized into a JSON string, such as an object of the POJO type.
// HelloFC.java
package example;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.PojoRequestHandler;
public class HelloFC implements PojoRequestHandler<SimpleRequest, SimpleResponse> {
@Override
public SimpleResponse handleRequest(SimpleRequest request, Context context) {
String message = "Hello, " + request.getFirstName() + " " + request.getLastName();
return new SimpleResponse(message);
}
}
// SimpleRequest.java
package example;
public class SimpleRequest {
String firstName;
String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public SimpleRequest() {}
public SimpleRequest(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
// SimpleResponse.java
package example;
public class SimpleResponse {
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public SimpleResponse() {}
public SimpleResponse(String message) {
this.message = message;
}
}
Prepare an input file for invoking the function:
{
"firstName": "FC",
"lastName": "aliyun"
}
Use the context parameter
The context parameter is an object that is generated when Function Compute is running. It contains runtime information. You can use the information in your code. For more information about how to implement the context parameter, see fc-java-libs. The following example shows the definition of the context parameter:
package com.aliyun.fc.runtime;
public interface Context {
public String getRequestId();
public Credentials getExecutionCredentials();
public FunctionParam getFunctionParam();
public FunctionComputeLogger getLogger();
public Service getService();
}
The following table describes the fields contained in the context parameter.
Parameter | Description |
---|---|
RequestId | The unique ID of the request for invoking the function. You can record the ID for troubleshooting if an error occurs. |
Function | The basic information of the invoked function, such as the name, handler, memory, and timeout period of the function. |
Credentials | The temporary AccessKey pair that Function Compute obtains by assuming your service-linked role. The temporary AccessKey pair is valid for 5 minutes. You can use credentials in your code to access the related service such as OSS. This allows you not to write your AccessKey pair in the function code. For more information, see Grant permissions to a RAM user by using an Alibaba Cloud account. |
Logger | The logger encapsulated by Function Compute. |
Service | The basic information of the called service. |
The following sample code provides an example on how to upload an object to OSS by using a temporary AccessKey pair:
package example;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.Credentials;
import com.aliyun.fc.runtime.StreamRequestHandler;
import com.aliyun.oss.OSSClient;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class HelloFC implements StreamRequestHandler {
@Override
public void handleRequest(
InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
String endpoint = "oss-cn-shanghai.aliyuncs.com";
String bucketName = "my-bucket";
Credentials creds = context.getExecutionCredentials();
OSSClient client = new OSSClient(
endpoint, creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken());
client.putObject(bucketName, "my-object", new ByteArrayInputStream(new String("hello").getBytes()));
outputStream.write(new String("done").getBytes());
}
}