This is an automated email from the ASF dual-hosted git repository.
tuglu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new e738c9daa5c minor: Upgrade to Hadoop 3.5 (#19273)
e738c9daa5c is described below
commit e738c9daa5ca8c660d7857cbcf7f5c6eed386d05
Author: jtuglu1 <[email protected]>
AuthorDate: Mon Apr 13 14:59:14 2026 -0700
minor: Upgrade to Hadoop 3.5 (#19273)
Upgrade to https://hadoop.apache.org/release/3.5.0.html
---
.github/workflows/worker.yml | 1 +
embedded-tests/pom.xml | 43 ++++++++-
extensions-contrib/cloudfiles-extensions/pom.xml | 6 ++
.../druid-deltalake-extensions/pom.xml | 4 +-
.../druid-exact-count-bitmap/pom.xml | 5 +
.../druid-iceberg-extensions/pom.xml | 10 +-
extensions-contrib/influx-extensions/pom.xml | 5 +
extensions-contrib/kafka-emitter/pom.xml | 5 +
extensions-contrib/momentsketch/pom.xml | 5 +
extensions-contrib/thrift-extensions/pom.xml | 5 +
extensions-core/avro-extensions/pom.xml | 5 +
extensions-core/druid-kerberos/pom.xml | 6 ++
extensions-core/hdfs-storage/pom.xml | 10 +-
extensions-core/kinesis-indexing-service/pom.xml | 1 -
extensions-core/testing-tools/pom.xml | 5 +
licenses.yaml | 107 +++++++++++++++++++++
pom.xml | 16 ++-
quidem-ut/pom.xml | 16 ++-
web-console/e2e-tests/tutorial-batch.spec.ts | 14 ++-
web-console/e2e-tests/util/retry.ts | 18 ++++
web-console/script/druid | 3 +-
21 files changed, 265 insertions(+), 25 deletions(-)
diff --git a/.github/workflows/worker.yml b/.github/workflows/worker.yml
index 6eb428b5750..eb18e219a23 100644
--- a/.github/workflows/worker.yml
+++ b/.github/workflows/worker.yml
@@ -119,3 +119,4 @@ jobs:
**/TEST-*.xml
**/target/jacoco*.exec
**/target/ci-debug/**
+ distribution/target/apache-druid-*/log/**
diff --git a/embedded-tests/pom.xml b/embedded-tests/pom.xml
index f2b30b34273..1c77fe29744 100644
--- a/embedded-tests/pom.xml
+++ b/embedded-tests/pom.xml
@@ -305,6 +305,12 @@
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
</exclusion>
+ <!-- Hadoop 3.5.0 introduced jakarta.ws.rs-api (JAX-RS 2.x) in
hadoop-hdfs-client,
+ which conflicts with Jersey 1.x's UriBuilderImpl that only
implements JAX-RS 1.x. -->
+ <exclusion>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
@@ -433,7 +439,7 @@
<version>${iceberg.version}</version>
<scope>test</scope>
<exclusions>
- <!-- Let parquet version be driven by druid-parquet-extensions
(1.15.2) -->
+ <!-- Let parquet version be driven by druid-parquet-extensions
(${parquet.version}) -->
<exclusion>
<groupId>org.apache.parquet</groupId>
<artifactId>*</artifactId>
@@ -773,7 +779,7 @@
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-avro</artifactId>
- <version>1.15.2</version>
+ <version>${parquet.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -796,6 +802,39 @@
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-hdfs-client</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>software.amazon.awssdk</groupId>
+ <artifactId>aws-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>software.amazon.awssdk</groupId>
+ <artifactId>bundle</artifactId>
+ <version>${aws.sdk.v2.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.parquet</groupId>
+ <artifactId>parquet-column</artifactId>
+ <version>${parquet.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.auth</groupId>
+ <artifactId>google-auth-library-credentials</artifactId>
+ <version>1.20.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.github.docker-java</groupId>
+ <artifactId>docker-java-transport</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/extensions-contrib/cloudfiles-extensions/pom.xml
b/extensions-contrib/cloudfiles-extensions/pom.xml
index 782743023d6..2d9d308d1f8 100644
--- a/extensions-contrib/cloudfiles-extensions/pom.xml
+++ b/extensions-contrib/cloudfiles-extensions/pom.xml
@@ -134,6 +134,12 @@
<version>${jclouds.version}</version>
</dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
<!-- Tests -->
<dependency>
<groupId>junit</groupId>
diff --git a/extensions-contrib/druid-deltalake-extensions/pom.xml
b/extensions-contrib/druid-deltalake-extensions/pom.xml
index b1b334de04a..076e92e33e2 100644
--- a/extensions-contrib/druid-deltalake-extensions/pom.xml
+++ b/extensions-contrib/druid-deltalake-extensions/pom.xml
@@ -111,8 +111,8 @@
<scope>runtime</scope>
<exclusions>
<exclusion>
- <groupId>com.amazonaws</groupId>
- <artifactId>aws-java-sdk-bundle</artifactId>
+ <groupId>software.amazon.awssdk</groupId>
+ <artifactId>bundle</artifactId>
</exclusion>
</exclusions>
</dependency>
diff --git a/extensions-contrib/druid-exact-count-bitmap/pom.xml
b/extensions-contrib/druid-exact-count-bitmap/pom.xml
index b9409fe4cdc..f5fa439fef3 100644
--- a/extensions-contrib/druid-exact-count-bitmap/pom.xml
+++ b/extensions-contrib/druid-exact-count-bitmap/pom.xml
@@ -93,6 +93,11 @@
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ <scope>provided</scope>
+ </dependency>
<!-- Test Dependencies -->
<dependency>
diff --git a/extensions-contrib/druid-iceberg-extensions/pom.xml
b/extensions-contrib/druid-iceberg-extensions/pom.xml
index 974f2ea9dc7..8ff3dc67dbf 100644
--- a/extensions-contrib/druid-iceberg-extensions/pom.xml
+++ b/extensions-contrib/druid-iceberg-extensions/pom.xml
@@ -637,6 +637,12 @@
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-common</artifactId>
</exclusion>
+ <!-- Hadoop 3.5.0 introduced jakarta.ws.rs-api (JAX-RS 2.x),
+ which conflicts with Jersey 1.x's UriBuilderImpl. -->
+ <exclusion>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
+ </exclusion>
</exclusions>
</dependency>
@@ -718,8 +724,8 @@
<scope>runtime</scope>
<exclusions>
<exclusion>
- <groupId>com.amazonaws</groupId>
- <artifactId>aws-java-sdk-bundle</artifactId>
+ <groupId>software.amazon.awssdk</groupId>
+ <artifactId>bundle</artifactId>
</exclusion>
</exclusions>
</dependency>
diff --git a/extensions-contrib/influx-extensions/pom.xml
b/extensions-contrib/influx-extensions/pom.xml
index a151fe6f056..495a24fcd72 100644
--- a/extensions-contrib/influx-extensions/pom.xml
+++ b/extensions-contrib/influx-extensions/pom.xml
@@ -75,6 +75,11 @@
<artifactId>jsr305</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ <scope>provided</scope>
+ </dependency>
<!-- Tests -->
<dependency>
diff --git a/extensions-contrib/kafka-emitter/pom.xml
b/extensions-contrib/kafka-emitter/pom.xml
index 1d022c30eb3..ddb5eb9c935 100644
--- a/extensions-contrib/kafka-emitter/pom.xml
+++ b/extensions-contrib/kafka-emitter/pom.xml
@@ -86,6 +86,11 @@
<artifactId>jackson-datatype-joda</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
diff --git a/extensions-contrib/momentsketch/pom.xml
b/extensions-contrib/momentsketch/pom.xml
index 1a2524f61e2..13a776d04b2 100644
--- a/extensions-contrib/momentsketch/pom.xml
+++ b/extensions-contrib/momentsketch/pom.xml
@@ -74,6 +74,11 @@
<artifactId>jackson-core</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>junit</groupId>
diff --git a/extensions-contrib/thrift-extensions/pom.xml
b/extensions-contrib/thrift-extensions/pom.xml
index b0d2b09c933..d2426dec715 100644
--- a/extensions-contrib/thrift-extensions/pom.xml
+++ b/extensions-contrib/thrift-extensions/pom.xml
@@ -98,6 +98,11 @@
<artifactId>commons-io</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>com.twitter</groupId>
<artifactId>scrooge-core_2.11</artifactId>
diff --git a/extensions-core/avro-extensions/pom.xml
b/extensions-core/avro-extensions/pom.xml
index 4205f008d34..007418bc8c7 100644
--- a/extensions-core/avro-extensions/pom.xml
+++ b/extensions-core/avro-extensions/pom.xml
@@ -206,6 +206,11 @@
<artifactId>json-path</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ <scope>provided</scope>
+ </dependency>
<!-- Tests -->
<dependency>
diff --git a/extensions-core/druid-kerberos/pom.xml
b/extensions-core/druid-kerberos/pom.xml
index 20d8ed91a97..f1843314434 100644
--- a/extensions-core/druid-kerberos/pom.xml
+++ b/extensions-core/druid-kerberos/pom.xml
@@ -168,6 +168,12 @@
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
</exclusion>
+ <!-- Hadoop 3.5.0 introduced jakarta.ws.rs-api (JAX-RS 2.x) via
hadoop-hdfs-client,
+ which conflicts with Jersey 1.x's UriBuilderImpl that only
implements JAX-RS 1.x. -->
+ <exclusion>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
+ </exclusion>
<exclusion>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
diff --git a/extensions-core/hdfs-storage/pom.xml
b/extensions-core/hdfs-storage/pom.xml
index 5596f9c860c..c0c1c73ffc9 100644
--- a/extensions-core/hdfs-storage/pom.xml
+++ b/extensions-core/hdfs-storage/pom.xml
@@ -48,8 +48,8 @@
<scope>runtime</scope>
<exclusions>
<exclusion>
- <groupId>com.amazonaws</groupId>
- <artifactId>aws-java-sdk-bundle</artifactId>
+ <groupId>software.amazon.awssdk</groupId>
+ <artifactId>bundle</artifactId>
</exclusion>
</exclusions>
</dependency>
@@ -160,12 +160,6 @@
<version>${hadoop.compile.version}</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>com.amazonaws</groupId>
- <artifactId>aws-java-sdk-s3</artifactId>
- <version>${aws.sdk.v1.version}</version>
- <scope>runtime</scope>
- </dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
diff --git a/extensions-core/kinesis-indexing-service/pom.xml
b/extensions-core/kinesis-indexing-service/pom.xml
index 353599f6960..0ce89c05cf8 100644
--- a/extensions-core/kinesis-indexing-service/pom.xml
+++ b/extensions-core/kinesis-indexing-service/pom.xml
@@ -116,7 +116,6 @@
<version>${aws.sdk.v2.version}</version>
<scope>provided</scope>
</dependency>
-
<!-- KCL v2 for deaggregation support -->
<dependency>
<groupId>software.amazon.kinesis</groupId>
diff --git a/extensions-core/testing-tools/pom.xml
b/extensions-core/testing-tools/pom.xml
index 33951df0562..5468fcb9836 100644
--- a/extensions-core/testing-tools/pom.xml
+++ b/extensions-core/testing-tools/pom.xml
@@ -135,6 +135,11 @@
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>com.github.rvesse</groupId>
<artifactId>airline</artifactId>
diff --git a/licenses.yaml b/licenses.yaml
index 567b0482d19..618d830d833 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -7001,3 +7001,110 @@ version: 1.4.5
copyright: Ecwid
libraries:
- com.ecwid.consul: consul-api
+
+---
+
+name: Apache Commons Text
+license_category: binary
+module: extensions-core/druid-kerberos
+license_name: Apache License version 2.0
+version: 1.14.0
+libraries:
+ - org.apache.commons: commons-text
+
+---
+
+name: Apache Hadoop
+license_category: binary
+module: extensions-core/druid-kerberos
+license_name: Apache License version 2.0
+version: 3.5.0
+libraries:
+ - org.apache.hadoop: hadoop-auth
+ - org.apache.hadoop: hadoop-common
+ - org.apache.hadoop: hadoop-client-api
+
+---
+
+name: DNS Java
+license_category: binary
+module: extensions-core/druid-kerberos
+license_name: BSD-3-Clause License
+version: 3.6.1
+libraries:
+ - dnsjava: dnsjava
+
+---
+
+name: Jakarta Servlet JSP API
+license_category: binary
+module: extensions-core/druid-kerberos
+license_name: Eclipse Public License 2.0
+version: 2.3.6
+libraries:
+ - jakarta.servlet.jsp: jakarta.servlet.jsp-api
+
+---
+
+name: Hadoop shaded
+license_category: binary
+module: extensions-core/druid-kerberos
+license_name: Apache License version 2.0
+version: 1.5.0
+libraries:
+ - org.apache.hadoop.thirdparty: hadoop-shaded-protobuf_3_25
+ - org.apache.hadoop.thirdparty: hadoop-shaded-guava
+
+---
+
+name: Kerby
+license_category: binary
+module: extensions-core/druid-kerberos
+license_name: Apache License version 2.0
+version: 2.0.3
+libraries:
+ - org.apache.kerby: kerb-core
+ - org.apache.kerby: kerb-crypto
+ - org.apache.kerby: kerb-util
+ - org.apache.kerby: kerby-asn1
+ - org.apache.kerby: kerby-config
+ - org.apache.kerby: kerby-pkix
+ - org.apache.kerby: kerby-util
+
+---
+
+name: HK2
+license_category: binary
+module: extensions-core/druid-kerberos
+license_name: Eclipse Public License 2.0
+version: 2.6.1
+libraries:
+ - org.glassfish.hk2: hk2-api
+ - org.glassfish.hk2: hk2-locator
+ - org.glassfish.hk2: hk2-utils
+ - org.glassfish.hk2.external: aopalliance-repackaged
+
+---
+
+name: Jersey
+license_category: binary
+module: extensions-core/druid-kerberos
+license_name: Eclipse Public License 2.0
+version: '2.46'
+libraries:
+ - org.glassfish.jersey.containers: jersey-container-servlet
+ - org.glassfish.jersey.containers: jersey-container-servlet-core
+ - org.glassfish.jersey.core: jersey-client
+ - org.glassfish.jersey.core: jersey-common
+ - org.glassfish.jersey.core: jersey-server
+ - org.glassfish.jersey.inject: jersey-hk2
+
+---
+
+name: Javassist
+license_category: binary
+module: extensions-core/druid-kerberos
+license_name: Apache License version 2.0
+version: 3.30.2-GA
+libraries:
+ - org.javassist: javassist
diff --git a/pom.xml b/pom.xml
index 4fa5bccfbd1..dbcf3b21112 100644
--- a/pom.xml
+++ b/pom.xml
@@ -117,7 +117,7 @@
<slf4j.version>2.0.17</slf4j.version>
<jna.version>5.18.1</jna.version>
<jna-platform.version>5.18.1</jna-platform.version>
- <hadoop.compile.version>3.3.6</hadoop.compile.version>
+ <hadoop.compile.version>3.5.0</hadoop.compile.version>
<graaljs.version>22.3.5</graaljs.version>
<mockito.version>5.23.0</mockito.version>
<!-- AWS SDK v1 is still used as a transitive dependency by Hadoop and
Ranger extensions.
@@ -353,7 +353,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
- <version>1.13.1</version>
+ <version>1.14.0</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
@@ -761,7 +761,7 @@
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
- <version>2.3.3</version>
+ <version>2.3.9</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
@@ -1513,6 +1513,16 @@
<version>${hadoop.compile.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-client-api</artifactId>
+ <version>${hadoop.compile.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-client-runtime</artifactId>
+ <version>${hadoop.compile.version}</version>
+ </dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value-annotations</artifactId>
diff --git a/quidem-ut/pom.xml b/quidem-ut/pom.xml
index eda8287f96b..2a6720bfd38 100644
--- a/quidem-ut/pom.xml
+++ b/quidem-ut/pom.xml
@@ -133,8 +133,20 @@
<version>${project.parent.version}</version>
<exclusions>
<exclusion>
- <groupId>com.amazonaws</groupId>
- <artifactId>aws-java-sdk-bundle</artifactId>
+ <groupId>software.amazon.awssdk</groupId>
+ <artifactId>bundle</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-hdfs-client</artifactId>
+ <exclusions>
+ <!-- Hadoop 3.5.0 introduced jakarta.ws.rs-api (JAX-RS 2.x),
+ which conflicts with Jersey 1.x's UriBuilderImpl. -->
+ <exclusion>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
</exclusion>
</exclusions>
</dependency>
diff --git a/web-console/e2e-tests/tutorial-batch.spec.ts
b/web-console/e2e-tests/tutorial-batch.spec.ts
index 59ac0a40781..e917ba5af20 100644
--- a/web-console/e2e-tests/tutorial-batch.spec.ts
+++ b/web-console/e2e-tests/tutorial-batch.spec.ts
@@ -31,7 +31,7 @@ import { QueryOverview } from './component/query/overview';
import { saveScreenshotIfError } from './util/debug';
import { DRUID_EXAMPLES_QUICKSTART_TUTORIAL_DIR, UNIFIED_CONSOLE_URL } from
'./util/druid';
import { createBrowser, createPage } from './util/playwright';
-import { retryIfJestAssertionError } from './util/retry';
+import { retryIfJestAssertionError, retryOnAnyError } from './util/retry';
import { waitTillWebConsoleReady } from './util/setup';
jest.setTimeout(5 * 60 * 1000);
@@ -168,9 +168,15 @@ async function validateDatasourceStatus(page:
playwright.Page, datasourceName: s
async function validateQuery(page: playwright.Page, datasourceName: string) {
const queryOverview = new QueryOverview(page, UNIFIED_CONSOLE_URL);
const query = `SELECT * FROM ${T(datasourceName)} ORDER BY __time`;
- const results = await queryOverview.runQuery(query);
- expect(results).toBeDefined();
- expect(results.length).toBeGreaterThan(0);
+ let results!: string[][];
+ await retryOnAnyError(
+ async () => {
+ results = await queryOverview.runQuery(query);
+ expect(results.length).toBeGreaterThan(0);
+ },
+ 1000,
+ 3,
+ );
expect(results[0]).toStrictEqual([
/* __time */ '2015-09-12T00:46:58.772Z',
/* time */ '2015-09-12T00:46:58.771Z',
diff --git a/web-console/e2e-tests/util/retry.ts
b/web-console/e2e-tests/util/retry.ts
index 63360dbf381..b077ebda8c7 100644
--- a/web-console/e2e-tests/util/retry.ts
+++ b/web-console/e2e-tests/util/retry.ts
@@ -41,3 +41,21 @@ export async function retryIfJestAssertionError(
}
}
}
+
+export async function retryOnAnyError(callback: () => Promise<void>, msec =
1000, maxTries = 60) {
+ let i = 0;
+
+ while (true) {
+ try {
+ await callback();
+ return;
+ } catch (e) {
+ i++;
+ if (i < maxTries) {
+ await sleep(msec);
+ } else {
+ throw e;
+ }
+ }
+ }
+}
diff --git a/web-console/script/druid b/web-console/script/druid
index 47a0c607ea5..dfb9d49ce1a 100755
--- a/web-console/script/druid
+++ b/web-console/script/druid
@@ -115,7 +115,8 @@ function start() {
fi
export DRUID_SKIP_JAVA_CHECK=1 # Make it simpler to develop the web console
when localhost is on JDK11
-
"$(_get_code_root)/distribution/target/apache-druid-$(_get_druid_version)/bin/start-druid"
-m 16g > /dev/null &
+ mkdir -p
"$(_get_code_root)/distribution/target/apache-druid-$(_get_druid_version)/log"
+
"$(_get_code_root)/distribution/target/apache-druid-$(_get_druid_version)/bin/start-druid"
-m 16g >
"$(_get_code_root)/distribution/target/apache-druid-$(_get_druid_version)/log/start-druid.log"
2>&1 &
local pid="$!"
echo "$pid" > "$DRUID_PID_FILE"
_log "Druid started with pid ${pid}"
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]