Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Apache Derby and Hibernate to print english exception messages in a Java EE application?

I'm running a Java EE application which uses Hibernate 5.2.10.Final with an Apache Derby storage backend on Payara 4.1.1.172. I'm seeing error messages like

Caused by: java.sql.SQLDataException: A truncation error was encountered trying to shrink VARCHAR () FOR BIT DATA '(Binärer Datenwert wird nicht angezeigt)' to length 255.

which indicates that either Hibernate or Derby or both are not using english error messages in all parts of the message.

I tried to

  • add a

    static {
        System.setProperty("user.language", "en");
        System.setProperty("user.region", "en_US");
    }
    

    to a class, but I don't seem to find a deterministic way to get this loaded before any exception occurs and I'd rather like to keep the setting out of the code. The same thus applies to Locale.setDefault.

  • specify -Duser.language=en in the Payara JVM options of server-config as describe at How to enable assertion for a Java EE project in NetBeans?

I see that the beginning of the exception message is in English. I want the complete message to be in English including all possible parts. I'm not interesting in solving the exception, it's an example. I'm not looking for a translation of the German part of the message.

The non-English message part is most likely caused by the German Ubuntu 18.04 the server is started on. Changing the system locale of the OS or a container the server could be wrapped into is a workaround, but not a solution.

A SSCCE can be found at https://gitlab.com/krichter/derby-embedded-data-source-locale-j4ee and example output of the CI at https://gitlab.com/krichter/derby-embedded-data-source-locale-j4ee/-/jobs/83525395. The SSCCE only contains boilerplate around the server start and a simple invalid native query causing a german error message, not more information than provided in the question.

Please verify answers with the SSCCE if possible.

My motivation is to have English exception messages in order to make finding solution through search engines easier during development without tampering with the system language.

like image 828
Kalle Richter Avatar asked Jun 02 '17 12:06

Kalle Richter


1 Answers

Why don't you just use the JAVA_TOOL_OPTIONS env-variable? After setting export LC_ALL=de_DE.UTF-8 (in your .gitlab-ci.yml) you could set export JAVA_TOOL_OPTIONS="-Duser.language=en" and enjoy your error-messages in English.

Regarding "-Duser.language" not working for derby's startNetworkServer: startNetworkServer is a script that executes (in its simplest form) java -jar derby.jar. Because of that you cannot simply execute bin/startNetworkServer -Duser.language=en. But if you take a look at the startNetworkServer script, you can see that an environment-variable DERBY_OPTS is used. So probably it would also work to specify export DERBY_OPTS="-Duser.language=en", although I didn't try it that way. (and as your comment states, it doesn't)

sample .gitlab-ci.yml which works:

main:
    image: ubuntu:18.04
    script:
        - apt-get update && apt-get install --yes language-pack-de wget openjdk-8-jdk maven
        - export LC_ALL=de_DE.UTF-8
        - export JAVA_TOOL_OPTIONS="-Duser.language=en"
        - wget http://www-eu.apache.org/dist//db/derby/db-derby-10.14.2.0/db-derby-10.14.2.0-bin.tar.gz && tar xf db-derby-10.14.2.0-bin.tar.gz
        - cd db-derby-10.14.2.0-bin && bin/startNetworkServer &
        - mvn --batch-mode install
        - java -jar target/derby-embedded-data-source-locale-1.0-SNAPSHOT-jar-with-dependencies.jar

output:

$ java -jar target/derby-embedded-data-source-locale-1.0-SNAPSHOT-jar-with-dependencies.jar
Picked up JAVA_TOOL_OPTIONS: -Duser.language=en
running main
Exception in thread "main" java.sql.SQLNonTransientConnectionException: The connection was refused because the database database was not found.
        at org.apache.derby.client.am.SQLExceptionFactory.getSQLException(Unknown Source)
        at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
        at org.apache.derby.jdbc.ClientDriver.connect(Unknown Source)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
        at de.richtercloud.derby.embedded.data.source.locale.Main.main(Main.java:12)
Caused by: ERROR 08004: The connection was refused because the database database was not found.
        at org.apache.derby.client.net.NetConnectionReply.parseRDBNFNRM(Unknown Source)
        at org.apache.derby.client.net.NetConnectionReply.parseAccessRdbError(Unknown Source)
        at org.apache.derby.client.net.NetConnectionReply.parseACCRDBreply(Unknown Source)
        at org.apache.derby.client.net.NetConnectionReply.readAccessDatabase(Unknown Source)
        at org.apache.derby.client.net.NetConnection.readSecurityCheckAndAccessRdb(Unknown Source)
        at org.apache.derby.client.net.NetConnection.flowSecurityCheckAndAccessRdb(Unknown Source)
        at org.apache.derby.client.net.NetConnection.flowUSRIDPWDconnect(Unknown Source)
        at org.apache.derby.client.net.NetConnection.flowConnect(Unknown Source)
        at org.apache.derby.client.net.NetConnection.<init>(Unknown Source)
        at org.apache.derby.client.net.ClientJDBCObjectFactoryImpl.newNetConnection(Unknown Source)
        ... 4 more
ERROR: Job failed: exit code 1
FATAL: exit code 1
like image 165
Halko Karr-Sajtarevic Avatar answered Oct 20 '22 03:10

Halko Karr-Sajtarevic