Skip to content

Commit 6cbf1cf

Browse files
authored
add jar build (#2473)
* switch from war to jar * adjust dockerfile * fixes * add ci for webapi-3.0 branch * fix * make war build the default
1 parent c1c9f58 commit 6cbf1cf

6 files changed

Lines changed: 102 additions & 64 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ name: CI
44
# Run in master and dev branches and in all pull requests to those branches
55
on:
66
push:
7-
branches: [ master ]
7+
branches: [ master, webapi-3.0 ]
88
pull_request:
9-
branches: [ master ]
9+
branches: [ master, webapi-3.0 ]
1010

1111
env:
1212
DOCKER_IMAGE: ohdsi/webapi
@@ -82,14 +82,14 @@ jobs:
8282
id: build_params
8383
run: |
8484
echo "::set-output name=sha8::${GITHUB_SHA::8}"
85-
if [ ${{ github.event_name == 'pull_request' }} ]; then
86-
echo "::set-output name=push::false"
87-
echo "::set-output name=load::true"
88-
echo "::set-output name=platforms::linux/amd64"
89-
else
85+
if [ "${{ github.event_name }}" != "pull_request" ] && [ "${{ github.ref }}" == "refs/heads/master" ]; then
9086
echo "::set-output name=push::true"
9187
echo "::set-output name=load::false"
9288
echo "::set-output name=platforms::linux/amd64,linux/arm64"
89+
else
90+
echo "::set-output name=push::false"
91+
echo "::set-output name=load::true"
92+
echo "::set-output name=platforms::linux/amd64"
9393
fi
9494
9595
- name: Login to DockerHub

.github/workflows/release.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,17 @@ jobs:
3636
restore-keys: |
3737
${{ runner.os }}-maven-
3838
39-
- name: Build code
39+
- name: Build JAR
4040
run: mvn -B -DskipTests=true -DskipUnitTests=true -P${{ env.MAVEN_PROFILE }} package
4141

42-
# Upload it to GitHub
42+
- name: Build WAR
43+
run: mvn -B -DskipTests=true -DskipUnitTests=true -P${{ env.MAVEN_PROFILE }},war package
44+
45+
# Upload both JAR and WAR to GitHub release
4346
- name: Upload to GitHub
4447
uses: AButler/upload-release-assets@v2.0
4548
with:
46-
files: 'target/WebAPI.war'
49+
files: 'target/WebAPI.jar;target/WebAPI.war'
4750
repo-token: ${{ secrets.GITHUB_TOKEN }}
4851

4952
# Build and push tagged release docker image to

Dockerfile

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ RUN curl -LSsO https://github.com/open-telemetry/opentelemetry-java-instrumentat
1212
COPY pom.xml /code/
1313
RUN mkdir .git \
1414
&& mvn package \
15+
-Dpackaging.type=jar \
1516
-P${MAVEN_PROFILE}
1617

1718
ARG GIT_BRANCH=unknown
@@ -20,24 +21,18 @@ ARG GIT_COMMIT_ID_ABBREV=unknown
2021
# Compile code and repackage it
2122
COPY src /code/src
2223
RUN mvn package ${MAVEN_PARAMS} \
24+
-Dpackaging.type=jar \
2325
-Dgit.branch=${GIT_BRANCH} \
2426
-Dgit.commit.id.abbrev=${GIT_COMMIT_ID_ABBREV} \
25-
-P${MAVEN_PROFILE} \
26-
&& mkdir war \
27-
&& mv target/WebAPI.war war \
28-
&& cd war \
29-
&& jar -xf WebAPI.war \
30-
&& rm WebAPI.war
27+
-P${MAVEN_PROFILE}
3128

32-
# OHDSI WebAPI and ATLAS web application running as a Spring Boot application with Java 21
29+
# OHDSI WebAPI running as a Spring Boot executable JAR with Java 21
3330
FROM index.docker.io/library/eclipse-temurin:21-jre
3431

3532
MAINTAINER Lee Evans - www.ltscomputingllc.com
3633

3734
# Any Java options to pass along, e.g. memory, garbage collection, etc.
3835
ENV JAVA_OPTS=""
39-
# Additional classpath parameters to pass along. If provided, start with colon ":"
40-
ENV CLASSPATH=""
4136
# Default Java options. The first entry is a fix for when java reads secure random numbers:
4237
# in a containerized system using /dev/random may reduce entropy too much, causing slowdowns.
4338
# https://ruleoftech.com/2016/avoiding-jvm-delays-caused-by-random-number-generation
@@ -47,21 +42,13 @@ ENV DEFAULT_JAVA_OPTS="-Djava.security.egd=file:///dev/./urandom"
4742
WORKDIR /var/lib/ohdsi/webapi
4843

4944
COPY --from=builder /code/opentelemetry-javaagent.jar .
50-
51-
# deploy the just built OHDSI WebAPI war file
52-
# copy resources in order of fewest changes to most changes.
53-
# This way, the libraries step is not duplicated if the dependencies
54-
# do not change.
55-
COPY --from=builder /code/war/WEB-INF/lib*/* WEB-INF/lib/
56-
COPY --from=builder /code/war/org org
57-
COPY --from=builder /code/war/WEB-INF/classes WEB-INF/classes
58-
COPY --from=builder /code/war/META-INF META-INF
45+
COPY --from=builder /code/target/WebAPI.jar .
5946

6047
EXPOSE 8080
6148

6249
USER 101
6350

64-
# Directly run the code as a WAR.
51+
# Run the executable JAR
6552
CMD exec java ${DEFAULT_JAVA_OPTS} ${JAVA_OPTS} \
66-
-cp ".:WebAPI.jar:WEB-INF/lib/*.jar${CLASSPATH}" \
67-
org.springframework.boot.loader.WarLauncher
53+
--add-opens java.naming/com.sun.jndi.ldap=ALL-UNNAMED \
54+
-jar WebAPI.jar

README.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ The API Documentation is found at [http://webapidoc.ohdsi.org/](http://webapidoc
2424

2525
Documentation can be found a the [Web API Installation Guide](https://github.com/OHDSI/WebAPI/wiki) which covers the system requirements and installation instructions.
2626

27+
## JAR Build (Executable)
28+
29+
WebAPI can also be built as a self-contained executable JAR with embedded Tomcat:
30+
31+
```bash
32+
# Build as JAR
33+
mvn clean package -DskipTests -Dpackaging.type=jar
34+
35+
# Run
36+
java -jar target/WebAPI.jar --spring.profiles.active=webapi-postgresql
37+
```
38+
2739
## SAML Auth support
2840

2941
The following parameters are used:
@@ -82,20 +94,20 @@ It was chosen to use embedded PG instead of H2 for unit tests since H2 doesn't s
8294

8395
To start the application locally, the following quick steps (all commands are executed from repository root directory)
8496

85-
1. Ensure that you have the following tools installed: Java 1.8, maven (check via `mvn -v`), docker-ce (check via `docker -v`), psql command line client
97+
1. Ensure that you have the following tools installed: Java 1.8, maven (check via `mvn -v`), docker-ce (check via `docker -v`), psql command line client
8698
(check via psql --version) or other tool that allows to connect to postgres DB.
8799
2. Run `mvn clean install` and make sure it completes successfully, resolve dependency issues if any.
88100
3. Create a new database in docker: `docker create --name postgres-webapi -p 8432:5432 -e POSTGRES_PASSWORD=ohdsi postgres:15.0-alpine`.
89101
4. Start DB container: `docker start postgres-webapi`.
90102
Verify that you can connect via psql console (`PGPASSWORD='ohdsi' psql -d postgresql://localhost:8432/?user=postgres`).
91-
5. If your default java version is too high (e.g. 17), set JAVA_HOME to point to 1.8 installaction, for example `export JAVA_HOME=/usr/lib/jvm/zulu8-ca-amd64`
103+
5. If your default java version is too high (e.g. 17), set JAVA_HOME to point to 1.8 installaction, for example `export JAVA_HOME=/usr/lib/jvm/zulu8-ca-amd64`
92104
6. Start WebAPI `mvn clean install spring-boot:run -Dmaven.test.skip=true -P webapi-postgresql -s src/dev/settings.xml -f pom.xml`
93105
7. Log in with the username of your liking
94106
8. Grant this newly created user admin privileges by running the following sql `INSERT INTO sec_user_role (user_id, role_id, origin) VALUES (1000, 2, 'SYSTEM');`
95107
and log in again.
96108

97-
At this point you have the application running and admin account operational. To actually use it, additional steps are required to set up privileges
98-
and at least one CDM database. They are covered in the respective documentation sections.
99-
109+
At this point you have the application running and admin account operational. To actually use it, additional steps are required to set up privileges
110+
and at least one CDM database. They are covered in the respective documentation sections.
111+
100112
## License
101-
OHDSI WebAPI is licensed under Apache License 2.0
113+
OHDSI WebAPI is licensed under Apache License 2.0

pom.xml

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55

66
<groupId>org.ohdsi</groupId>
77
<artifactId>WebAPI</artifactId>
8-
<packaging>war</packaging>
8+
<packaging>${packaging.type}</packaging>
99
<version>3.0.0-SNAPSHOT</version>
1010
<name>WebAPI</name>
1111
<properties>
12+
<packaging.type>war</packaging.type>
1213
<build.number>${BUILD_NUMBER}</build.number>
1314
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1415
<!-- Spring Boot manages spring.version as well -->
@@ -416,7 +417,6 @@
416417
<groupId>org.springframework.boot</groupId>
417418
<artifactId>spring-boot-maven-plugin</artifactId>
418419
<version>${spring.boot.version}</version>
419-
<!-- executable-war via 'java -jar WebAPI-exec.war' currently fails with Jersey FileNotFound exception. TODO -->
420420
<configuration>
421421
<!-- Since we filter properties files via Maven, do not add resources. -->
422422
<addResources>false</addResources>
@@ -476,15 +476,6 @@
476476
</compilerArgs>
477477
</configuration>
478478
</plugin>
479-
<plugin>
480-
<groupId>org.apache.maven.plugins</groupId>
481-
<artifactId>maven-war-plugin</artifactId>
482-
<version>3.4.0</version>
483-
<configuration>
484-
<failOnMissingWebXml>false</failOnMissingWebXml>
485-
<attachClasses>true</attachClasses>
486-
</configuration>
487-
</plugin>
488479
<plugin>
489480
<groupId>org.apache.maven.plugins</groupId>
490481
<artifactId>maven-failsafe-plugin</artifactId>
@@ -689,16 +680,14 @@
689680
<dependency>
690681
<groupId>org.springframework.boot</groupId>
691682
<artifactId>spring-boot-starter-tomcat</artifactId>
692-
<scope>provided</scope>
693683
</dependency>
694684
<dependency>
695685
<groupId>org.springframework.boot</groupId>
696686
<artifactId>spring-boot-starter-batch</artifactId>
697687
</dependency>
698688

699-
<!-- We are intentionally overriding the Tomcat version from Spring Boot 1.5.22.RELEASE -->
700-
<!-- and assuming tomcat-jdbc.jar will be in the Tomcat installation folder (\apache-tomcat-8.5.xxx\lib). -->
701-
<!-- WebAPI.war.original should not contain overridden libraries -->
689+
<!-- Embedded Tomcat dependencies for executable JAR -->
690+
<!-- Note: WAR packaging is available via 'mvn package -Pwar' profile -->
702691
<dependency>
703692
<groupId>org.apache.tomcat.embed</groupId>
704693
<artifactId>tomcat-embed-el</artifactId>
@@ -711,7 +700,6 @@
711700
<dependency>
712701
<groupId>org.apache.tomcat</groupId>
713702
<artifactId>tomcat-jdbc</artifactId>
714-
<scope>provided</scope>
715703
</dependency>
716704
<dependency>
717705
<groupId>org.apache.tomcat</groupId>
@@ -779,12 +767,15 @@
779767
</exclusion>
780768
</exclusions>
781769
</dependency> -->
770+
<!-- javax.servlet-api is now provided by spring-boot-starter-tomcat (Jakarta Servlet API) -->
771+
<!-- This old javax.servlet dependency can be removed for JAR packaging -->
772+
<!--
782773
<dependency>
783774
<groupId>javax.servlet</groupId>
784775
<artifactId>javax.servlet-api</artifactId>
785776
<version>3.1.0</version>
786-
<scope>provided</scope>
787777
</dependency>
778+
-->
788779
<dependency>
789780
<groupId>javax.cache</groupId>
790781
<artifactId>cache-api</artifactId>
@@ -1902,5 +1893,49 @@
19021893
</dependency>
19031894
</dependencies>
19041895
</profile>
1896+
1897+
<!-- WAR packaging profile - use with: mvn package -Pwar -->
1898+
<profile>
1899+
<id>war</id>
1900+
<properties>
1901+
<packaging.type>war</packaging.type>
1902+
</properties>
1903+
<dependencies>
1904+
<!-- Mark embedded Tomcat as provided for external servlet container deployment -->
1905+
<dependency>
1906+
<groupId>org.springframework.boot</groupId>
1907+
<artifactId>spring-boot-starter-tomcat</artifactId>
1908+
<scope>provided</scope>
1909+
</dependency>
1910+
<dependency>
1911+
<groupId>org.apache.tomcat</groupId>
1912+
<artifactId>tomcat-jdbc</artifactId>
1913+
<scope>provided</scope>
1914+
</dependency>
1915+
</dependencies>
1916+
<build>
1917+
<plugins>
1918+
<plugin>
1919+
<groupId>org.apache.maven.plugins</groupId>
1920+
<artifactId>maven-war-plugin</artifactId>
1921+
<version>3.4.0</version>
1922+
<executions>
1923+
<execution>
1924+
<id>build-war</id>
1925+
<phase>package</phase>
1926+
<goals>
1927+
<goal>war</goal>
1928+
</goals>
1929+
<configuration>
1930+
<failOnMissingWebXml>false</failOnMissingWebXml>
1931+
<attachClasses>true</attachClasses>
1932+
<warName>WebAPI</warName>
1933+
</configuration>
1934+
</execution>
1935+
</executions>
1936+
</plugin>
1937+
</plugins>
1938+
</build>
1939+
</profile>
19051940
</profiles>
19061941
</project>

src/main/java/org/ohdsi/webapi/WebApi.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package org.ohdsi.webapi;
22

33
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
4+
import org.springframework.boot.SpringApplication;
45
import org.springframework.boot.autoconfigure.SpringBootApplication;
5-
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
6-
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
76
import org.springframework.boot.builder.SpringApplicationBuilder;
87
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
9-
import org.springframework.context.annotation.ComponentScan;
8+
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
9+
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
1010
import org.springframework.context.annotation.EnableAspectJAutoProxy;
1111
import org.springframework.scheduling.annotation.EnableScheduling;
1212

@@ -15,25 +15,26 @@
1515

1616

1717
/**
18-
* Launch as java application or deploy as WAR (@link {@link WebApplication}
19-
* will source this file).
18+
* OHDSI WebAPI Spring Boot Application
19+
*
20+
* Supports both JAR and WAR deployment:
21+
* - JAR: java -jar WebAPI.jar (embedded Tomcat)
22+
* - WAR: Deploy to external servlet container (mvn package -Pwar)
2023
*/
2124
@EnableScheduling
2225
@SpringBootApplication(exclude={HibernateJpaAutoConfiguration.class, ErrorMvcAutoConfiguration.class})
2326
@EnableAspectJAutoProxy(proxyTargetClass = true)
2427
public class WebApi extends SpringBootServletInitializer {
2528

26-
27-
2829
@Override
29-
protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
30-
return application.sources(WebApi.class);
30+
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
31+
return builder.sources(WebApi.class);
3132
}
3233

3334
public static void main(final String[] args) throws Exception
3435
{
3536
TomcatURLStreamHandlerFactory.disable();
36-
new SpringApplicationBuilder(WebApi.class).run(args);
37+
SpringApplication.run(WebApi.class, args);
3738
}
3839

3940
@PostConstruct

0 commit comments

Comments
 (0)