DEV Community

Cover image for Introducing Free Java Utility Package
Andy Brunner
Andy Brunner

Posted on

Introducing Free Java Utility Package

A fast and easy to use programming toolkit for the Java backend developer

In my professional life as an administrator and developer, I have benefited many times from countless freeware and open source products. It is therefore natural for me to also contribute to this community.

This collection of Java classes was created in the course of various projects and will be further developed. I hope that this tool will also serve you well.

https://java-util.k43.ch

Design Goals

  • Ease of use: The classes and methods must be flexible and simple to use.
  • No UI calls: Do everything without user interface to allow this toolkit to be used for background tasks or server processes.
  • Fast: Write the code as performant as possible.
  • Favor memory usage over I/O: In today's world, memory is no longer a limiting factor. Therefore, many operations can be done in memory where (temporary) files were used in the past (e.g. KDB creates a data structure from SQL SELECT, KFile operations are mostly in memory).
  • Use extensive logging: The KLog.debug() function is used heavily throughout the code to help debugging your code. Use the toString() methods found in each class to show the internal field values of the objects during development.
  • Platform independence: Write everything platform independent.
  • Minimize prerequisites: Stay with the Java SE standard libraries. Use only external JAR files when absolutely necessary (e.g. KSMTPMailer, JDBC drivers).

Logging: Simple but powerful

  • Reduces the logging complexity to debug, info and error messages.
  • Uses the standard Java SE logging class without the need for any additional library.
  • Every log records includes an exact time stamp and the source code location.
  • Besides the standard ConsoleHandler and FileHandler, the output may be sent to any JDBC database or errors can be sent to an SMTP host.
  • Five logging formatters are provided: Tabular line, CSV, JSON, YAML and XML.
public static void main(String[] args) {

  KLog.info("Start");

  int result = 0;

  try {
    result = 10 / 0;
  } catch (Exception e) {
    KLog.error(e);
  }

  KLog.debug("Result is " + result);
}
Enter fullscreen mode Exit fullscreen mode
2024-09-16T07:17:11.095 D main[1]:ch.k43.util.KLog:open:459                            ===== Application started 2024-09-16T07:17:11.048 =====
2024-09-16T07:17:11.111 D main[1]:ch.k43.util.KLog:open:460                            Java Utility Package (Freeware) ch.k43.util Version 2024.09.15
2024-09-16T07:17:11.112 D main[1]:ch.k43.util.KLog:open:463                            Homepage java-util.k43.ch - Please send any feedback to andy.brunner@k43.ch
2024-09-16T07:17:11.122 D main[1]:ch.k43.util.KLog:open:466                            Host ab-macbook-pro (10.0.0.105)
2024-09-16T07:17:11.122 D main[1]:ch.k43.util.KLog:open:467                            OS platform Mac OS X (Version 14.6.1/aarch64)
2024-09-16T07:17:11.123 D main[1]:ch.k43.util.KLog:open:471                            OS disk space total 3.63 TB, free 2.37 TB, usable 2.37 TB
2024-09-16T07:17:11.123 D main[1]:ch.k43.util.KLog:open:474                            Java version 21 (OpenJDK 64-Bit Server VM - Eclipse Adoptium)
2024-09-16T07:17:11.123 D main[1]:ch.k43.util.KLog:open:477                            Java CPUs 10
2024-09-16T07:17:11.124 D main[1]:ch.k43.util.KLog:open:481                            Java heap maximum 16.00 GB, current 1.00 GB, used 7.68 MB, free 1016.32 MB
2024-09-16T07:17:11.124 D main[1]:ch.k43.util.KLog:open:485                            Java locale de/CH, time UTC +02:00
2024-09-16T07:17:11.125 D main[1]:ch.k43.util.KLog:open:488                            Java classpath ../bin/:../lib/angus-mail-2.0.3.jar:../lib/jakarta.mail-api-2.1.3.jar:../lib/org.json.20230618.jar:../lib/h2-2.2.224.jar:../lib/jakarta.activation-api-2.1.3.jar:../lib/angus-activation-2.0.2.jar
2024-09-16T07:17:11.125 I main[1]:Test:main:9                                          Start
2024-09-16T07:17:11.125 E main[1]:Test:main:16                                         ===> java.lang.ArithmeticException: / by zero
2024-09-16T07:17:11.126 E main[1]:Test:main:16                                         ===> Stack[1]: Test.main(Test.java:14)
2024-09-16T07:17:11.126 D main[1]:Test:main:19                                         Result is 0
Enter fullscreen mode Exit fullscreen mode

