Function Compute supports Java runtime environments of Java OpenJDK 1.8.0 (runtime = java8) and Java OpenJDK 11 (runtime = java11). This topic describes log generation, troubleshooting, and custom modules of the Java runtime environments.

Generate logs

Logs generated by using context.getLogger() are collected to the Logstore that you specify when you create the service.

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 {

        context.getLogger().info("hello world");
        outputStream.write(new String("hello world").getBytes());
    }
}

After the preceding code is executed, the following log entry is generated:

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

You can use context.getLogger().warn and context.getLogger().error to generate a WARN log entry and an ERROR log entry.

Troubleshooting

If an error occurs when Function Compute executes your function, Function Compute captures the error and returns a message.

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 {
        throw new IOException("oops");
    }
} 

When the function is invoked, the following response is returned:

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

When an error occurs, the HTTP header in the response contains X-Fc-Error-Type: UnhandledInvocationError.

For more information, see Terms.

Use custom modules

If you want to use custom modules, package them with the code when you create a JAR package. The following example demonstrates how to package OSS SDK for Java into a project. Java OpenJDK 1.8.0 (runtime = java8) is used in the example.

  1. Install Java and Maven.
    You can download SDK for Java applicable to your system at the official website and then install it. For more information about how to install Maven, see Installing Apache Maven.
  2. Create a Java project with the following directory structure.
    test/src/main/java/example/App.java       
  3. Enter the following content to the App.java file.
    package example;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import com.aliyun.fc.runtime.Context;
    import com.aliyun.fc.runtime.StreamRequestHandler;
    import com.aliyun.fc.runtime.FunctionInitializer;
    
    /**
     * Hello world!
     *
     */
    public class App implements StreamRequestHandler, FunctionInitializer {
    
        public void initialize(Context context) throws IOException {
        }
    
        public void handleRequest(
                InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
            outputStream.write(new String("hello world\n").getBytes());
        }
    }             
  4. In the root directory of the project folder, create a pom.xml file. In the pom.xml file, add a maven-assembly-plugin with the following content:
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>example</groupId>
      <artifactId>Java-example</artifactId>
      <packaging>jar</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>Java-example</name>
    
      <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.test.skip>true</maven.test.skip>
      </properties>
    <build>
      <plugins>
          <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <version>3.1.0</version>
              <configuration>
                  <descriptorRefs>
                      <descriptorRef>jar-with-dependencies</descriptorRef>
                  </descriptorRefs>
                  <appendAssemblyId>false</appendAssemblyId> <!-- this is used for not append id to the jar name -->
              </configuration>
              <executions>
                  <execution>
                      <id>make-assembly</id> <!-- this is used for inheritance merges -->
                      <phase>package</phase> <!-- bind to the packaging phase -->
                      <goals>
                          <goal>single</goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                  <source>1.8</source>
                  <target>1.8</target>
              </configuration>
          </plugin>
      </plugins>
      </build>
    </project>            
  5. To reference the external package of Maven Central for the project, add dependencies based on your needs. OSS SDK for Java is used in the example. The pom.xml has the following content:
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>example</groupId>
      <artifactId>Java-example</artifactId>
      <packaging>jar</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>Java-example</name>
    
      <dependencies>
        <dependency>
          <groupId>com.aliyun.fc.runtime</groupId>
          <artifactId>fc-java-core</artifactId>
          <version>1.3.0</version>
        </dependency>
        <dependency>
         <groupId>com.aliyun.oss</groupId>
         <artifactId>aliyun-sdk-oss</artifactId>
         <version>2.6.1</version>
       </dependency>
      </dependencies>
    
      <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.test.skip>true</maven.test.skip>
      </properties>
    <build>
      <plugins>
          <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <version>3.1.0</version>
              <configuration>
                  <descriptorRefs>
                      <descriptorRef>jar-with-dependencies</descriptorRef>
                  </descriptorRefs>
                  <appendAssemblyId>false</appendAssemblyId> <!-- this is used for not append id to the jar name -->
              </configuration>
              <executions>
                  <execution>
                      <id>make-assembly</id> <!-- this is used for inheritance merges -->
                      <phase>package</phase> <!-- bind to the packaging phase -->
                      <goals>
                          <goal>single</goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                  <source>1.8</source>
                  <target>1.8</target>
              </configuration>
          </plugin>
      </plugins>
      </build>
    </project>             
  6. In the project root directory, run the mvn package command to package the files. The following sample code shows the compilation output:
    $mvn package
    [INFO] Scanning for projects...
     ...  ....   ....
    [INFO] --------------------------< example:example >---------------------------
    [INFO] Building Java-example 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
     ...  ....   ....
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  11.681 s
    [INFO] Finished at: 2020-03-26T15:55:05+08:00
    [INFO] ------------------------------------------------------------------------          

    If the message shows that compilation failed, modify the code based on the error message.

    The compiled JAR package is in the target directory of the project folder and is named as Java-example-1.0-SNAPSHOT.jar based on the artifactId and version fields in pom.xml.

  7. Upload a JAR package in the Function Compute console.
    1. Log on to the Function Compute console.
    2. In the top navigation bar, select the region where your Function Compute service is located.
    3. Find the function in the service and click the name of the function.
    4. On the Code tab, select Import from OSS or Upload Zip File to upload the JAR package.

