Ubuntu 22.04 安装 Apache Jackrabbit 2.22.5 指南

在 Ubuntu 22.04 上从零安装 Apache Jackrabbit 2.22.5(standalone 可执行 jar),实测配置 JDK 17/JAVA_HOME、修正 persistence 配置、启动 8080 服务并通过 WebDAV 与 JCR API 创建 workspace 与内容节点。

Apache JackrabbitApache Jackrabbit安装部署数据库ApacheUbuntu 22.042026/10/11

Ubuntu 22.04 安装 Apache Jackrabbit 2.22.5 指南

目标:在 Ubuntu 22.04 上从 0 到 1 完整部署 Apache Jackrabbit 2.22.5(JSR-283/JSR-333 JCR 内容仓库的 Java 实现),开通 8080 端口的 HTTP 服务,并在 WebDAV 与 JCR 客户端里实测创建 workspace 与内容节点。全部命令与回显均在真实 Ubuntu 22.04.5 LTS 环境实测通过(JDK 17,路径 /opt/apache-jackrabbit/、/opt/data/jackrabbit/)。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(Linux x86_64)
  • JDK:OpenJDK 17.0.20.1(java-17-openjdk-amd64),JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
  • Apache Jackrabbit:2.22.5(standalone 版 jackrabbit-standalone-2.22.5.jar,Java 可执行 jar)
  • 服务监听:HTTP 0.0.0.0:8080
  • 安装目录:/opt/apache-jackrabbit/
  • 仓库数据目录:/opt/data/jackrabbit/
  • 仓库配置文件:/opt/apache-jackrabbit/conf/repository.xml(实测改名为 repository-fs.xml 使用文件持久化)
  • HTTP 端点:/server/*(JCR Remoting,即 davE)、/repository/*(WebDAV)
  • 演示管理账号:admin / q1w2e3r4

⚠️ 注意:Apache Jackrabbit 与 Apache Jackrabbit Oak(jackrabbit-oak)是两个独立发行线。本文只讲经典 Jackrabbit 核心(jackrabbit-core,2.x standalone);Oak 属下一代内容仓库实现,见「三、版本选型说明」。

二、前置条件

  1. Ubuntu 22.04 真机,具备 root 权限,可访问外网(需从 downloads.apache.org / archive.apache.org 下载软件包)。
  2. 服务器尚未安装 JDK。先更新软件源并安装 JDK 17:
# 使用 root 或 sudo 执行
apt-get update

# 安装 OpenJDK 17(Jackrabbit 2.22.x 官方以 JDK 8/11/17 构建,此处用 17)
apt-get install -y openjdk-17-jdk-headless
  1. 校验 Java 版本:
java -version

实测回显如下:

openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
  1. 定位 JDK 安装路径并写入环境变量(standalone jar 通过 java -jar 运行,JAVA_HOME 供定义 JDK 路径使用)。自动探测路径:
JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
echo "JAVA_HOME=$JAVA_HOME"

实测回显:

JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64

如需持久化,追加到 /etc/environment:

echo 'JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> /etc/environment
echo 'PATH=/usr/lib/jvm/java-17-openjdk-amd64/bin:$PATH' >> /etc/profile.d/java.sh

WebDAV 客户端测试依赖 curl 与解压工具(可选):

apt-get install -y curl unzip

💡 说明:本指南下载使用 curl,若偏好 wget 可先 apt-get install -y wget 后再用 wget <同 URL> 命令,二者等效。

三、版本选型说明

3.1 两个发行线的选择

Apache Jackrabbit 生态有两条主线,部署前务必区分:

主线组件坐标GAV 坐标场景
经典 Jackrabbitjackrabbit-core / jackrabbit-standaloneorg.apache.jackrabbit:jackrabbit-standaloneJCR 1.0/2.0 规范的标准实现,轻量、单仓库,适合作为进程内内容仓库或独立 HTTP 服务
Jackrabbit Oakapache-jackrabbit-oakorg.apache.jackrabbit:oak-*下一代内容仓库,面向大规模/集群/高并发场景,是 Adobe Experience Manager(AEM) 的存储层,部署方式是打进应用/独立服务

本系列安装指南使用经典 Jackrabbit 2.x standalone。它和你可能听过的「Oak」不是同一个东西,不要混用配置与 jar。

3.2 版本获取方法

到 Apache 官方发行目录查看当前最新稳定版: https://downloads.apache.org/jackrabbit/

实测列出的 2.x 发行版有 2.20.18/、2.22.5/(当前稳定版)、2.23.6-beta/(预发布),及 oak/(下一代 Oak 的家长目录)。本文以稳定版 2.22.5 为例。2.20 起 standalone 文件命名去掉了 apache- 前缀,即 jackrabbit-standalone-<ver>.jar。

四、下载与目录规划

创建目录并下载官方 standalone jar:

mkdir -p /opt/apache-jackrabbit
cd /opt/apache-jackrabbit

curl -fsSL -o jackrabbit-standalone-2.22.5.jar \
  https://downloads.apache.org/jackrabbit/2.22.5/jackrabbit-standalone-2.22.5.jar

ls -la jackrabbit-standalone-2.22.5.jar

实测回显:

-rw-r--r-- 1 root root 104497574 Oct 11 11:09 jackrabbit-standalone-2.22.5.jar

校验文件完整性(SHA-512,对 jackrabbit-standalone-2.22.5.jar):

sha512sum jackrabbit-standalone-2.22.5.jar

实测回显:

89836e498555b7d9378ed6df1c2d5a7cf1765b5c6972eaf8098886465af46536f20715cc2877e355c9498ac341e1d2102840a07e538822a42280a376334e149a  jackrabbit-standalone-2.22.5.jar

确认它是可执行 jar(Main-Class 为 org.apache.jackrabbit.standalone.Main):

unzip -p jackrabbit-standalone-2.22.5.jar META-INF/MANIFEST.MF | grep -i main-class

实测回显:

Main-Class: org.apache.jackrabbit.standalone.Main

准备仓库数据目录:

mkdir -p /opt/data/jackrabbit

五、部署步骤

5.1 抽取仓库配置文件(repository.xml)

standalone jar 内置默认 repository.xml,先抽取到 conf/ 目录以便后续配置:

cd /opt/apache-jackrabbit
mkdir -p conf
unzip -o jackrabbit-standalone-2.22.5.jar \
  org/apache/jackrabbit/core/repository.xml -d conf/
mv conf/org/apache/jackrabbit/core/repository.xml conf/repository.xml
rm -rf conf/org

ls -la conf/

5.2 修正 persistence 配置(关键)

⚠️ 首次直接用默认配置启动会失败:默认 repository.xml 的 workspace 与 version 均使用 DerbyPersistenceManager(内嵌 Apache Derby JDBC 库),而 jackrabbit-standalone-2.22.5.jar 并没有把 Derby 驱动打进 fat jar,启动时会报:

javax.jcr.RepositoryException: Could not load JDBC driver class org.apache.derby.jdbc.EmbeddedDriver
...
Caused by: java.lang.ClassNotFoundException: org.apache.derby.jdbc.EmbeddedDriver

解决办法:把两处 DerbyPersistenceManager 换成基于文件系统的 BundleFsPersistenceManager(纯磁盘存储,无需任何 JDBC 驱动),并删掉只对 Derby 生效的 url / schemaObjectPrefix 参数。生成新配置 conf/repository-fs.xml:

cd /opt/apache-jackrabbit/conf
cp repository.xml repository-fs.xml

# 两处(workspace persistence + version persistence)统一替换
sed -i \
  's|org.apache.jackrabbit.core.persistence.pool.DerbyPersistenceManager|org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager|g' \
  repository-fs.xml

# 删除 Derby 专属参数
sed -i '/<param name="url" value="jdbc:derby:/d' repository-fs.xml
sed -i '/<param name="schemaObjectPrefix" value=/d' repository-fs.xml

校验改动(应只剩两处 PersistenceManager 类名变更为 BundleFsPersistenceManager,且不再有 Derby/build 字样):

diff repository.xml repository-fs.xml

核心差异(节选):

99,101c99
< <PersistenceManager class="org.apache.jackrabbit.core.persistence.pool.DerbyPersistenceManager">
<   <param name="url" value="jdbc:derby:${wsp.home}/db;create=true"/>
<   <param name="schemaObjectPrefix" value="${wsp.name}_"/>
---
> <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">

5.3 启动 Jackrabbit 服务

💡 先看 standalone 的完整用法:java -jar jackrabbit-standalone-2.22.5.jar --help

usage: java -jar jackrabbit-standalone-2.22.5.jar [-?] [-b] [-c <arg>] [-C
       <arg>] [-d] [-f <arg>] [-h <arg>] [-i <arg>] [-l] [-n] [-p <arg>]
       [-q] [-r <arg>] [-R <arg>]
 -?,--help                print this message
 -b,--backup              create a backup of the repository
 -c,--conf <arg>          repository configuration file
 -C,--backup-conf <arg>   backup repository configuration file
 -d,--debug               enable debug logging
 -f,--file <arg>          location of this jar file
 -h,--host <arg>          IP address of the HTTP server
 -i,--cli <arg>           command line access to a remote repository
 -l,--license             print license information
 -n,--notice              print copyright notices
 -p,--port <arg>          TCP port of the HTTP server (8080)
 -q,--quiet               disable console output
 -r,--repo <arg>          repository directory (jackrabbit)
 -R,--backup-repo <arg>   backup repository directory (jackrabbit-backupN)

常用启动参数:-c 指定 repository.xml、-r 指定仓库数据目录、-p 端口(默认 8080)、-h 绑定地址。

前台直接启动(便于观察,Ctrl+C 停止):

cd /opt/apache-jackrabbit
JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
$JAVA_HOME/bin/java -jar jackrabbit-standalone-2.22.5.jar \
  -c /opt/apache-jackrabbit/conf/repository-fs.xml \
  -r /opt/data/jackrabbit

后台启动并把日志写入 /tmp/jr.log:

cd /opt/apache-jackrabbit
nohup $JAVA_HOME/bin/java -jar jackrabbit-standalone-2.22.5.jar \
  -c /opt/apache-jackrabbit/conf/repository-fs.xml \
  -r /opt/data/jackrabbit > /tmp/jr.log 2>&1 &

启动日志(实测回显):

Using repository directory /opt/data/jackrabbit
Writing log messages to /opt/data/jackrabbit/log
Welcome to Apache Jackrabbit!
-------------------------------
Starting the server...
Apache Jackrabbit is now running at http://localhost:8080/

运行级日志在 /opt/data/jackrabbit/log/jackrabbit.log(含各 servlet 初始化、Started ServerConnector ... 0.0.0.0:8080)。首次启动会自动创建 repository/、workspaces/、version/、tmp/、log/ 等目录。

5.4 验证服务与端点

# 仓库概览(davE 端点,列出所有 workspace,即本版本的「管理台」入口)
curl -s -u admin:q1w2e3r4 http://localhost:8080/server/

实测回显(工作区含默认自带两个 + 后续新建的 ws_demo):

<html><head><title>Jackrabbit 2.22.5</title></head><body><h2>Jackrabbit
2.22.5</h2><h3>Available Workspace Resources:</h3><ul><li><a
href="http://localhost:8080/server/default/">default</a></li><li><a
href="http://localhost:8080/server/security/">security</a></li><li><a
href="http://localhost:8080/server/ws_demo/">ws_demo</a></li></ul>
<hr size="1"><em>Powered by <a
href="http://jackrabbit.apache.org/">Jackrabbit</a> 2.22.5</em></body></html>

默认监听端口回显(访问日志 access.log.<日期>):

127.0.0.1 - - [11/Oct/2026:11:14:37 +0000] "PROPFIND /repository/default/ HTTP/1.1" 207 1505 "-" "curl/7.81.0"

5.5 实测创建 workspace 与内容节点

Jackrabbit 内容节点可通过 WebDAV(/repository/*)或 JCR API 创建;workspace 通过 JCR Workspace.createWorkspace() 创建。

A. WebDAV 创建内容节点

创建存放文件记录的集合(MKCOL):

curl -i -X MKCOL -u admin:q1w2e3r4 \
  http://localhost:8080/repository/default/mydocs

实测回显:

HTTP/1.1 201 Created
Date: Sun, 11 Oct 2026 11:14:42 GMT
Content-Length: 0

向集合写入一个文本资源(PUT,等价创建 nt:file + nt:resource 节点):

curl -i -X PUT -u admin:q1w2e3r4 -H "Content-Type: text/plain" \
  --data "Hello Jackrabbit!" \
  http://localhost:8080/repository/default/mydocs/hello.txt

实测回显:

HTTP/1.1 201 Created
Date: Sun, 11 Oct 2026 11:14:42 GMT
Content-Length: 0

读回该资源内容:

curl -s -u admin:q1w2e3r4 \
  http://localhost:8080/repository/default/mydocs/hello.txt

实测回显:

Hello Jackrabbit!

列出集合内子资源(PROPFIND,Depth 1):

curl -s -X PROPFIND -H "Depth: 1" -u admin:q1w2e3r4 \
  http://localhost:8080/repository/default/mydocs/ > /tmp/pf.xml

grep -E "href>|displayname" /tmp/pf.xml | head

实测回显中可见 mydocs 与 hello.txt 两个资源。

B. JCR API 创建 workspace 与带属性节点

写一个小 Java 客户端(基于 standalone jar,内含完整 JCR 库),登录 admin,创建新 workspace ws_demo,并在 default workspace 根下加一个 nt:unstructured 节点 /api(含 author、version 两个属性):

import javax.jcr.*;
import java.util.Arrays;
import org.apache.jackrabbit.core.RepositoryImpl;
import org.apache.jackrabbit.core.config.RepositoryConfig;

public class JcrOps {
    public static void main(String[] args) throws Exception {
        RepositoryConfig config = RepositoryConfig.create(
            "/opt/apache-jackrabbit/conf/repository-fs.xml", "/opt/data/jackrabbit");
        RepositoryImpl repo = RepositoryImpl.create(config);
        Session session = repo.login(
            new SimpleCredentials("admin", "q1w2e3r4".toCharArray()), "default");
        Workspace ws = session.getWorkspace();

        if (!Arrays.asList(ws.getAccessibleWorkspaceNames()).contains("ws_demo")) {
            ws.createWorkspace("ws_demo");          // 创建新 workspace
            System.out.println("CREATED_WORKSPACE  name=ws_demo");
        }
        Node api = session.getRootNode().addNode("api", "nt:unstructured");
        api.setProperty("author", "tester");
        api.setProperty("version", "1.2");
        session.save();
        System.out.println("CREATED_NODE  path=" + api.getPath()
            + " primaryType=" + api.getPrimaryNodeType().getName());
        System.out.println("== workspace list ==");
        for (String name : ws.getAccessibleWorkspaceNames()) System.out.println("  " + name);
        session.logout();
        repo.shutdown();
    }
}

编译并运行(需在 Jackrabbit 服务停止时执行,避免仓库目录锁冲突):

cd /opt/apache-jackrabbit
$JAVA_HOME/bin/javac -cp jackrabbit-standalone-2.22.5.jar JcrOps.java
$JAVA_HOME/bin/java -cp jackrabbit-standalone-2.22.5.jar:. JcrOps

实测回显:

== workspace list before ==
  security
  default
CREATED_WORKSPACE  name=ws_demo
CREATED_NODE  path=/api primaryType=nt:unstructured
== workspace list after ==
  security
  default
  ws_demo

重启服务后可在 http://localhost:8080/server/ 看到 ws_demo,且 default 的 WebDAV PROPFIND 也能列出 /api 的 author、version 属性(见 5.4)。

C. davE(REST)读取节点

读取 default 工作区根节点(jcr:root,XML):

curl -s -u admin:q1w2e3r4 -H "Accept: application/json" \
  http://localhost:8080/server/default/jcr%3aroot/

实测回显(节选,根为 rep:root,带 rep:AccessControllable mixin):

<?xml version="1.0" encoding="UTF-8"?><sv:node sv:name="jcr:root"
...><sv:property sv:name="jcr:primaryType" sv:type="Name"><sv:value>rep:root</sv:value>
</sv:property></sv:node>

⚠️ 注意:davE 对任意节点路径的 URL 采用 jcr:root 为根的规范(/server/<workspace>/jcr:root/<路径>)。直接 /server/default/api 这种省略 jcr:root 的写法会返回 500(Unexpected format of resource path)。写内容节点优先用 WebDAV 的 MKCOL/PUT,跨 workspace 管理用 JCR API。

六、配置说明

6.1 配置文件位置

配置默认位置作用
repository.xml从 jar 抽取,本文放 /opt/apache-jackrabbit/conf/仓库全局配置:数据存储、安全、workspace、版本、搜索索引、集群
workspace 模板见 repository.xml 的 <Workspace name="${wsp.name}">每个 workspace 的 file system / persistence / search index 模板
实例化 workspace 配置/opt/data/jackrabbit/workspaces/<ws>/首次创建 workspace 时按模板生成
运行日志/opt/data/jackrabbit/log/jackrabbit.log、access.log.<日期>应用与访问日志
数据目录/opt/data/jackrabbit/repository / version / workspaces / tmp / log

6.2 关键配置项(repository.xml)

  • <DataStore class="org.apache.jackrabbit.core.data.FileDataStore"/>:二进制数据存储,默认文件存储。
  • <Security> / <LoginModule>:adminId 默认 admin,anonymousId 默认 anonymous。
  • <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default"/>:workspace 根目录与默认 workspace 名。
  • <Workspace> / <PersistenceManager>:workspace 持久化,本文改为 BundleFsPersistenceManager(文件系统)。
  • <Versioning> / <PersistenceManager>:版本存储持久化,同理改为 BundleFsPersistenceManager。
  • <SearchIndex class="...lucene.SearchIndex">:Lucene 全文索引,path 指向索引目录。
  • <Cluster id="node1"> / <Journal class="...MemoryJournal">:集群 journal(默认内存实现,单机可忽略)。

详见《Apache Jackrabbit 配置参数详解》。

6.3 JVM 堆内存限制

Jackrabbit 是 Java 进程,生产应按机器规格限制堆内存,避免沿用启动时未设限制导致的默认大堆。standalone 通过 java -jar 启动,-Xms/-Xmx 直接写在命令行:

nohup $JAVA_HOME/bin/java -Xms256m -Xmx512m -Xmn128m \
  -jar jackrabbit-standalone-2.22.5.jar \
  -c /opt/apache-jackrabbit/conf/repository-fs.xml \
  -r /opt/data/jackrabbit > /tmp/jr.log 2>&1 &

其中 -Xms256m(初始堆 256MB)、-Xmx512m(最大堆 512MB)、-Xmn128m(新生代 128MB),符合 256–512MB 堆区间建议。

若用 systemd 托管,在 unit 里通过 Environment=JAVA_OPTS 注入(每行一个变量):

[Service]
Environment=JAVA_OPTS=-Xms256m -Xmx512m -Xmn128m
ExecStart=/usr/lib/jvm/java-17-openjdk-amd64/bin/java $JAVA_OPTS -jar /opt/apache-jackrabbit/jackrabbit-standalone-2.22.5.jar -c /opt/apache-jackrabbit/conf/repository-fs.xml -r /opt/data/jackrabbit

⚠️ 若用 Docker Compose 部署,通过 environment: 注入 JAVA_TOOL_OPTIONS(见《Apache Jackrabbit Docker Compose 部署指南》)。

验证窗口:确认实际生效的堆参数 用 jps -v 查看已运行 Java 进程的完整 JVM 参数(只能看到已生效的,即真实生效值):

$JAVA_HOME/bin/jps -v | grep jackrabbit

实测回显(明确可见 -Xms256m -Xmx512m -Xmn128m):

5134 jackrabbit-standalone-2.22.5.jar -Xms256m -Xmx512m -Xmn128m

七、注意事项

  • Derby 驱动缺失:2.22.5 standalone 未内嵌 Derby 驱动,默认 repository.xml 直接启动必失败,务必按「五、5.2」改为 BundleFsPersistenceManager。
  • 写内容节点用 WebDAV:/repository/* 走标准 WebDAV(MKCOL/PUT/PROPFIND),最稳;davE 读取走 /server/*,创建复杂节点直接写 JCR 客户端代码。
  • JVM 堆:始终显式设 -Xms/-Xmx,以 jps -v 确认生效。
  • 密码与账号:本文演示账号 admin / q1w2e3r4 为环境实测值;独立新装工厂默认密码为 admin,见「八、常见问题」改密方式。
  • 修改 repository.xml 后需重启服务生效;仓库元数据(用户、密码、节点)持久化于 /opt/data/jackrabbit,重启不丢(见 5.5 中重启后节点仍可读)。

八、常见问题

Q1:启动报 Could not load JDBC driver class org.apache.derby.jdbc.EmbeddedDriver? 原因:repository.xml 默认用 DerbyPersistenceManager,但 standalone jar 未打包 Derby 驱动。按「五、5.2」用 BundleFsPersistenceManager 替换两处即可。

Q2:/ 根路径访问返回 503? 正常。standalone 无根欢迎页,Jetty 默认 servlet 对 / 返回 503。管理入口是 /server/(workspace 概览)和 /repository/(WebDAV)。

Q3:davE 访问 /server/default/api 返回 500 Unexpected format of resource path? 该路径缺 jcr:root 前缀。应使用 /server/default/jcr:root/... 形态取节点,或直接用 WebDAV MKCOL/PUT 创建。

Q4:默认 admin 密码是什么?如何改成 q1w2e3r4? 工厂默认 admin/admin。可在服务停止后用 JCR UserManager.changePassword() 修改(参考 JcrOps 的登录写法取到 User 后调用 changePassword("q1w2e3r4") 并 save())。本指南环境已按此流程设为 admin/q1w2e3r4。

Q5:JVM 堆没生效? 用 jps -v 看真实进程参数;若通过 systemd/Compose 启动,检查注入变量是否真正传给 java(见三、六)。

九、卸载方式

  1. 停止服务(systemd 托管时):
systemctl stop jackrabbit
systemctl disable jackrabbit
  1. 删除安装目录、启动脚本与单元文件:
rm -rf /opt/apache-jackrabbit
rm -f /etc/systemd/system/jackrabbit.service
systemctl daemon-reload
  1. 如需连带清空数据(不可逆,谨慎):
rm -rf /opt/data/jackrabbit

若只卸 Java 进程 JDK:

apt-get purge -y openjdk-17-jdk-headless
rm -f /etc/profile.d/java.sh

十、参考链接