Support occlum font for java

This commit is contained in:
jeffery.wsj 2020-10-12 11:05:18 +08:00 committed by Zongmin.Gu
parent 28f47dacce
commit 7eb132c2b2
5 changed files with 223 additions and 0 deletions

@ -0,0 +1,23 @@
FROM alpine:3.12
ENV JAVA_HOME="/usr/lib/jvm/default-jvm/"
RUN echo -e "https://mirrors.ustc.edu.cn/alpine/v3.12/main\nhttps://mirrors.ustc.edu.cn/alpine/v3.12/community" > /etc/apk/repositories; \
apk add openjdk11
# Has to be set explictly to find binaries
ENV PATH=$PATH:${JAVA_HOME}/bin
ENV GRADLE_VERSION 6.6
# get gradle and supporting libs
RUN apk -U add --no-cache curl; \
curl https://downloads.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip > gradle.zip; \
unzip gradle.zip; \
rm gradle.zip; \
apk del curl; \
apk update && apk add --no-cache libstdc++ && rm -rf /var/cache/apk/* && apk add --update ttf-dejavu fontconfig
COPY simsun.ttf /usr/share/fonts/simsun/simsun.ttf
ENV PATH=${PATH}:/gradle-${GRADLE_VERSION}/bin

@ -0,0 +1,35 @@
# Make Occlum support font
This project demonstrates how Occlum support font with a Java demo in SGX enclaves.
# About JDK
Both the unmodified [OpenJDK 11](https://hg.openjdk.java.net/portola/jdk11), which is imported from Alpine Linux, and the [Alibaba Dragonwell](https://github.com/alibaba/dragonwell11/tree/dragonwell-for-enclave), which is a downstream version of OpenJDK, are supported now. We have already installed OpenJDK and Dragonwell while building the Docker image, the OpenJDK is installed at `/opt/occlum/toolchains/jvm/java-11-openjdk`, and the Dragonwell is installed at `/opt/occlum/toolchains/jvm/java-11-alibaba-dragonwell`.
Our demos use Dragonwell as the default JDK, you are free to change to OpenJDK by setting the `JAVA_HOME` to point to the installation directory of OpenJDK and copying it into Occlum instance.
## Demo: Java excel file writting with Poi
We provide a excel file writting demo to show how to make occlum support font inside SGX enclaves.
### Create demo and build it
Excel writting demo is created in create_java_font_app.sh, and the script also creates a build.gradle to build demo. Then a docker container is created to
build the demo and we will get a fat jar file. The docker container is based on Alpine, we will collect all dependency libs and font in document font-lib
from the container.
### Run demo in Occlum container
Create occlum instance and copy all libs into occlum image which font dependence in occlum container, then build the occlum image and run the demo.
### How to Run
Step 1: Create and build demo, also collect font dependency occlum needs
./create_java_font_app.sh
Step 2: Create occlum instance and run the demo in occlum's latest docker image release
docker run -it --device /dev/isgx --rm -v `pwd`:`pwd` -w `pwd` occlum/occlum:0.16.0-ubuntu18.04 `pwd`/run_java_font_app_internal.sh
Step 3: To check whether it works, a Demo.xlsx file should be created in occlum image host path.

@ -0,0 +1,13 @@
#!/bin/sh
set -e
workpath=`pwd`
cd ./poi-excel-demo && gradle build customFatJar && cd ../
mkdir -p font-lib/etc && cp -r /etc/fonts ./font-lib/etc
mkdir -p font-lib/lib && cp -d /lib/libuuid.so.1* ./font-lib/lib
mkdir -p font-lib/usr/lib && cp -d /usr/lib/libbz2.so.1* ./font-lib/usr/lib && cp -d /usr/lib/libbrotlicommon.so.1* ./font-lib/usr/lib && cp -d /usr/lib/libbrotlidec.so.1* ./font-lib/usr/lib && \
cp -d /usr/lib/libexpat.so.1* ./font-lib/usr/lib && cp -d /usr/lib/libfontconfig.so.1* ./font-lib/usr/lib && cp -d /usr/lib/libfreetype.so.6* ./font-lib/usr/lib && \
cp -d /usr/lib/libpng16.so.16* ./font-lib/usr/lib
mkdir -p font-lib/usr/share && cp -r /usr/share/fontconfig ./font-lib/usr/share && cp -r /usr/share/fonts ./font-lib/usr/share

@ -0,0 +1,98 @@
#!/bin/bash
SCRIPT_NAME=build_java_font_app.sh
# 1. Create the poi demo with font
demopath=`pwd`
rm -rf poi-excel-demo && mkdir poi-excel-demo && cd $_
mkdir -p src/main/java && cd $_
echo '
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.streaming.SXSSFCell;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SXSSFWriteDemoTwo {
public static void main(String[] args) throws IOException {
// 数据源
List<String[]> data = new ArrayList<>();
data.add(new String[]{"学号", "姓名", "性别", "专业"});
data.add(new String[]{"1001", "小白", "女", "计算机科学与技术"});
data.add(new String[]{"1002", "小黑", "男", "软件工程"});
// 关闭自动转移(内存向硬盘)
SXSSFWorkbook swb = new SXSSFWorkbook(-1);
// 创建sheet
SXSSFSheet sheet = swb.createSheet("Demo");
// 设置font字体
XSSFFont font = (XSSFFont) swb.createFont();
font.setFontName("宋体");
CellStyle cellFormat = swb.createCellStyle();
cellFormat.setFont(font);
for (int i = 0; i < data.size(); i++) {
if (0 != i && 0 == i % 1000) {
// 手动转移(内存向硬盘)
sheet.flushRows(1000);
}
// 创建行
SXSSFRow row = sheet.createRow(i);
String[] content = data.get(i);
for (int j = 0; j < content.length; j++) {
// 创建单元格
if (0 != i && 0 == j) {
SXSSFCell c = row.createCell(j);
c.setCellStyle(cellFormat);
c.setCellValue(Double.valueOf(content[j]));
continue;
}
SXSSFCell c = row.createCell(j);
c.setCellStyle(cellFormat);
c.setCellValue(content[j]);
}
}
// 生成Excel
FileOutputStream out = new FileOutputStream("/host/Demo.xlsx");
swb.write(out);
out.close();
}
}' > SXSSFWriteDemoTwo.java
cd $demopath/poi-excel-demo
# 2. Create gradle project
echo "
apply plugin: 'java'
repositories {
mavenCentral()
}
task customFatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'SXSSFWriteDemoTwo'
}
baseName = 'SXSSFWriteDemoTwo'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
dependencies {
compile 'org.apache.poi:poi:3.17'
compile 'org.apache.poi:poi-ooxml:3.17'
}" > build.gradle
cd $demopath
rm -rf SimSun.ttf && wget http://d.xiazaiziti.com/en_fonts/fonts/s/SimSun.ttf && mv SimSun.ttf simsun.ttf
docker images | grep occlum-font &> /dev/null
if [ $? -ne 0 ]
then
echo 'docker build occlum-font:v1 image'
docker build -t occlum-font:v1 .
else
echo 'docker image occlum-font:v1 exist'
fi
docker run -it --rm -v `pwd`:`pwd` -w `pwd` --network host --entrypoint=/bin/sh occlum-font:v1 `pwd`/$SCRIPT_NAME

@ -0,0 +1,54 @@
#!/bin/bash
set -e
BLUE='\033[1;34m'
NC='\033[0m'
check_file_exist() {
file=$1
if [ ! -f ${file} ];then
echo "Error: cannot stat file '${file}'"
echo "Please see README and build it"
exit 1
fi
}
init_instance() {
# Init Occlum instance
rm -rf occlum_instance && mkdir occlum_instance
cd occlum_instance
occlum init
new_json="$(jq '.resource_limits.user_space_size = "1400MB" |
.resource_limits.kernel_space_heap_size="64MB" |
.resource_limits.max_num_of_threads = 64 |
.process.default_heap_size = "256MB" |
.process.default_mmap_size = "1120MB" |
.entry_points = [ "/usr/lib/jvm/java-11-alibaba-dragonwell/jre/bin" ] |
.env.default = [ "LD_LIBRARY_PATH=/usr/lib/jvm/java-11-alibaba-dragonwell/jre/lib/server:/usr/lib/jvm/java-11-alibaba-dragonwell/jre/lib:/usr/lib/jvm/java-11-alibaba-dragonwell/jre/../lib" ]' Occlum.json)" && \
echo "${new_json}" > Occlum.json
}
build_poi_font() {
# Copy JVM and JAR file into Occlum instance and build
mkdir -p image/usr/lib/jvm
cp -r /opt/occlum/toolchains/jvm/java-11-alibaba-dragonwell image/usr/lib/jvm
cp /usr/local/occlum/x86_64-linux-musl/lib/libz.so.1 image/lib
cp -r /opt/occlum/font-lib/etc image && cp -r /opt/occlum/font-lib/lib/. image/lib && cp -r /opt/occlum/font-lib/usr/. image/usr
mkdir -p image/usr/app
cp ../${jar_path} image/usr/app
occlum build
}
run_poi_font() {
jar_path=./poi-excel-demo/build/libs/SXSSFWriteDemoTwo.jar
check_file_exist ${jar_path}
jar_file=`basename "${jar_path}"`
cp -r ./font-lib /opt/occlum
/opt/occlum/start_aesm.sh
init_instance
build_poi_font
echo -e "${BLUE}occlum run JVM poi font app${NC}"
occlum run /usr/lib/jvm/java-11-alibaba-dragonwell/jre/bin/java -Xmx512m -XX:-UseCompressedOops -XX:MaxMetaspaceSize=64m -Dos.name=Linux -jar /usr/app/SXSSFWriteDemoTwo.jar
}
run_poi_font