
# Java函数开发指南（使用IDEA工具创建maven工程）
本章节介绍使用IDEA工具创建maven工程开发Java函数。关于Java函数接口定义、Initializer入口介绍以及SDK接口说明请参考[Java函数开发概述](https://support.huaweicloud.com/devg-functiongraph/functiongraph_02_0430.html)。
#### 操作流程
您可以跟随本文以下步骤从头开始创建Java工程和Java函数，也可以直接下载Java的[maven样例工程包](https://support.huaweicloud.com/devg-functiongraph/functiongraph_02_0101.html#functiongraph_02_0101__section3825924414326)并从[步骤二：创建Java函数并测试]开始操作。
 #### 步骤一：使用IDEA创建maven工程
1. 创建函数工程
   如[图1]所示配置IDEA，创建maven工程。
   图1创建工程   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000002408891577.png "点击放大") 
2. 添加工程依赖 根据[Java SDK下载](https://function-community.obs.cn-north-1.myhuaweicloud.com/sdk/java/fss-java-sdk-2.0.5.zip)提供的SDK地址，下载JavaRuntime SDK到本地开发环境解压，如[图2]所示。
   图2下载SDK解压   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000001522218636.png)
   1. 将zip中的"Runtime-2.0.5.jar"拷贝到本地目录，例如d:\\\\runtime中，在命令行窗口执行如下命令安装到本地的maven仓库中。
      ```
      mvn install:install-file -Dfile=d:\runtime\RunTime-2.0.5.jar -DgroupId=RunTime -DartifactId=RunTime -Dversion=2.0.5 -Dpackaging=jar
      ```
      
   
   2. 在pom.xml中配置dependency，如下所示。
      ```
      <dependency>
      <groupId>Runtime</groupId>
      <artifactId>Runtime</artifactId>
      <version>2.0.5</version>
      </dependency>
      ```
      
   
   3. 配置其他的依赖包，以obs依赖包为例，如下所示。
      ```
      <dependency>
      <groupId>com.huaweicloud</groupId>
      <artifactId>esdk-obs-java</artifactId>
      <version>3.21.4</version>
      </dependency>
      ```
      
   
   4. 在pom.xml中添加插件用来将代码和依赖包打包到一起。**请把mainClass替换为真实的类。**
      ```
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.huawei.demo.TriggerTests</mainClass>
                </manifest>
              </archive>
              <finalName>${project.name}</finalName>
            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals><goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      ```
      
    
3. 配置函数资源
   创建包com.huawei.demo，并在包下创建TriggerTests类，如[图3]所示。
   图3创建TriggerTests类   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000001407243738.png "点击放大") 
