diff --git a/.github/workflows/license-header-format.yml b/.github/workflows/license-header-format.yml
index 0ac41c7bc8..6be1171b32 100644
--- a/.github/workflows/license-header-format.yml
+++ b/.github/workflows/license-header-format.yml
@@ -35,7 +35,7 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: 'corretto' # https://github.com/actions/setup-java?tab=readme-ov-file#supported-distributions
- java-version: '21'
+ java-version: '25'
cache: 'maven' # https://github.com/actions/setup-java?tab=readme-ov-file#caching-sbt-dependencies
- name: License header format
diff --git a/application/src/main/data/json/edge/instructions/install/centos/instructions.md b/application/src/main/data/json/edge/instructions/install/centos/instructions.md
index 1822add6d8..964cdcb887 100644
--- a/application/src/main/data/json/edge/instructions/install/centos/instructions.md
+++ b/application/src/main/data/json/edge/instructions/install/centos/instructions.md
@@ -1,22 +1,24 @@
-Here is the list of commands that can be used to quickly install ThingsBoard Edge on RHEL/CentOS 7/8 and connect to the server.
+Here is the list of commands that can be used to quickly install ThingsBoard Edge on RHEL/CentOS 9/10 and connect to the server.
+
+**Note:** OpenJDK 25 requires RHEL/CentOS 9+ or RHEL/CentOS 10+. Earlier versions (RHEL/CentOS 7, 8) are not supported.
#### Prerequisites
Before continuing to installation, execute the following commands to install the necessary tools:
```bash
-sudo yum install -y nano wget && sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
+sudo dnf install -y nano wget
{:copy-code}
```
-#### Step 1. Install Java 17 (OpenJDK)
-ThingsBoard service is running on Java 17. To install OpenJDK 17, follow these instructions:
+#### Step 1. Install Java 25 (OpenJDK)
+ThingsBoard service is running on Java 25. To install OpenJDK 25, follow these instructions:
```bash
-sudo dnf install java-17-openjdk
+sudo dnf install -y java-25-openjdk
{:copy-code}
```
-Configure your operating system to use OpenJDK 17 by default. You can configure the default version by running the following command:
+Configure your operating system to use OpenJDK 25 by default. You can configure the default version by running the following command:
```bash
sudo update-alternatives --config java
@@ -33,7 +35,7 @@ java -version
The expected result is:
```text
-openjdk version "17.x.xx"
+openjdk version "25.x.xx"
OpenJDK Runtime Environment (...)
OpenJDK 64-Bit Server VM (build ...)
```
@@ -41,7 +43,7 @@ OpenJDK 64-Bit Server VM (build ...)
#### Step 2. Configure ThingsBoard Edge Database
ThingsBoard Edge supports **SQL** and **hybrid** database configurations.
-In this guide, we’ll use an **SQL** database.
+In this guide, we'll use an **SQL** database.
For more details about the hybrid setup, please refer to the official installation instructions on the ThingsBoard documentation site.
To install the PostgreSQL database, run these commands:
@@ -54,19 +56,19 @@ sudo dnf update
Install the repository RPM:
-* **For CentOS/RHEL 8:**
+* **For RHEL/CentOS 9:**
```bash
-# Install the repository RPM (For CentOS/RHEL 8):
-sudo sudo dnf -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
+# Install the repository RPM (for RHEL/CentOS 9):
+sudo dnf -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
{:copy-code}
```
-* **For CentOS/RHEL 9:**
+* **For RHEL/CentOS 10:**
```bash
-# Install the repository RPM (for CentOS 9):
-sudo dnf -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
+# Install the repository RPM (for RHEL/CentOS 10):
+sudo dnf -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm
{:copy-code}
```
@@ -91,8 +93,8 @@ sudo -u postgres psql -c "\password"
Then, enter and confirm the password.
-Since ThingsBoard Edge uses the PostgreSQL database for local storage, configuring MD5 authentication ensures that only authenticated users or
-applications can access the database, thus protecting your data. After configuring the password,
+Since ThingsBoard Edge uses the PostgreSQL database for local storage, configuring MD5 authentication ensures that only authenticated users or
+applications can access the database, thus protecting your data. After configuring the password,
edit the pg_hba.conf file to use MD5 hashing for authentication instead of the default method (ident) for local IPv4 connections.
To replace ident with md5, run the following command:
@@ -102,7 +104,7 @@ sudo sed -i 's/^host\s\+all\s\+all\s\+127\.0\.0\.1\/32\s\+ident/host all
{:copy-code}
```
-Then run the command that will restart the PostgreSQL service to apply configuration changes, connect to the database as a postgres user,
+Then run the command that will restart the PostgreSQL service to apply configuration changes, connect to the database as a postgres user,
and create the ThingsBoard Edge database (tb_edge). To connect to the PostgreSQL database, enter the PostgreSQL password.
```bash
diff --git a/application/src/main/data/json/edge/instructions/install/ubuntu/instructions.md b/application/src/main/data/json/edge/instructions/install/ubuntu/instructions.md
index b4782dd46a..6f74c09c08 100644
--- a/application/src/main/data/json/edge/instructions/install/ubuntu/instructions.md
+++ b/application/src/main/data/json/edge/instructions/install/ubuntu/instructions.md
@@ -1,14 +1,16 @@
Here is the list of commands that can be used to quickly install ThingsBoard Edge on Ubuntu Server and connect to the server.
-#### Step 1. Install Java 17 (OpenJDK)
-ThingsBoard service is running on Java 17. To install OpenJDK 17, follow these instructions:
+**Note:** OpenJDK 25 requires Ubuntu 22.04 LTS or newer. Earlier versions (20.04 and below) are not supported.
+
+#### Step 1. Install Java 25 (OpenJDK)
+ThingsBoard service is running on Java 25. To install OpenJDK 25, follow these instructions:
```bash
-sudo apt update && sudo apt install openjdk-17-jdk
+sudo apt update && sudo apt install openjdk-25-jdk
{:copy-code}
```
-Configure your operating system to use OpenJDK 17 by default. You can configure the default version by running the following command:
+Configure your operating system to use OpenJDK 25 by default. You can configure the default version by running the following command:
```bash
sudo update-alternatives --config java
@@ -25,7 +27,7 @@ java -version
The expected result is:
```text
-openjdk version "17.x.xx"
+openjdk version "25.x.xx"
OpenJDK Runtime Environment (...)
OpenJDK 64-Bit Server VM (build ...)
```
diff --git a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java
index 67e4ba8f32..76caa4d53c 100644
--- a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java
+++ b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java
@@ -2355,7 +2355,8 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest {
expected.put("date_1", d1.toString());
TbDate d2 = new TbDate(2023, 8, 6, 4, 4, 5, "Europe/Berlin");
expected.put("dLocal_2", d2.toLocaleString());
- expected.put("dLocal_2_us", "8/5/23, 10:04:05 PM");
+ // Java 21+ uses narrow no-break space (U+202F) before AM/PM per CLDR 42+
+ expected.put("dLocal_2_us", Runtime.version().feature() >= 21 ? "8/5/23, 10:04:05\u202FPM" : "8/5/23, 10:04:05 PM");
expected.put("dIso_2", d2.toISOString());
expected.put("date_2", d2.toString());
Object actual = invokeScript(evalScript(decoderStr), msgStr);
@@ -2387,7 +2388,8 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest {
""", s2);
LinkedHashMap expected = new LinkedHashMap<>();
TbDate d1 = new TbDate(2023, 8, 6, 4, 4, 5);
- expected.put("dLocal_1_us", "8/6/23, 4:04:05 AM");
+ // Java 21+ uses narrow no-break space (U+202F) before AM/PM per CLDR 42+
+ expected.put("dLocal_1_us", Runtime.version().feature() >= 21 ? "8/6/23, 4:04:05\u202FAM" : "8/6/23, 4:04:05 AM");
expected.put("dIso_1", d1.toISOString());
expected.put("d1", d1.toString());
TbDate d2 = new TbDate(s2);
@@ -2419,7 +2421,8 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest {
TbDate d = new TbDate(2023, 8, 6, 4, 4, 5, "Europe/Berlin");
expected.put("dIso", d.toISOString());
expected.put("dLocal_utc", d.toLocaleString("UTC"));
- expected.put("dLocal_us", "8/5/23, 10:04:05 PM");
+ // Java 21+ uses narrow no-break space (U+202F) before AM/PM per CLDR 42+
+ expected.put("dLocal_us", Runtime.version().feature() >= 21 ? "8/5/23, 10:04:05\u202FPM" : "8/5/23, 10:04:05 PM");
expected.put("dLocal_de", "06.08.23, 04:04:05");
Object actual = invokeScript(evalScript(decoderStr), msgStr);
assertEquals(expected, actual);
diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java
index 3529c94ee4..494eb64cde 100644
--- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java
+++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java
@@ -209,7 +209,9 @@ class TbDateTest {
.put("timeZone", "America/New_York")
.put("dateStyle", "full")
.toString()));
- Assertions.assertEquals("середа, 6 вересня 2023 р.", d.toLocaleDateString("uk-UA", JacksonUtil.newObjectNode()
+ // Java 21+ uses narrow no-break space (U+202F) before "р." per CLDR 42+
+ String expectedDate_ukUA = Runtime.version().feature() >= 21 ? "середа, 6 вересня 2023\u202Fр." : "середа, 6 вересня 2023 р.";
+ Assertions.assertEquals(expectedDate_ukUA, d.toLocaleDateString("uk-UA", JacksonUtil.newObjectNode()
.put("timeZone", "Europe/Kiev")
.put("dateStyle", "full")
.toString()));
@@ -244,12 +246,18 @@ class TbDateTest {
Assertions.assertNotNull(d.toLocaleTimeString());
Assertions.assertNotNull(d.toLocaleTimeString("en-US"));
- Assertions.assertEquals("9:04:05 PM", d.toLocaleTimeString("en-US", "America/New_York"));
+ // Java 21+ uses narrow no-break space (U+202F) before AM/PM per CLDR 42+
+ String expectedTime_enUS = Runtime.version().feature() >= 21 ? "9:04:05\u202FPM" : "9:04:05 PM";
+ Assertions.assertEquals(expectedTime_enUS, d.toLocaleTimeString("en-US", "America/New_York"));
Assertions.assertEquals("오후 9:04:05", d.toLocaleTimeString("ko-KR", "America/New_York"));
Assertions.assertEquals("04:04:05", d.toLocaleTimeString( "uk-UA", "Europe/Kiev"));
Assertions.assertEquals("9:04:05 م", d.toLocaleTimeString( "ar-EG", "America/New_York"));
- Assertions.assertEquals("9:04:05 PM Eastern Daylight Time", d.toLocaleTimeString("en-US", JacksonUtil.newObjectNode()
+ // Java 21+ uses narrow no-break space (U+202F) before AM/PM per CLDR 42+
+ String expectedFullTime_enUS = Runtime.version().feature() >= 21
+ ? "9:04:05\u202FPM Eastern Daylight Time"
+ : "9:04:05 PM Eastern Daylight Time";
+ Assertions.assertEquals(expectedFullTime_enUS, d.toLocaleTimeString("en-US", JacksonUtil.newObjectNode()
.put("timeZone", "America/New_York")
.put("timeStyle", "full")
.toString()));
@@ -292,14 +300,27 @@ class TbDateTest {
Assertions.assertNotNull(d.toLocaleString());
Assertions.assertNotNull(d.toLocaleString("en-US"));
- Assertions.assertEquals("9/5/23, 9:04:05 PM", d.toLocaleString("en-US", "America/New_York"));
+ // Java 21+ uses narrow no-break space (U+202F) before AM/PM per CLDR 42+
+ String expectedLocale_enUS = Runtime.version().feature() >= 21 ? "9/5/23, 9:04:05\u202FPM" : "9/5/23, 9:04:05 PM";
+ Assertions.assertEquals(expectedLocale_enUS, d.toLocaleString("en-US", "America/New_York"));
Assertions.assertEquals("23. 9. 5. 오후 9:04:05", d.toLocaleString("ko-KR", "America/New_York"));
Assertions.assertEquals("06.09.23, 04:04:05", d.toLocaleString( "uk-UA", "Europe/Kiev"));
- String expected_ver = Runtime.version().feature() == 11 ? "5\u200F/9\u200F/2023 9:04:05 م" :
- "5\u200F/9\u200F/2023, 9:04:05 م";
- Assertions.assertEquals(expected_ver, d.toLocaleString( "ar-EG", "America/New_York"));
+ // Java 11 has no comma, Java 17 uses ASCII comma, Java 21+ uses Arabic comma (U+060C)
+ String expected_ar;
+ if (Runtime.version().feature() == 11) {
+ expected_ar = "5\u200F/9\u200F/2023 9:04:05 م";
+ } else if (Runtime.version().feature() >= 21) {
+ expected_ar = "5\u200F/9\u200F/2023\u060C 9:04:05 م";
+ } else {
+ expected_ar = "5\u200F/9\u200F/2023, 9:04:05 م";
+ }
+ Assertions.assertEquals(expected_ar, d.toLocaleString( "ar-EG", "America/New_York"));
- Assertions.assertEquals("Tuesday, September 5, 2023 at 9:04:05 PM Eastern Daylight Time", d.toLocaleString("en-US", JacksonUtil.newObjectNode()
+ // Java 21+ changed "at" to "," and uses NNBSP before AM/PM per CLDR 42+
+ String expected_enUS_full = Runtime.version().feature() >= 21
+ ? "Tuesday, September 5, 2023, 9:04:05\u202FPM Eastern Daylight Time"
+ : "Tuesday, September 5, 2023 at 9:04:05 PM Eastern Daylight Time";
+ Assertions.assertEquals(expected_enUS_full, d.toLocaleString("en-US", JacksonUtil.newObjectNode()
.put("timeZone", "America/New_York")
.put("dateStyle", "full")
.put("timeStyle", "full")
@@ -309,15 +330,26 @@ class TbDateTest {
.put("dateStyle", "full")
.put("timeStyle", "full")
.toString()));
- Assertions.assertEquals("середа, 6 вересня 2023 р. о 04:04:05 за східноєвропейським літнім часом", d.toLocaleString("uk-UA", JacksonUtil.newObjectNode()
+ // Java 21+ changed Ukrainian locale: "о" replaced with "," and NNBSP before "р." per CLDR 42+
+ String expected_ukUA_full_summer = Runtime.version().feature() >= 21
+ ? "середа, 6 вересня 2023\u202Fр., 04:04:05 за східноєвропейським літнім часом"
+ : "середа, 6 вересня 2023 р. о 04:04:05 за східноєвропейським літнім часом";
+ Assertions.assertEquals(expected_ukUA_full_summer, d.toLocaleString("uk-UA", JacksonUtil.newObjectNode()
.put("timeZone", "Europe/Kiev")
.put("dateStyle", "full")
.put("timeStyle", "full")
.toString()));
- expected_ver = Runtime.version().feature() == 11 ? "الثلاثاء، 5 سبتمبر 2023 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية" :
- "الثلاثاء، 5 سبتمبر 2023 في 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية";
- Assertions.assertEquals(expected_ver, d.toLocaleString("ar-EG", JacksonUtil.newObjectNode()
+ // Java 11 has no connector, Java 17 uses "في", Java 21+ uses Arabic comma "،"
+ String expected_ar_full;
+ if (Runtime.version().feature() == 11) {
+ expected_ar_full = "الثلاثاء، 5 سبتمبر 2023 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية";
+ } else if (Runtime.version().feature() >= 21) {
+ expected_ar_full = "الثلاثاء، 5 سبتمبر 2023\u060C 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية";
+ } else {
+ expected_ar_full = "الثلاثاء، 5 سبتمبر 2023 في 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية";
+ }
+ Assertions.assertEquals(expected_ar_full, d.toLocaleString("ar-EG", JacksonUtil.newObjectNode()
.put("timeZone", "America/New_York")
.put("dateStyle", "full")
.put("timeStyle", "full")
@@ -825,16 +857,44 @@ class TbDateTest {
@Test
public void toStringAsJs() {
TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"-04:00");
- Assertions.assertEquals("четвер, 1 січня 1976 р. о 06:15:30 за східноєвропейським стандартним часом", d1.toString("uk-UA", "Europe/Kyiv"));
- Assertions.assertEquals("Thursday, January 1, 1976 at 6:15:30 AM Eastern European Standard Time", d1.toString("en-US", "Europe/Kyiv"));
- Assertions.assertEquals("1976 Jan 1, Thu 06:15:30 Eastern European Time", d1.toString("UTC", "Europe/Kyiv"));
- Assertions.assertEquals("Wednesday, December 31, 1975 at 10:15:30 PM Eastern Standard Time", d1.toString("en-US", "America/New_York"));
- Assertions.assertEquals("1975 Dec 31, Wed 22:15:30 Eastern Standard Time", d1.toString("GMT", "America/New_York"));
- Assertions.assertEquals("1975 Dec 31, Wed 22:15:30 Eastern Standard Time", d1.toString("UTC", "America/New_York"));
+ // Java 21+ changed Ukrainian locale: "о" (at) replaced with "," and NNBSP before "р." per CLDR 42+
+ String expected_ukUA_full = Runtime.version().feature() >= 21
+ ? "четвер, 1 січня 1976\u202Fр., 06:15:30 за східноєвропейським стандартним часом"
+ : "четвер, 1 січня 1976 р. о 06:15:30 за східноєвропейським стандартним часом";
+ Assertions.assertEquals(expected_ukUA_full, d1.toString("uk-UA", "Europe/Kyiv"));
+ // Java 21+ changed "at" to "," and uses NNBSP before AM/PM per CLDR 42+
+ String expected_enUS_Kyiv = Runtime.version().feature() >= 21
+ ? "Thursday, January 1, 1976, 6:15:30\u202FAM Eastern European Standard Time"
+ : "Thursday, January 1, 1976 at 6:15:30 AM Eastern European Standard Time";
+ Assertions.assertEquals(expected_enUS_Kyiv, d1.toString("en-US", "Europe/Kyiv"));
+ // Java 21+ changed timezone display for UTC locale
+ String expected_UTC_Kyiv = Runtime.version().feature() >= 21
+ ? "1976 Jan 1, Thu 06:15:30 Kyiv (+0)"
+ : "1976 Jan 1, Thu 06:15:30 Eastern European Time";
+ Assertions.assertEquals(expected_UTC_Kyiv, d1.toString("UTC", "Europe/Kyiv"));
+ // Java 21+ changed "at" to "," and uses NNBSP before AM/PM per CLDR 42+
+ String expected_enUS_NY = Runtime.version().feature() >= 21
+ ? "Wednesday, December 31, 1975, 10:15:30\u202FPM Eastern Standard Time"
+ : "Wednesday, December 31, 1975 at 10:15:30 PM Eastern Standard Time";
+ Assertions.assertEquals(expected_enUS_NY, d1.toString("en-US", "America/New_York"));
+ // Java 21+ changed timezone display for GMT/UTC locales
+ String expected_GMT_NY = Runtime.version().feature() >= 21
+ ? "1975 Dec 31, Wed 22:15:30 New York (+0)"
+ : "1975 Dec 31, Wed 22:15:30 Eastern Standard Time";
+ Assertions.assertEquals(expected_GMT_NY, d1.toString("GMT", "America/New_York"));
+ Assertions.assertEquals(expected_GMT_NY, d1.toString("UTC", "America/New_York"));
Assertions.assertEquals(d1.toUTCString("UTC"), d1.toUTCString());
- Assertions.assertEquals("четвер, 1 січня 1976 р., 03:15:30", d1.toUTCString("uk-UA"));
- Assertions.assertEquals("Thursday, January 1, 1976, 3:15:30 AM", d1.toUTCString("en-US"));
+ // Java 21+ uses NNBSP before "р." per CLDR 42+
+ String expected_ukUA_utc = Runtime.version().feature() >= 21
+ ? "четвер, 1 січня 1976\u202Fр., 03:15:30"
+ : "четвер, 1 січня 1976 р., 03:15:30";
+ Assertions.assertEquals(expected_ukUA_utc, d1.toUTCString("uk-UA"));
+ // Java 21+ uses NNBSP before AM/PM per CLDR 42+
+ String expected_enUS_utc = Runtime.version().feature() >= 21
+ ? "Thursday, January 1, 1976, 3:15:30\u202FAM"
+ : "Thursday, January 1, 1976, 3:15:30 AM";
+ Assertions.assertEquals(expected_enUS_utc, d1.toUTCString("en-US"));
Assertions.assertEquals("1976-01-01T03:15:30.567Z", d1.toJSON());
Assertions.assertEquals("1976-01-01T03:15:30.567Z", d1.toISOString());
@@ -842,22 +902,44 @@ class TbDateTest {
Assertions.assertEquals("1976-01-01 06:15:30", d1.toLocaleString("UTC", "Europe/Kyiv"));
Assertions.assertEquals("01.01.76, 06:15:30", d1.toLocaleString("uk-UA", "Europe/Kyiv"));
Assertions.assertEquals("1975-12-31 22:15:30", d1.toLocaleString("UTC", "America/New_York"));
- Assertions.assertEquals("12/31/75, 10:15:30 PM", d1.toLocaleString("en-US", "America/New_York"));
+ // Java 21+ uses NNBSP before AM/PM per CLDR 42+
+ String expected_enUS_locale_NY = Runtime.version().feature() >= 21
+ ? "12/31/75, 10:15:30\u202FPM"
+ : "12/31/75, 10:15:30 PM";
+ Assertions.assertEquals(expected_enUS_locale_NY, d1.toLocaleString("en-US", "America/New_York"));
Assertions.assertEquals("1976 Jan 1, Thu", d1.toDateString("UTC", "Europe/Kyiv"));
- Assertions.assertEquals("четвер, 1 січня 1976 р.", d1.toDateString("uk-UA", "Europe/Kyiv"));
+ // Java 21+ uses NNBSP before "р." per CLDR 42+
+ String expected_ukUA_date = Runtime.version().feature() >= 21
+ ? "четвер, 1 січня 1976\u202Fр."
+ : "четвер, 1 січня 1976 р.";
+ Assertions.assertEquals(expected_ukUA_date, d1.toDateString("uk-UA", "Europe/Kyiv"));
Assertions.assertEquals("1975 Dec 31, Wed", d1.toDateString("UTC", "America/New_York"));
Assertions.assertEquals("Wednesday, December 31, 1975", d1.toDateString("en-US", "America/New_York"));
Assertions.assertEquals("06:15:30", d1.toLocaleTimeString("uk-UA", "Europe/Kyiv"));
Assertions.assertEquals("06:15:30", d1.toLocaleTimeString("UTC", "Europe/Kyiv"));
- Assertions.assertEquals("10:15:30 PM", d1.toLocaleTimeString("en-US", "America/New_York"));
+ // Java 21+ uses NNBSP before AM/PM per CLDR 42+
+ String expected_enUS_time = Runtime.version().feature() >= 21 ? "10:15:30\u202FPM" : "10:15:30 PM";
+ Assertions.assertEquals(expected_enUS_time, d1.toLocaleTimeString("en-US", "America/New_York"));
Assertions.assertEquals("22:15:30", d1.toLocaleTimeString("UTC", "America/New_York"));
Assertions.assertEquals("06:15:30 за східноєвропейським стандартним часом", d1.toTimeString("uk-UA", "Europe/Kyiv"));
- Assertions.assertEquals("06:15:30 Eastern European Time", d1.toTimeString("UTC", "Europe/Kyiv"));
- Assertions.assertEquals("10:15:30 PM Eastern Standard Time", d1.toTimeString("en-US", "America/New_York"));
- Assertions.assertEquals("22:15:30 Eastern Standard Time", d1.toTimeString("UTC", "America/New_York"));
+ // Java 21+ changed timezone display for UTC locale
+ String expected_UTC_time_Kyiv = Runtime.version().feature() >= 21
+ ? "06:15:30 Kyiv (+0)"
+ : "06:15:30 Eastern European Time";
+ Assertions.assertEquals(expected_UTC_time_Kyiv, d1.toTimeString("UTC", "Europe/Kyiv"));
+ // Java 21+ uses NNBSP before AM/PM per CLDR 42+
+ String expected_enUS_timeStr = Runtime.version().feature() >= 21
+ ? "10:15:30\u202FPM Eastern Standard Time"
+ : "10:15:30 PM Eastern Standard Time";
+ Assertions.assertEquals(expected_enUS_timeStr, d1.toTimeString("en-US", "America/New_York"));
+ // Java 21+ changed timezone display for UTC locale
+ String expected_UTC_time_NY = Runtime.version().feature() >= 21
+ ? "22:15:30 New York (+0)"
+ : "22:15:30 Eastern Standard Time";
+ Assertions.assertEquals(expected_UTC_time_NY, d1.toTimeString("UTC", "America/New_York"));
}
@Test
diff --git a/common/util/src/main/java/org/thingsboard/common/util/ThingsBoardThreadFactory.java b/common/util/src/main/java/org/thingsboard/common/util/ThingsBoardThreadFactory.java
index a6218b2eb8..272e44ba7e 100644
--- a/common/util/src/main/java/org/thingsboard/common/util/ThingsBoardThreadFactory.java
+++ b/common/util/src/main/java/org/thingsboard/common/util/ThingsBoardThreadFactory.java
@@ -33,9 +33,7 @@ public class ThingsBoardThreadFactory implements ThreadFactory {
}
private ThingsBoardThreadFactory(String name) {
- SecurityManager s = System.getSecurityManager();
- group = (s != null) ? s.getThreadGroup() :
- Thread.currentThread().getThreadGroup();
+ group = Thread.currentThread().getThreadGroup();
namePrefix = name + "-" +
poolNumber.getAndIncrement() +
"-thread-";
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java
index f812d13f65..67e71ebcdf 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java
@@ -98,10 +98,8 @@ public interface AlarmRepository extends JpaRepository {
"AND ea.entityType = :affectedEntityType " +
"AND (:startTime IS NULL OR (a.createdTime >= :startTime AND ea.createdTime >= :startTime)) " +
"AND (:endTime IS NULL OR (a.createdTime <= :endTime AND ea.createdTime <= :endTime)) " +
- "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968
- "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968
-// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
-// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
+ "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
+ "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
"AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " +
"AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " +
"AND (:assigneeId IS NULL OR a.assigneeId = :assigneeId) " +
@@ -119,10 +117,8 @@ public interface AlarmRepository extends JpaRepository {
"AND ea.entityType = :affectedEntityType " +
"AND (:startTime IS NULL OR (a.createdTime >= :startTime AND ea.createdTime >= :startTime)) " +
"AND (:endTime IS NULL OR (a.createdTime <= :endTime AND ea.createdTime <= :endTime)) " +
- "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968
- "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968
-// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
-// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
+ "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
+ "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
"AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " +
"AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " +
"AND (:assigneeId IS NULL OR a.assigneeId = :assigneeId) " +
@@ -183,10 +179,8 @@ public interface AlarmRepository extends JpaRepository {
"WHERE a.tenantId = :tenantId " +
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
- "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968
- "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968
-// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
-// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
+ "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
+ "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
"AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " +
"AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " +
"AND (:assigneeId IS NULL OR a.assigneeId = :assigneeId) " +
@@ -199,10 +193,8 @@ public interface AlarmRepository extends JpaRepository {
"WHERE a.tenantId = :tenantId " +
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
- "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968
- "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968
-// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
-// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
+ "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
+ "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
"AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " +
"AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " +
"AND (:assigneeId IS NULL OR a.assigneeId = :assigneeId) " +
@@ -263,10 +255,8 @@ public interface AlarmRepository extends JpaRepository {
"WHERE a.tenantId = :tenantId AND a.customerId = :customerId " +
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
- "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968
- "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968
-// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
-// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
+ "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
+ "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
"AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " +
"AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " +
"AND (:assigneeId IS NULL OR a.assigneeId = :assigneeId) " +
@@ -280,10 +270,8 @@ public interface AlarmRepository extends JpaRepository {
"WHERE a.tenantId = :tenantId AND a.customerId = :customerId " +
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
- "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968
- "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968
-// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
-// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
+ "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " +
+ "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " +
"AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " +
"AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " +
"AND (:assigneeId IS NULL OR a.assigneeId = :assigneeId) " +
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/audit/AuditLogRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/audit/AuditLogRepository.java
index d685d9ee78..4266003706 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/audit/AuditLogRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/audit/AuditLogRepository.java
@@ -33,8 +33,7 @@ public interface AuditLogRepository extends JpaRepository
"a.tenantId = :tenantId " +
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
- "AND ((:#{#actionTypes == null} = true) OR a.actionType IN (:actionTypes)) " + //HHH-15968
-// "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " +
+ "AND ((:actionTypes) IS NULL OR a.actionType IN (:actionTypes)) " +
"AND (:textSearch IS NULL OR ilike(a.entityType, CONCAT('%', :textSearch, '%')) = true " +
"OR ilike(a.entityName, CONCAT('%', :textSearch, '%')) = true " +
"OR ilike(a.userName, CONCAT('%', :textSearch, '%')) = true " +
@@ -54,8 +53,7 @@ public interface AuditLogRepository extends JpaRepository
"AND a.entityType = :entityType AND a.entityId = :entityId " +
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
- "AND ((:#{#actionTypes == null} = true) OR a.actionType IN (:actionTypes)) " + //HHH-15968
-// "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " +
+ "AND ((:actionTypes) IS NULL OR a.actionType IN (:actionTypes)) " +
"AND (:textSearch IS NULL OR ilike(a.entityName, CONCAT('%', :textSearch, '%')) = true " +
"OR ilike(a.userName, CONCAT('%', :textSearch, '%')) = true " +
"OR ilike(a.actionType, CONCAT('%', :textSearch, '%')) = true " +
@@ -75,8 +73,7 @@ public interface AuditLogRepository extends JpaRepository
"AND a.customerId = :customerId " +
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
- "AND ((:#{#actionTypes == null} = true) OR a.actionType IN (:actionTypes)) " + //HHH-15968
-// "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " +
+ "AND ((:actionTypes) IS NULL OR a.actionType IN (:actionTypes)) " +
"AND (:textSearch IS NULL OR ilike(a.entityType, CONCAT('%', :textSearch, '%')) = true " +
"OR ilike(a.entityName, CONCAT('%', :textSearch, '%')) = true " +
"OR ilike(a.userName, CONCAT('%', :textSearch, '%')) = true " +
@@ -96,8 +93,7 @@ public interface AuditLogRepository extends JpaRepository
"AND a.userId = :userId " +
"AND (:startTime IS NULL OR a.createdTime >= :startTime) " +
"AND (:endTime IS NULL OR a.createdTime <= :endTime) " +
- "AND ((:#{#actionTypes == null} = true) OR a.actionType IN (:actionTypes)) " + //HHH-15968
-// "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " +
+ "AND ((:actionTypes) IS NULL OR a.actionType IN (:actionTypes)) " +
"AND (:textSearch IS NULL OR ilike(a.entityType, CONCAT('%', :textSearch, '%')) = true " +
"OR ilike(a.entityName, CONCAT('%', :textSearch, '%')) = true " +
"OR ilike(a.actionType, CONCAT('%', :textSearch, '%')) = true " +
diff --git a/msa/tb/docker-cassandra/Dockerfile b/msa/tb/docker-cassandra/Dockerfile
index 34a90e6fb7..358f2907c8 100644
--- a/msa/tb/docker-cassandra/Dockerfile
+++ b/msa/tb/docker-cassandra/Dockerfile
@@ -14,7 +14,7 @@
# limitations under the License.
#
-FROM thingsboard/openjdk17:bookworm-slim
+FROM thingsboard/openjdk25:trixie-slim
ENV PG_MAJOR=16
@@ -44,15 +44,14 @@ COPY logback.xml ${pkg.name}.conf start-db.sh stop-db.sh start-tb.sh upgrade-tb.
RUN apt-get update \
&& apt-get install -y --no-install-recommends wget nmap procps gnupg2 \
- && echo "deb http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null \
- && wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O- | apt-key add - \
- && echo "deb https://debian.cassandra.apache.org 40x main" | tee -a /etc/apt/sources.list.d/cassandra.sources.list > /dev/null \
- && wget -q https://downloads.apache.org/cassandra/KEYS -O- | apt-key add - \
+ && mkdir -p /etc/apt/keyrings \
+ && wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O- | gpg --dearmor -o /etc/apt/keyrings/postgresql.gpg \
+ && echo "deb [signed-by=/etc/apt/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list > /dev/null \
+ && wget -q https://downloads.apache.org/cassandra/KEYS -O- | gpg --dearmor -o /etc/apt/keyrings/cassandra.gpg \
+ && echo "deb [signed-by=/etc/apt/keyrings/cassandra.gpg] https://debian.cassandra.apache.org 40x main" | tee /etc/apt/sources.list.d/cassandra.sources.list > /dev/null \
&& apt-get update \
&& apt-get install -y --no-install-recommends cassandra cassandra-tools postgresql-${PG_MAJOR} \
&& rm -rf /var/lib/apt/lists/* \
- && update-rc.d cassandra disable \
- && update-rc.d postgresql disable \
&& apt-get purge -y --auto-remove \
&& sed -i.old '/ulimit/d' /etc/init.d/cassandra \
&& chmod a+x /tmp/*.sh \
diff --git a/msa/tb/docker-postgres/Dockerfile b/msa/tb/docker-postgres/Dockerfile
index 0a0f61f904..6ce066d1ed 100644
--- a/msa/tb/docker-postgres/Dockerfile
+++ b/msa/tb/docker-postgres/Dockerfile
@@ -14,7 +14,7 @@
# limitations under the License.
#
-FROM thingsboard/openjdk17:bookworm-slim
+FROM thingsboard/openjdk25:trixie-slim
ENV PG_MAJOR 12
@@ -36,12 +36,12 @@ COPY logback.xml ${pkg.name}.conf start-db.sh stop-db.sh start-tb.sh upgrade-tb.
RUN apt-get update \
&& apt-get install -y --no-install-recommends wget gnupg2 \
- && echo "deb http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null \
- && wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O- | apt-key add - \
+ && mkdir -p /etc/apt/keyrings \
+ && wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O- | gpg --dearmor -o /etc/apt/keyrings/postgresql.gpg \
+ && echo "deb [signed-by=/etc/apt/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list > /dev/null \
&& apt-get update \
&& apt-get install -y --no-install-recommends postgresql-${PG_MAJOR} \
&& rm -rf /var/lib/apt/lists/* \
- && update-rc.d postgresql disable \
&& apt-get purge -y --auto-remove \
&& chmod a+x /tmp/*.sh \
&& mv /tmp/start-tb.sh /usr/bin \
diff --git a/packaging/java/build.gradle b/packaging/java/build.gradle
index 5ef4576a91..6bd28968e9 100644
--- a/packaging/java/build.gradle
+++ b/packaging/java/build.gradle
@@ -16,12 +16,14 @@
import org.apache.tools.ant.filters.ReplaceTokens
plugins {
- id "nebula.ospackage" version "8.6.3"
+ id "com.netflix.nebula.ospackage" version "12.1.1"
}
buildDir = projectBuildDir
version = projectVersion
-distsDirName = "./"
+base {
+ distsDirectory = layout.buildDirectory.dir("./")
+}
// OS Package plugin configuration
ospackage {
@@ -33,8 +35,8 @@ ospackage {
into pkgInstallFolder
- user pkgUser
- permissionGroup pkgUser
+ user = pkgUser
+ permissionGroup = pkgUser
// Copy the actual .jar file
from(mainJar) {
@@ -42,19 +44,25 @@ ospackage {
rename { String fileName ->
"${pkgName}.jar"
}
- fileMode 0500
+ filePermissions {
+ unix('r-x------') // 0500
+ }
into "bin"
}
if("${pkgCopyInstallScripts}".equalsIgnoreCase("true")) {
// Copy the install files
from("${buildDir}/bin/install/install.sh") {
- fileMode 0775
+ filePermissions {
+ unix('rwxrwxr-x') // 0775
+ }
into "bin/install"
}
from("${buildDir}/bin/install/upgrade.sh") {
- fileMode 0775
+ filePermissions {
+ unix('rwxrwxr-x') // 0775
+ }
into "bin/install"
}
@@ -67,14 +75,18 @@ ospackage {
from("${buildDir}/conf") {
exclude "${pkgName}.conf"
fileType CONFIG | NOREPLACE
- fileMode 0754
+ filePermissions {
+ unix('rwxr-xr--') // 0754
+ }
into "conf"
}
// Copy the data files
from("${buildDir}/data") {
fileType CONFIG | NOREPLACE
- fileMode 0754
+ filePermissions {
+ unix('rwxr-xr--') // 0754
+ }
into "data"
}
@@ -92,7 +104,7 @@ buildRpm {
archiveVersion = projectVersion.replace('-', '')
archiveFileName = "${pkgName}.rpm"
- // Support Java 17 (existing), plus Java 21 and Java 25 for RPM-based distros
+ // Support Java 25 (current), plus Java 21 and Java 17 (backward compatibility) for RPM-based distros
// Keep using RPM boolean expression syntax since .or() chaining is for DEB only
requires("(java-17 or java-17-headless or jre-17 or jre-17-headless or " +
"java-21 or java-21-headless or jre-21 or jre-21-headless or " +
@@ -102,7 +114,9 @@ buildRpm {
include "${pkgName}.conf"
filter(ReplaceTokens, tokens: ['pkg.platform': 'rpm'])
fileType CONFIG | NOREPLACE
- fileMode 0754
+ filePermissions {
+ unix('rwxr-xr--') // 0754
+ }
into "${pkgInstallFolder}/conf"
}
@@ -111,13 +125,15 @@ buildRpm {
preUninstall file("${buildDir}/control/rpm/prerm")
postUninstall file("${buildDir}/control/rpm/postrm")
- user pkgUser
- permissionGroup pkgUser
+ user = pkgUser
+ permissionGroup = pkgUser
// Copy the system unit files
from("${buildDir}/control/template.service") {
addParentDirs = false
- fileMode 0644
+ filePermissions {
+ unix('rw-r--r--') // 0644
+ }
into "/usr/lib/systemd/system"
rename { String filename ->
"${pkgName}.service"
@@ -143,7 +159,9 @@ buildDeb {
include "${pkgName}.conf"
filter(ReplaceTokens, tokens: ['pkg.platform': 'deb'])
fileType CONFIG | NOREPLACE
- fileMode 0754
+ filePermissions {
+ unix('rwxr-xr--') // 0754
+ }
into "${pkgInstallFolder}/conf"
}
@@ -157,13 +175,15 @@ buildDeb {
preUninstall file("${buildDir}/control/deb/prerm")
postUninstall file("${buildDir}/control/deb/postrm")
- user pkgUser
- permissionGroup pkgUser
+ user = pkgUser
+ permissionGroup = pkgUser
// Copy the system unit files
from("${buildDir}/control/template.service") {
addParentDirs = false
- fileMode 0644
+ filePermissions {
+ unix('rw-r--r--') // 0644
+ }
into "/lib/systemd/system"
rename { String filename ->
"${pkgName}.service"
diff --git a/packaging/java/scripts/windows/install.bat b/packaging/java/scripts/windows/install.bat
index ca17408dfe..566286d4b5 100644
--- a/packaging/java/scripts/windows/install.bat
+++ b/packaging/java/scripts/windows/install.bat
@@ -7,11 +7,11 @@ setlocal ENABLEEXTENSIONS
for /f tokens^=2-5^ delims^=.-_^" %%j in ('java -fullversion 2^>^&1') do set "jver=%%j%%k"
@ECHO CurrentVersion %jver%
-if %jver% NEQ 170 GOTO JAVA_NOT_INSTALLED
+if %jver% NEQ 250 GOTO JAVA_NOT_INSTALLED
:JAVA_INSTALLED
-@ECHO Java 17 found!
+@ECHO Java 25 found!
@ECHO Installing thingsboard ...
SET loadDemo=false
@@ -50,8 +50,8 @@ POPD
GOTO END
:JAVA_NOT_INSTALLED
-@ECHO Java 17 is not installed. Only Java 17 is supported
-@ECHO Please go to https://adoptopenjdk.net/index.html and install Java 17. Then retry installation.
+@ECHO Java 25 is not installed. Only Java 25 is supported
+@ECHO Please go to https://adoptopenjdk.net/index.html and install Java 25. Then retry installation.
PAUSE
GOTO END
diff --git a/packaging/js/build.gradle b/packaging/js/build.gradle
index 15b8e546a1..13a2779f34 100644
--- a/packaging/js/build.gradle
+++ b/packaging/js/build.gradle
@@ -13,15 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import org.apache.tools.ant.filters.ReplaceTokens
plugins {
- id "nebula.ospackage" version "8.6.3"
+ id "com.netflix.nebula.ospackage" version "12.1.1"
}
buildDir = projectBuildDir
version = projectVersion
-distsDirName = "./"
+base {
+ distsDirectory = layout.buildDirectory.dir("./")
+}
// OS Package plugin configuration
ospackage {
@@ -33,18 +34,22 @@ ospackage {
into pkgInstallFolder
- user pkgUser
- permissionGroup pkgUser
+ user = pkgUser
+ permissionGroup = pkgUser
// Copy the executable file
from("${buildDir}/package/linux/bin/${pkgName}") {
- fileMode 0500
+ filePermissions {
+ unix('r-x------') // 0500
+ }
into "bin"
}
// Copy the init file
from("${buildDir}/package/linux/init/template") {
- fileMode 0500
+ filePermissions {
+ unix('r-x------') // 0500
+ }
into "init"
rename { String filename ->
"${pkgName}"
@@ -54,7 +59,9 @@ ospackage {
// Copy the config files
from("${buildDir}/package/linux/conf") {
fileType CONFIG | NOREPLACE
- fileMode 0754
+ filePermissions {
+ unix('rwxr-xr--') // 0754
+ }
into "conf"
}
@@ -78,13 +85,15 @@ buildRpm {
preUninstall file("${buildDir}/control/rpm/prerm")
postUninstall file("${buildDir}/control/rpm/postrm")
- user pkgUser
- permissionGroup pkgUser
+ user = pkgUser
+ permissionGroup = pkgUser
// Copy the system unit files
from("${buildDir}/control/template.service") {
addParentDirs = false
- fileMode 0644
+ filePermissions {
+ unix('rw-r--r--') // 0644
+ }
into "/usr/lib/systemd/system"
rename { String filename ->
"${pkgName}.service"
@@ -111,13 +120,15 @@ buildDeb {
preUninstall file("${buildDir}/control/deb/prerm")
postUninstall file("${buildDir}/control/deb/postrm")
- user pkgUser
- permissionGroup pkgUser
+ user = pkgUser
+ permissionGroup = pkgUser
// Copy the system unit files
from("${buildDir}/control/template.service") {
addParentDirs = false
- fileMode 0644
+ filePermissions {
+ unix('rw-r--r--') // 0644
+ }
into "/lib/systemd/system"
rename { String filename ->
"${pkgName}.service"
diff --git a/pom.xml b/pom.xml
index 7e5a21e82a..45808df712 100755
--- a/pom.xml
+++ b/pom.xml
@@ -28,8 +28,8 @@
2016
- 17
- 17
+ 25
+ 25
${basedir}
true
none
@@ -65,7 +65,7 @@
3.25.5
1.76.0
1.2.8
- 1.18.38
+ 1.18.40
1.2.5
1.2.5
1.7.1
@@ -111,6 +111,7 @@
4.0.2
1.7.5
3.8.0
+ 1.18.4
1.8.0-TB
2.38.0
1.24
@@ -605,7 +606,7 @@
maven-compiler-plugin
3.11.0
- 17
+ 25
-Xlint:deprecation
-Xlint:removal
@@ -649,7 +650,7 @@
org.thingsboard
gradle-maven-plugin
- 1.0.12
+ 1.0.15
com.github.eirslett
@@ -663,6 +664,7 @@
-XX:+UseStringDeduplication -XX:MaxGCPauseMillis=200
+ -XX:+EnableDynamicAgentLoading
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
-Dqueue.edqs.local.rocksdb_path="target/rocksdb/fork_${surefire.forkNumber}/edqs"
-Dqueue.calculated_fields.rocks_db_path="target/rocksdb/fork_${surefire.forkNumber}/cf"
@@ -913,6 +915,16 @@
pom
import
+
+ net.bytebuddy
+ byte-buddy
+ ${bytebuddy.version}
+
+
+ net.bytebuddy
+ byte-buddy-agent
+ ${bytebuddy.version}
+
org.thingsboard.langchain4j
langchain4j-bom
@@ -1955,4 +1967,10 @@
+
+
+ thingsboard-repo
+ https://repo.thingsboard.io/artifactory/libs-release-public
+
+