在 IDEA 中配置 Server 开发环境

注意:下述配置仅供参考,基于这个版本,在 Linux 和 macOS 平台下进行了测试。

背景

Quick Start 部分已经介绍了使用脚本启停 HugeGraph-Server 的流程。下面以 Linux 平台为例,介绍使用 IntelliJ IDEA 运行与调试 HugeGraph-Server 的流程。

本地启动的核心与脚本启动是一样的:

  1. 初始化数据库后端,执行 InitStore 类初始化图
  2. 启动 HugeGraph-Server,执行 HugeGraphServer 类加载初始化的图信息启动

在执行下述流程之前,请确保已经克隆了 HugeGraph 的源代码,并且已经配置了 JDK 11 等开发环境。

git clone https://github.com/apache/hugegraph.git

步骤

1. 配置文件拷贝

为了避免配置文件的更改影响 Git 的追踪,建议将所需的配置文件拷贝到一个单独的文件夹中:

cp -r hugegraph-dist/src/assembly/static/scripts hugegraph-dist/src/assembly/static/conf path-to-your-directory

path-to-your-directory 替换为你创建的文件夹的路径。

2. InitStore 类初始化图

首先,需要在配置文件中配置数据库后端。以 RocksDB 为例,在 path-to-your-directory/conf/graphs/hugegraph.properties 文件中进行以下配置:

backend=rocksdb
serializer=binary
rocksdb.data_path=.
rocksdb.wal_path=.

然后,打开 IntelliJ IDEA 的 Run/Debug Configurations 面板,创建一个新的 Application 配置,按照以下步骤进行配置:

  • Use classpath of module 中选择 hugegraph-dist
  • Main class 设置为 org.apache.hugegraph.cmd.InitStore
  • 设置运行参数为 conf/rest-server.properties,这里的路径是相对于工作路径的,需要将工作路径设置为 path-to-your-directory

若在 Java 11 环境下为 HugeGraph-Server 配置了用户认证 (authenticator),需要参考二进制包的脚本配置,添加下述 VM options:

--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED

否则会报错:

java.lang.reflect.InaccessibleObjectException: Unable to make public static synchronized void jdk.internal.reflect.Reflection.registerFieldsToFilter(java.lang.Class,java.lang.String[]) accessible: module java.base does not "exports jdk.internal.reflect" to unnamed module @xxx

配置完成后运行,如果运行成功,将会输出以下类似运行日志:

2023-06-05 00:43:37 [main] [INFO] o.a.h.u.ConfigUtil - Scanning option 'graphs' directory './conf/graphs'
2023-06-05 00:43:37 [main] [INFO] o.a.h.c.InitStore - Init graph with config file: ./conf/graphs/hugegraph.properties
......
2023-06-05 00:43:39 [main] [INFO] o.a.h.b.s.r.RocksDBStore - Write down the backend version: 1.11
2023-06-05 00:43:39 [main] [INFO] o.a.h.StandardHugeGraph - Graph 'hugegraph' has been initialized
2023-06-05 00:43:39 [main] [INFO] o.a.h.StandardHugeGraph - Close graph standardhugegraph[hugegraph]
2023-06-05 00:43:39 [db-open-1] [INFO] o.a.h.b.s.r.RocksDBStore - Opening RocksDB with data path: ./m
2023-06-05 00:43:39 [db-open-1] [INFO] o.a.h.b.s.r.RocksDBStore - Opening RocksDB with data path: ./s
2023-06-05 00:43:39 [db-open-1] [INFO] o.a.h.b.s.r.RocksDBStore - Opening RocksDB with data path: ./g
2023-06-05 00:43:39 [main] [INFO] o.a.h.HugeFactory - HugeFactory shutdown
2023-06-05 00:43:39 [hugegraph-shutdown] [INFO] o.a.h.HugeFactory - HugeGraph is shutting down

3. 运行 HugeGraphServer

类似地,打开 IntelliJ IDEA 的 Run/Debug Configurations 面板,创建一个新的 Application 配置,按照以下步骤进行配置:

  • Use classpath of module 中选择 hugegraph-dist
  • Main class 设置为 org.apache.hugegraph.dist.HugeGraphServer
  • 设置运行参数为 conf/gremlin-server.yaml conf/rest-server.properties,同样地,这里的路径是相对于工作路径的,需要将工作路径设置为 path-to-your-directory

类似的,若在 Java 11 环境下为 HugeGraph-Server 配置了用户认证 (authenticator),同样需要参考二进制包的脚本配置,添加下述 VM options:

--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED --add-modules=jdk.unsupported --add-exports=java.base/sun.nio.ch=ALL-UNNAMED

否则会报错:

java.lang.reflect.InaccessibleObjectException: Unable to make public static synchronized void jdk.internal.reflect.Reflection.registerFieldsToFilter(java.lang.Class,java.lang.String[]) accessible: module java.base does not "exports jdk.internal.reflect" to unnamed module @xxx

配置完成后运行,如果看到以下类似日志,表示 HugeGraphServer 已经成功启动:

......
2023-06-05 00:51:56 [gremlin-server-boss-1] [INFO] o.a.t.g.s.GremlinServer - Gremlin Server configured with worker thread pool of 1, gremlin pool of 8 and boss thread pool of 1.
2023-06-05 00:51:56 [gremlin-server-boss-1] [INFO] o.a.t.g.s.GremlinServer - Channel started at port 8182.

4. 调试 HugeGraphServer (可选)

在完成上述配置后,可以尝试对 HugeGraphServer 进行调试。在调试模式下运行 HugeGraphServer,并在以下位置设置断点:

public String list(@Context GraphManager manager,
                   @PathParam("graph") String graph, @QueryParam("label") String label,
                   @QueryParam("properties") String properties, ......) {
    // ignore log
    Map<String, Object> props = parseProperties(properties);

然后,使用 RESTful API 请求 HugeGraphServer

curl "http://localhost:8080/graphs/hugegraph/graph/vertices" | gunzip

此时,可以在调试器中查看详细的变量信息。

5. Log4j2 日志配置

默认情况下,运行 InitStoreHugeGraphServer 时,读取的 Log4j2 配置文件路径为 hugegraph-dist/src/main/resources/log4j2.xml,而不是 path-to-your-directory/conf/log4j2.xml,这个配置文件是使用脚本启动 HugeGraph-Server 时读取的。

为了避免同时维护两份配置文件,可以考虑在 IntelliJ IDEA 运行与调试 HugeGraph-Server 时,修改读取的 Log4j2 配置文件路径:

  1. 打开之前创建的 Application 配置
  2. 点击 Modify options - Add VM options
  3. 设置 VM options 为 -Dlog4j.configurationFile=conf/log4j2.xml

可能遇到的问题

1. java: package sun.misc does not exist

原因可能是在使用 Java 11 编译时触发了交叉编译,导致项目中使用的 sun.misc.Unsafe 找不到符号。有两种解决方案可供选择:

  1. 在 IntelliJ IDEA 的 Preferences/Settings 中找到 Java Compiler 面板,然后关闭 --release 选项 (推荐)
  2. 或者将项目的 SDK 版本设置为 8 (Deprecated soon)

2. Log4j2 日志无法打印 %l 等位置信息

这是因为 Log4j2 中使用了 asynchronous loggers,可以参考官方文档进行配置


参考
  1. HugeGraph-Server Quick Start
  2. hugegraph-server 本地调试文档 (Win/Unix)
  3. “package sun.misc does not exist” compilation error
  4. Cannot compile: java: package sun.misc does not exist