4. 配置函数代码
   在TriggerTests.java中定义函数运行入口，示例代码如下：
   ```
   package com.huawei.demo;
   import java.io.UnsupportedEncodingException;
   import java.util.HashMap;
   import java.util.Map;
   import com.huawei.services.runtime.Context;
   import com.huawei.services.runtime.entity.apig.APIGTriggerEvent;
   import com.huawei.services.runtime.entity.apig.APIGTriggerResponse;
   import com.huawei.services.runtime.entity.dis.DISTriggerEvent;
   import com.huawei.services.runtime.entity.dms.DMSTriggerEvent;
   import com.huawei.services.runtime.entity.lts.LTSTriggerEvent;
   import com.huawei.services.runtime.entity.smn.SMNTriggerEvent;
   import com.huawei.services.runtime.entity.timer.TimerTriggerEvent;
   import com.huawei.services.runtime.entity.eventgrid.EventGridTriggerEvent;
   public class TriggerTests {
       public APIGTriggerResponse apigTest(APIGTriggerEvent event, Context context){
           System.out.println(event);
           Map<String, String> headers = new HashMap<String, String>();
           headers.put("Content-Type", "application/json");
           return new APIGTriggerResponse(200, headers, event.toString());
       }
       public String smnTest(SMNTriggerEvent event, Context context){
           System.out.println(event);
           return "ok";
       }
       public String dmsTest(DMSTriggerEvent event, Context context){
           System.out.println(event);
           return "ok";
       }
       public String timerTest(TimerTriggerEvent event, Context context){
           System.out.println(event);
           return "ok";
       }
       public String disTest(DISTriggerEvent event, Context context) throws UnsupportedEncodingException{
           System.out.println(event);
           System.out.println(event.getMessage().getRecords()[0].getRawData());
           return "ok";
       }
       public String ltsTest(LTSTriggerEvent event, Context context) throws UnsupportedEncodingException {
           System.out.println(event);
           event.getLts().getData();
           System.out.println("raw data: " + event.getLts().getRawData());
           return "ok";
       }
       public String eventgridTest(EventGridTriggerEvent event, Context context){
           System.out.println(event);return "ok";
       }
   }
   ```
   示例代码中添加了多个入口函数，分别使用了不同的触发器事件类型，可通过FunctionGraph控制台修改函数执行入口测试不同的入口函数。**当函数的事件源是APIG时，相关约束条件请参考** **[Base64解码和返回结构体的说明](https://support.huaweicloud.com/devg-functiongraph/functiongraph_02_0102.html#functiongraph_02_0102__li176282148442)** **。**
   ![](https://support.huaweicloud.com/devg-functiongraph/public_sys-resources/note_3.0-zh-cn.png)
   **修改函数执行入口：**
   在FunctionGraph控制台左侧导航栏选择"函数 \> 函数列表"，单击需要设置的"函数名称"进入函数详情页，选择"设置 \> 常规设置"，配置"函数执行入口"参数，如[图4]所示。
   图4函数执行入口   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000002232783648.png "点击放大") 
5. 工程编译打包 在命令行窗口执行如下命令进行编译打包。编译完成后在target目录会生成一个"xx-jar-with-dependencies.jar"文件。
   ```
   mvn package assembly:single
   ```
   
 
 #### 步骤二：创建Java函数并测试
1. 登录[函数工作流控制台](https://console.huaweicloud.com/functiongraph/?locale=zh-cn)，左侧导航栏选择"函数 \> 函数列表"，单击右上角"创建函数"进入创建函数页面，选择"创建空白函数"。
2. 如[图5]所示，配置函数基本信息，配置完成后单击右下角"创建函数"完成创建。
   图5创建Java函数   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000002408892753.png "点击放大")
   
   
3. 进入函数详情页，在"代码"页签下，单击右侧"上传代码 \> JAR文件 "，添加[步骤一：使用IDEA创建maven工程]的JAR文件上传。
4. 上传成功后，选择"设置 \> 常规设置"，修改需要测试的函数执行入口参数，单击"保存"。
5. 回到"代码"页签，单击代码编辑区的"测试"，选择"创建新的测试事件"，在云事件模板列表中选择需要测试的事件模板，单击"创建"。
6. 单击"测试"，查看函数执行结果。 函数执行结果分为三部分，分别为函数返回（由callback返回）、执行摘要、日志输出（由console.log或getLogger()方法获取的日志方法输出），参考[表1]查看结果说明。
    表1执行结果说明 
   | 参数项  | 执行成功                          | 执行失败                                                                                                                                                                                                                            |
   |:---|:---|:---|
   | 函数返回 | 返回函数中定义的返回信息。                 | 返回包含错误信息和堆栈异常报错信息的JSON文件。格式如下： ``` { "errorMessage": "", "stackTrace": [] } ``` errorMessage：Runtime返回的错误信息 stackTrace：Runtime返回的堆栈异常报错信息 |
   | 执行摘要 | 显示请求ID、配置内存、执行时长、实际使用内存和收费时长。 | 显示请求ID、配置内存、执行时长、实际使用内存和收费时长。                                                                                                                                                                                                   |
   | 日志   | 打印函数日志，最多显示4KB的日志。            | 打印报错信息，最多显示4KB的日志。                                                                                                                                                                                                              |
      
   ![](https://support.huaweicloud.com/devg-functiongraph/public_sys-resources/note_3.0-zh-cn.png)
   如需测试示例代码中的其他事件源触发器，例如SMN事件源，可在函数的常规设置中，将函数执行入口修改为com.huawei.demo.TriggerTests.smnTest，并参考以上步骤，创建新的消息通知服务SMN测试事件进行函数测试。
   
 
