Skip to content

Commit d82489d

Browse files
STAND-126: Improve Windows Compatibility and Safe Data Directory Reuse for Standalone 3.x (openmrs#84)
* Replace the embedded mysql with mariadb4j in Ref App 2.x * removing nashorn-core * updating to the latest snapshot * resized MainFrame and updated readme * added unit tests * STAND-119: Support-reference-application-3-x-on-open-mrs-standalone * STAND-126: Improve Windows Compatibility and Safe Data Directory Reuse for Standalone 3.x * include back the openmrs-standalone.jar in target * separating the poms to solve classifier attached error * updating phase to package * updated unzip destination on Windows * applying the industry standard on titles and update pom rules
1 parent 97c828e commit d82489d

File tree

10 files changed

+315
-104
lines changed

10 files changed

+315
-104
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,27 @@ SUMMARY: Using a single package for all (most) platforms approximately tripples
183183

184184

185185
MariaDB4j documentation can be found at: https://github.com/MariaDB4j/MariaDB4j
186+
187+
188+
## 🛠️ Reusable Embedded MariaDB (ReusableDB.java) for Windows Compatibility
189+
The OpenMRS Standalone project uses a custom wrapper around the MariaDB4j `DB` class called `ReusableDB`. This wrapper is designed to enhance the robustness of the startup process and improve cross-platform compatibility, particularly on Windows systems.
190+
191+
192+
#### 🔍 Purpose
193+
194+
`ReusableDB` avoids deleting the `dataDir` when the database is already initialized. This:
195+
- Prevents startup failures due to locked files on Windows.
196+
- Supports seamless restarts of the Standalone without losing data.
197+
- Makes switching between demo and empty databases more reliable.
198+
199+
#### ✅ How it Works
200+
- Checks for the presence of the `openmrs` database directory inside `dataDir`.
201+
- If not found, triggers the initial MariaDB install process.
202+
- Otherwise, starts MariaDB using the existing configuration and data files.
203+
204+
#### 📦 Usage Example
205+
206+
```java
207+
DBConfigurationBuilder config = DBConfigurationBuilder.newBuilder();
208+
config.setPort(3316);
209+
ReusableDB db = ReusableDB.openEmbeddedDB(config.build());

pom-step-02.xml

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -210,76 +210,6 @@
210210
</execution>
211211
</executions>
212212
</plugin>
213-
<plugin>
214-
<groupId>org.apache.maven.plugins</groupId>
215-
<artifactId>maven-assembly-plugin</artifactId>
216-
<executions>
217-
<execution>
218-
<id>package-jar-with-dependencies</id>
219-
<phase>prepare-package</phase>
220-
<goals>
221-
<goal>single</goal>
222-
</goals>
223-
<configuration>
224-
<finalName>openmrs-standalone</finalName>
225-
<appendAssemblyId>true</appendAssemblyId>
226-
<outputDirectory>${project.build.directory}</outputDirectory>
227-
<descriptorRefs>
228-
<descriptorRef>jar-with-dependencies</descriptorRef>
229-
</descriptorRefs>
230-
<archive>
231-
<manifest>
232-
<mainClass>org.openmrs.standalone.Bootstrap</mainClass>
233-
</manifest>
234-
</archive>
235-
</configuration>
236-
</execution>
237-
<execution>
238-
<id>zip-demo-database</id>
239-
<phase>package</phase>
240-
<goals>
241-
<goal>single</goal>
242-
</goals>
243-
<configuration>
244-
<finalName>demodatabase</finalName>
245-
<appendAssemblyId>false</appendAssemblyId>
246-
<attach>false</attach>
247-
<descriptors>
248-
<descriptor>src/main/assembly/zip-demo-database.xml</descriptor>
249-
</descriptors>
250-
</configuration>
251-
</execution>
252-
<execution>
253-
<id>zip-empty-database</id>
254-
<phase>package</phase>
255-
<goals>
256-
<goal>single</goal>
257-
</goals>
258-
<configuration>
259-
<finalName>emptydatabase</finalName>
260-
<appendAssemblyId>false</appendAssemblyId>
261-
<attach>false</attach>
262-
<descriptors>
263-
<descriptor>src/main/assembly/zip-empty-database.xml</descriptor>
264-
</descriptors>
265-
</configuration>
266-
</execution>
267-
<execution>
268-
<id>zip-standalone</id>
269-
<phase>package</phase>
270-
<goals>
271-
<goal>single</goal>
272-
</goals>
273-
<configuration>
274-
<finalName>referenceapplication-standalone-${refapp.version}</finalName>
275-
<appendAssemblyId>false</appendAssemblyId>
276-
<descriptors>
277-
<descriptor>src/main/assembly/zip-standalone.xml</descriptor>
278-
</descriptors>
279-
</configuration>
280-
</execution>
281-
</executions>
282-
</plugin>
283213
</plugins>
284214
<pluginManagement>
285215
<plugins>

pom-step-03.xml

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<groupId>org.openmrs</groupId>
6+
<artifactId>referenceapplication-standalone-03</artifactId>
7+
<version>3.0.0-SNAPSHOT</version>
8+
<packaging>jar</packaging>
9+
10+
<name>referenceapplication-standalone-03</name>
11+
12+
<parent>
13+
<groupId>org.openmrs</groupId>
14+
<artifactId>referenceapplication-standalone</artifactId>
15+
<version>3.0.0-SNAPSHOT</version>
16+
<relativePath>pom.xml</relativePath>
17+
</parent>
18+
19+
<build>
20+
<plugins>
21+
<plugin>
22+
<groupId>org.apache.maven.plugins</groupId>
23+
<artifactId>maven-assembly-plugin</artifactId>
24+
<executions>
25+
<execution>
26+
<id>package-jar-with-dependencies</id>
27+
<phase>package</phase>
28+
<goals>
29+
<goal>single</goal>
30+
</goals>
31+
<configuration>
32+
<finalName>openmrs-standalone</finalName>
33+
<appendAssemblyId>false</appendAssemblyId>
34+
<outputDirectory>${project.build.directory}</outputDirectory>
35+
<descriptorRefs>
36+
<descriptorRef>jar-with-dependencies</descriptorRef>
37+
</descriptorRefs>
38+
<archive>
39+
<manifest>
40+
<mainClass>org.openmrs.standalone.Bootstrap</mainClass>
41+
</manifest>
42+
</archive>
43+
</configuration>
44+
</execution>
45+
<execution>
46+
<id>zip-demo-database</id>
47+
<phase>package</phase>
48+
<goals>
49+
<goal>single</goal>
50+
</goals>
51+
<configuration>
52+
<finalName>demodatabase</finalName>
53+
<appendAssemblyId>false</appendAssemblyId>
54+
<attach>false</attach>
55+
<descriptors>
56+
<descriptor>src/main/assembly/zip-demo-database.xml</descriptor>
57+
</descriptors>
58+
</configuration>
59+
</execution>
60+
<execution>
61+
<id>zip-empty-database</id>
62+
<phase>package</phase>
63+
<goals>
64+
<goal>single</goal>
65+
</goals>
66+
<configuration>
67+
<finalName>emptydatabase</finalName>
68+
<appendAssemblyId>false</appendAssemblyId>
69+
<attach>false</attach>
70+
<descriptors>
71+
<descriptor>src/main/assembly/zip-empty-database.xml</descriptor>
72+
</descriptors>
73+
</configuration>
74+
</execution>
75+
<execution>
76+
<id>zip-standalone</id>
77+
<phase>package</phase>
78+
<goals>
79+
<goal>single</goal>
80+
</goals>
81+
<configuration>
82+
<finalName>referenceapplication-standalone-${refapp.version}</finalName>
83+
<appendAssemblyId>false</appendAssemblyId>
84+
<descriptors>
85+
<descriptor>src/main/assembly/zip-standalone.xml</descriptor>
86+
</descriptors>
87+
</configuration>
88+
</execution>
89+
</executions>
90+
</plugin>
91+
</plugins>
92+
<pluginManagement>
93+
<plugins>
94+
<plugin>
95+
<groupId>org.liquibase</groupId>
96+
<artifactId>${liquibase.plugin.artifactId}</artifactId>
97+
<version>${liquibase.plugin.version}</version>
98+
<dependencies>
99+
<dependency>
100+
<groupId>org.openmrs.api</groupId>
101+
<artifactId>openmrs-api</artifactId>
102+
<version>${openmrs.version}</version>
103+
<type>jar</type>
104+
</dependency>
105+
</dependencies>
106+
</plugin>
107+
</plugins>
108+
</pluginManagement>
109+
</build>
110+
</project>

pom.xml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<modules>
1414
<module>pom-step-01.xml</module>
1515
<module>pom-step-02.xml</module>
16+
<module>pom-step-03.xml</module>
1617
</modules>
1718

1819
<properties>
@@ -131,13 +132,13 @@
131132
<property>refapp.version</property>
132133
<message>refapp.version property is missing. This should be
133134
something like 3.4, 3.5 Add
134-
-Drefapp.version=3.5</message>
135+
-Drefapp.version=3.4.1-SNAPSHOT</message>
135136
</requireProperty>
136137
<requireProperty>
137138
<property>openmrs.version</property>
138139
<message>openmrs.version property is missing. This should be
139-
something like 3.4.0, 3.3.1 Add
140-
-Dopenmrs.version=3.4.1-SNAPSHOT</message>
140+
something like 2.7.4, 2.8.0 Add
141+
-Dopenmrs.version=2.7.4</message>
141142
</requireProperty>
142143
</rules>
143144
<fail>true</fail>

src/main/java/org/openmrs/standalone/ApplicationController.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.openmrs.standalone;
1515

1616
import ch.vorburger.exec.ManagedProcessException;
17+
import org.apache.commons.io.FileUtils;
1718

1819
import java.io.BufferedInputStream;
1920
import java.io.BufferedOutputStream;
@@ -24,6 +25,7 @@
2425
import java.io.IOException;
2526
import java.lang.management.ManagementFactory;
2627
import java.util.Enumeration;
28+
import java.util.Objects;
2729
import java.util.Properties;
2830
import java.util.zip.ZipEntry;
2931
import java.util.zip.ZipFile;
@@ -168,9 +170,6 @@ public void finished() {
168170
} else {
169171
userInterface.setStatus(UserInterface.STATUS_MESSAGE_STOPPED);
170172
}
171-
172-
//userInterface.enableStart(value == null);
173-
//userInterface.enableStop(value != null);
174173
}
175174
};
176175

@@ -253,6 +252,12 @@ public void run() {
253252
}
254253

255254
if (applyDatabaseChange != null) {
255+
File dest = new File("db");
256+
if (dest.exists()) {
257+
if (dest.isDirectory() && dest.listFiles() != null && Objects.requireNonNull(dest.listFiles()).length > 0) {
258+
FileUtils.cleanDirectory(dest);
259+
}
260+
}
256261
if (applyDatabaseChange == DatabaseMode.USE_INITIALIZATION_WIZARD) {
257262
deleteActiveDatabase();
258263
StandaloneUtil.resetConnectionPassword();
@@ -352,7 +357,7 @@ private boolean deleteFileOrDirectory(File dirOrFile) {
352357
*/
353358
private void unzipDatabase(File zipFile) throws IOException {
354359
System.out.println("Unzipping database from " + zipFile.getName());
355-
File dest = new File("database");
360+
File dest = new File("db");
356361
dest.mkdir();
357362
unzip(zipFile, dest);
358363
}

src/main/java/org/openmrs/standalone/MainFrame.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,12 +429,12 @@ public void showInitialConfig() {
429429
final JButton useCurrent = new JButton("Do Not Modify the Database");
430430

431431
final JButton demoDatabase = new JButton(
432-
"<html><h3>Demonstration mode</h3>Configures OpenMRS " + OpenmrsUtil.REFAPP_VERSION + " with a demonstration database. This is the quickest way to start up OpenMRS " + OpenmrsUtil.REFAPP_VERSION + " with some sample data to evaluate the system or experiment with features</html>",
432+
"<html><h3>Demonstration mode</h3>Configures OpenMRS with a demonstration database. This is the quickest way to start up OpenMRS with some sample data to evaluate the system or experiment with features</html>",
433433
new ImageIcon(getClass().getResource("demonstration_mode.png")));
434434
colorHelper(demoDatabase, new Color(136, 235, 148));
435435

436436
final JButton emptyDatabase = new JButton(
437-
"<html><h3>Starter Implementation</h3>Configures OpenMRS " + OpenmrsUtil.REFAPP_VERSION + " without any patient data. If you are familiar with OpenMRS " + OpenmrsUtil.REFAPP_VERSION + " and want to start a new system, this is a good place to start.</html>",
437+
"<html><h3>Starter Implementation</h3>Configures OpenMRS without any patient data. If you are familiar with OpenMRS and want to start a new system, this is a good place to start.</html>",
438438
new ImageIcon(getClass().getResource("starter_impl.png")));
439439
colorHelper(emptyDatabase, new Color(255, 243, 136));
440440

@@ -466,7 +466,7 @@ public void actionPerformed(ActionEvent e) {
466466
}
467467

468468
JLabel instructions = new JLabel(
469-
"<html><b>Welcome to OpenMRS " + OpenmrsUtil.REFAPP_VERSION + "! OpenMRS " + OpenmrsUtil.REFAPP_VERSION + " can be configured in one of " + buttonList.size() + " ways, depending on your needs. Please click on the configuration that best meets your needs.</b><br/>(You will not see this next time you run OpenMRS " + OpenmrsUtil.REFAPP_VERSION + ")</html>");
469+
"<html><b>Welcome to OpenMRS " + OpenmrsUtil.REFAPP_VERSION + "! OpenMRS can be configured in one of " + buttonList.size() + " ways, depending on your needs. Please click on the configuration that best meets your needs.</b><br/>(You will not see this next time you run OpenMRS)</html>");
470470
instructions.setFont(font);
471471

472472
JButton exitButton = new JButton("Exit");

0 commit comments

Comments
 (0)