NoClassDefFoundError: com/sun/mail/util/MailLogger

Wenn man die Fehlermeldung bekommt

Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/MailLogger
        at javax.mail.Session.initLogger(Session.java:283)
        at javax.mail.Session.(Session.java:268)
        at javax.mail.Session.getDefaultInstance(Session.java:378)
        at javax.mail.Session.getDefaultInstance(Session.java:418)
        at eu.masterdevops.sendmail.App.main(App.java:25)
Caused by: java.lang.ClassNotFoundException: com.sun.mail.util.MailLogger
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        … 5 more

dann fehlt vermutlich eine Abhängigkeit in der pom.xml:

<dependency>
  <groupId>com.sun.mail</groupId>
  <artifactId>javax.mail</artifactId>
  <version>1.6.2</version>
</dependency>

Cannot find default setter in class org.apache.maven.archiver.ManifestConfiguration

Beim Bauen eines meiner Java-Projekte bekam ich nach dem Anpassen der pom.xml diese Fehlermeldung

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.2-beta-5:single
(default-cli) on project <projektname>: Unable to parse configuration of mojo
org.apache.maven.plugins:maven-assembly-plugin:2.2-beta-5:single for parameter manifest:
Cannot find default setter in class org.apache.maven.archiver.ManifestConfiguration -> [Help 1]

Wie es sich herausgestellt hat, hatte ich eine falsche Einstellung in die pom.xml geschrieben (Fehler hier fett abgebildet):

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>      <manifest>com.project.projectname.App</manifest>
    </archive>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
  </configuration>
</plugin>

Zwischen <manifest> und </manifest> hätte was anderes rein müssen als die Main-Class:

<archive>
   <manifest>
     <mainClass>com.project.projectname.App </mainClass>
   </manifest>
 </archive>

Nach diese Änderung ist die Fehlermeldung verschwunden.

OpenSSL 1.1: undefined symbol: UINT32_it

Wenn man unter Linux mit dem GNU Compiler eine Bibliothek beim Kompilieren benötigt, kann es doch manchmal wichtig sein, in welcher Reihenfolge man die abhängigen Bibliotheken angibt. Das habe ich letztens wieder gemerkt als mein Programm eine Bibliothek laden wollte, die wiederum die Bibliothek OpenSSL als Abhängigkeit hatte.

Beim Laden der Bibliothek bekam ich diese Fehlermeldung:

undefined symbol: UINT32_it

Nach einer kurzen Suche hatte ich schon eine Antwort. Beim Bauen meiner Bibliothek hatte ich die OpenSSL Bibliotheken in dieser Reihenfolge als abhängige Bibliotheken angegeben:

g++ ... -lcrypto -lssl ...

Nachdem ich die Reihenfolge dieser beiden Bibliotheken beim Bau meiner Bibliothek in

g++ ... -lssl -lcrypto ...

geändert hatte, kam die Fehlermeldung nicht mehr wieder.

Eine statische Bibliothek unter Linux mit CMake erstellen

In diesem Post möchte ich ein kleines Beispiel zeigen, wie man eine statische C++ Bibliothek unter Linux mit Hilfe von CMake baut. Dazu habe ich eine sehr einfache C++-Datei namens funcs.cpp erstellt. Die in der Datei enthaltene Funktion add soll zu Beispielzwecken dann in der statischen Bibliothek enthalten sein.

int add(int a, int b)
{
  return (a+b);
}

Die schon erwähnte Funktion add soll zu Beispielzwecken einfach zwei ganze Zahlen addieren. Um die Datei nun in eine statische Bibliothek zu packen, wird eine weitere Datei namens CMakeLists.txt benötigt, die in etwa so aussieht:

cmake_minimum_required(VERSION 3.6)

# Projektname definieren
project(static_test)

# Liste aller Quelldateien in einer Variablen speichern.
# Aus diesen Dateien entsteht dann die statische Bibliothek
set(ST_SOURCES funcs.cpp)

# CMake sagen, dass eine statische Bibliothek erstellt werden soll.
add_library(static_test STATIC ${ST_SOURCES})

Mit dem Kommando project definiert man den Projektnamen. Mit dem Kommando set wird eine neue Variable namens ST_SOURCES erstellt und gleich definiert. Dabei soll ST_SOURCES aus einer Liste aller Quelltextdateien bestehen, die für die statische Bibliothek nötig sind. Da wir in diesem Beispiel nur eine Datei haben, enthält die Liste ST_SOURCES nur einen Eintrag namens funcs.cpp. Man kann hier aber auch mehrere Dateinamen oder -pfade hintereinander setzen, getrennt durch ein Leerzeichen. Der Variablenname ist frei wählbar, muss aber gültig sein.

Das Kommando add_library sagt CMake nun, dass wir eine Bibliothek bauen wollen. Erst das STATIC in dem Kommando macht CMake klar, dass es sich um eine statische Bibliothek handeln muss. Will man jedoch eine dynamische Bibliothek, ersetzt man das STATIC einfach durch SHARED.

Beide Dateien befinden sich im selben Ordner.

Wenn man nun die CMakeLists.txt erstellt hat, muss man anschließend in die Kommandozeile diese zwei Befehle eingeben:

cmake -G "Unix Makefiles" .
make
Die statische Bibliothek wird gebaut.

Der erste Befehl (cmake …) erstellt nun das entsprechende Makefile. Ist das erstellt, kann man make starten und die statische Bibliothek wird erstellt.

Ist alles erfolgreich verlaufen, müsste man nun im Ordner eine Datei namens libstatic_test.a finden.

Der Bau der statischen Bibliothek war erfolgreich.