Database: Access any JDBC database

  • Loads the required JDBC driver and executes any SQL statement.
  • Any JDBC compliant database may be used.
  • Retrieve data in raw Java format (rows as ArraryList, columns as Java Objects).
  • Format result set as a JSON, YAML, XML, CSV or tabular string.
try (KDB db = new KDB(KDB.JDBC_H2, "jdbc:h2:mem:mydb", "", "")) {

  KLog.abort(!db.isConnected(), "Error: " + db.getErrorMessage());

  db.exec("CREATE TABLE ADDRESSES (SEQUENCE INT AUTO_INCREMENT, LASTNAME VARCHAR(20), FIRSTNAME VARCHAR(20))");
  db.exec("INSERT INTO ADDRESSES (LASTNAME, FIRSTNAME) VALUES ('Smith', 'John')");
  db.exec("INSERT INTO ADDRESSES (LASTNAME, FIRSTNAME) VALUES ('Miller', 'Bob')");
  db.exec("INSERT INTO ADDRESSES (LASTNAME, FIRSTNAME) VALUES ('Johnson', 'Eve')");
   db.exec("SELECT * FROM ADDRESSES", 10);

  System.out.println(db.getDataAsTable());
  System.out.println(db.getDataAsJSON());
}
Enter fullscreen mode Exit fullscreen mode
SEQUENCE    LASTNAME             FIRSTNAME            
1           Smith                John                 
2           Miller               Bob                  
3           Johnson              Eve                  
Enter fullscreen mode Exit fullscreen mode
{
  "ADDRESSES": [
    {
      "SEQUENCE": 1,
      "LASTNAME": "Smith",
      "FIRSTNAME": "John"
    },
    {
      "SEQUENCE": 2,
      "LASTNAME": "Miller",
      "FIRSTNAME": "Bob"
    },
    {
      "SEQUENCE": 3,
      "LASTNAME": "Johnson",
      "FIRSTNAME": "Eve"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

SMTP: Create and send message

  • Create MIME multipart message with test, HTML and file attachments.
  • Support for STARTTLS/TLS or non-TLS connections.
  • Support for OAuth 2.0 and basic authentication.
KSMTPMailer mailer = new KSMTPMailer();

mailer.setFrom("john.doe@acme.com");
mailer.setTo("bob.smith@hotmail.com");
mailer.setSubject("Subject");
mailer.addHTML("<h1>Your requested files</h1>");
mailer.addText("Body Text");
mailer.addFile("test1.txt");
mailer.addFile("test2.txt");
mailer.addText("Regards, John");
mailer.send();
Enter fullscreen mode Exit fullscreen mode

HTTP Client: Simple standard or REST calls

  • Supports HTTP and HTTPS.
  • Support for all standard HTTP methods (GET, POST, PUT, POST, etc).
  • Request header Date, User-Agent, Host and Content-Length are automatically added.
Properties props = new Properties();
props.put("Authorization", "Basic " + K.encodeBase64(userName + ':' + password);

KHTTPClient http = new KHTTPClient();

if (!http.post("https://example.com:4443", props, "HTTP body data")) {
   KLog.abort("HTTP POST failed - " + http.getLastError());
}
Enter fullscreen mode Exit fullscreen mode

K: Utility class

  • Encode/decode for URL, Base64, CSV, JSON, XML and YAML.
  • AES256 encrypt/decrypt (AES/CBC/PKCS5Padding).
  • ZLIB compress/decompress.
  • Generate hash (MD5, SHA-2 or SHA-3).
  • Query any DNS record (MX, A, etc.).
// Wait 1/4 second
K.waitMilliseconds(250);

// Get DNS MX record(s)
String[] mxRRs = K.queryDNS("MX", "yahoo.com");

//
// AES-256 Encryption/Decryption
//
String secretKey = "This is the secret key";

// Create a simple text file
KFile.writeFile("This is a simple text file", "AES-Text.txt");

// Generate and save random AES-256 initialization vector
KFile.writeFile(K.getRandomBytes(16), "AES.iv");

// Encrypt
byte[] clearText    = KFile.readByteFile("AES-Text.txt");
byte[] initVector   = KFile.readByteFile("AES.iv");
byte[] cipherText   = K.encryptAES256(clearText, secretKey.getBytes(), initVector);
KFile.writeFile(cipherText, "AES-Text.encrypted");

// Decrypt
cipherText  = KFile.readByteFile("AES-Text.encrypted");
initVector  = KFile.readByteFile("AES.iv");
clearText   = K.decryptAES256(cipherText, secretKey.getBytes(), initVector);
Enter fullscreen mode Exit fullscreen mode

Have fun and let me know what you like and what needs improvement. You can reach me via email [andy.brunner@k43.ch] or at Mastodon.

Top comments (0)