You can also use maven-shade-plugin to package the files. The preceding package methods can meet the needs in most scenarios. If you want to package JAR packages that are not managed by Maven, such as JAR packages in other non-Maven repositories that you reference in resources/lib, you can use maven-jar-plugin and maven-dependency-plugin to package the JAR packages into the final JAR package.

Use IntelliJ IDEA to install dependencies, and then compress and upload the dependencies

  1. Create a local Java project. The pom.xml file contains the following content:
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>example</groupId>
      <artifactId>Java-example</artifactId>
      <packaging>jar</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>Java-example</name>
      <dependencies>
        <dependency>
          <groupId>com.aliyun.fc.runtime</groupId>
          <artifactId>fc-java-core</artifactId>
          <version>1.3.0</version>
        </dependency>
        <dependency>
         <groupId>com.aliyun.oss</groupId>
         <artifactId>aliyun-sdk-oss</artifactId>
         <version>2.6.1</version>
       </dependency>
      </dependencies>
    </project>       
  2. Use IntelliJ IDEA to export JAR package configurations.
    1. Choose File > Project Structure.
      export jar
    2. In the dialog box that appears, choose Artifacts > + > JAR > From modules with dependencies.
      choose from modules with dependencies
    3. In the dialog box that appears, use the default configuration and click OK.
      ok
    4. In the top navigation bar of IntelliJ IDEA, choose Build > Build Artifacts, and then click Build or Rebuild to generate a JAR package.
      build
  3. You can upload the JAR package from out/artifacts/example_jar of the project root directory to Function Compute. In the Function Compute console, click the Code tab, and then select Import from OSS or Upload Zip File to upload the exported JAR package.

Use FunCraft to package project files

If you use FunCraft to deploy an application, you can run the fun install command to create the application.

  1. In the root directory of the project, create a template.yml with the following content:
    ROSTemplateFormatVersion: '2015-09-01'
    Transform: 'Aliyun::Serverless-2018-04-03'
    Resources:
      JavaDemo:
        Type: 'Aliyun::Serverless::Service'
        Properties:
          Description: 'helloworld'
        test:
          Type: 'Aliyun::Serverless::Function'
          Properties:
            Handler: example.App::handleRequest
            Initializer: example.App::initialize
            Runtime: java8
            CodeUri: './'               
  2. Run the following command to package the project files:
    fun build             
    A similar output is displayed.
    using template: template.yml
    start building function dependencies without docker
    
    building JavaDemo/test
    running task flow MavenTaskFlow
    running task: MavenCompileTask
    running task: MavenCopyDependencies
    running task: CopyMavenArtifacts
    
    Build Success
    
    Built artifacts: .fun/build/artifacts
    Built template: .fun/build/artifacts/template.yml
    
    Tips for next step
    ======================
    * Invoke Event Function: fun local invoke
    * Invoke Http Function: fun local start
    * Deploy Resources: fun deploy  
  3. Run the following command to deploy the function:
    fun deploy -y              
    A similar output is displayed.
    using template: .fun/build/artifacts/template.yml
    using region: cn-qingdao
    using accountId: ***********3743
    using accessKeyId: ***********Ptgk
    using timeout: 60
    
    Collecting your services information, in order to caculate devlopment changes...
    
    Resources Changes(Beta version! Only FC resources changes will be displayed):
    
    ***********
    
    Waiting for service JavaDemo to be deployed...
            Waiting for function test to be deployed...
                    Waiting for packaging function test code...
                    The function test has been packaged. A total of 3 files were compressed and the final size was 330.35 KB
            function test deploy success
    service JavaDemo deploy success  

Result

Log on to the . The related service and function are displayed. If you click Invoke on the Code tab, the correct results are returned.