# Mit Maven eine jar Datei Bauen ohne irgendeine main Methode



## matze86 (6. Jan 2022)

Hallo, ich habe mittels Maven mehrere Klassen in verschiedenen Quelltexten in einen Paket. Das ganze baue ich, mit samt Abhängigkeiten, zur jar Datei.

Soweit so gut. Dazu habe ich auch eine Klasse mit einer "main" Methode. Lasse ich sie weg (was ich möchte), meckert mich Eclipse beim bauen an, dass sie fehlt.

Jetzt zu meinen anliegen. Ich möchte eine Jahr Datei bauen ohne das irgendeine Klasse die Methode "main" hat. 
Dann möchte ich die einzelnen Klassen von der jar Datei in ein anderen Projekt zu importieren. 
Da, dass ich erst recht neu bin weiß ich nicht ob man das so macht, oder ob man die ganze jar Datei importiert.

Vielleicht kann mir dazu einen Rat geben.
Vielen dank im voraus.


----------



## kneitzel (6. Jan 2022)

Bitte immer alle Details bringen:
a) pom.xml
b) wie baust Du das jar genau?
c) Was für Fehler bekommst du?

Eine Library lässt sich mit Maven ganz ohne Probleme bauen.


----------



## mihe7 (6. Jan 2022)

Wenn Du mit Maven arbeitest, reicht ein "Run As" -> "Maven install". Dadurch werden die Klassen kompiliert, das Jar gebaut und im lokalen Maven-Repository installiert. Die anderen Maven-Projekte brauchen dann nur noch die dependency anzugeben.


matze86 hat gesagt.:


> Dann möchte ich die einzelnen Klassen von der jar Datei in ein anderen Projekt zu importieren.
> Da, dass ich erst recht neu bin weiß ich nicht ob man das so macht, oder ob man die ganze jar Datei importiert.


In der Regel nimmt man die komplette Jar in den Classpath auf (ggf. mit Unterstützung der IDE).

Ich hatte hier mal was über ein paar grundlegende Zusammenhänge geschrieben: https://www.java-forum.org/thema/classpath-ressourcen-ides-und-build-systeme.194131/ Hilft Dir vielleicht beim Verständnis.


----------



## Mart (7. Jan 2022)

vllt brauchst du ja mvn deploy mit dem deploy plugin das glaub ich von haus aus shcon dabei ist? das kann repositories bauen mit der jar datei ( wie zb in github mit den github repositories )


----------



## matze86 (7. Jan 2022)

Das bauen ohne "main" hat funktioniert. Jetzt muss ich nochmal fragen, könnte man nicht die .jar Datei einfach entpacken und mit den Ordner der Abhängigkeiten an einen Ort kopieren und die dann in Java importieren?
Oder macht man das so nicht? Muss man immer ein classpath angeben?


----------



## kneitzel (7. Jan 2022)

Das kann man so machen. Siehe z.B. Maven Shade Plugin. Oder such mal nach Fat Jars.

Paar Probleme gibt es ggf .it Inhalten aus dem META-INF Ordner. Z.B. Signaturen müssten entfernt werden.


----------



## temi (7. Jan 2022)

matze86 hat gesagt.:


> Das bauen ohne "main" hat funktioniert. Jetzt muss ich nochmal fragen, könnte man nicht die .jar Datei einfach entpacken und mit den Ordner der Abhängigkeiten an einen Ort kopieren und die dann in Java importieren?
> Oder macht man das so nicht? Muss man immer ein classpath angeben?


Wenn man ein Library-Projekt hat, dann könnte man ein lokales Maven-Repository erstellen, in das man die Library deployt. Dann kann man sie im anderen Projekt auch wieder, wie alle anderen Abhängigkeiten, mit Maven importieren (aus dem lokalen Repository).

Keine Ahnung, ob das der übliche Weg ist. Es gibt bestimmt noch andere Möglichkeiten.


----------



## kneitzel (7. Jan 2022)

temi hat gesagt.:


> Wenn man ein Library-Projekt hat, dann könnte man ein lokales Maven-Repository erstellen, in das man die Library deployt. Dann kann man sie im anderen Projekt auch wieder, wie alle anderen Abhängigkeiten, mit Maven importieren (aus dem lokalen Repository).
> 
> Keine Ahnung, ob das der übliche Weg ist. Es gibt bestimmt noch andere Möglichkeiten.


Also Du beschreibst den üblichen Weg. Ich hatte ganz vergessen, dass es ja um eine Library geht.

Es wird Maven verwendet und Maven nutzt das lokale Repository. Daher macht es Sinn, die eigene Library einfach entsprechend zu deployen.
Wenn man die Software nicht nur selbst nutzen will, dann deployed man seine Abhängigkeit zu einem Zielserver. Das kann Maven Central sein aber auch jedes andere Repository (Also z.B. selbst betrieben oder github oder ....).

Wichtig ist dabei: Die Abhängigkeiten der Lib werden da dann nicht mit eingebunden! Zu dem Maven Repository gehlrt auch immer die pom Datei und die Abhängigkeiten Deiner Lib werden automatisch mit geladen, wenn deine Lib eingebunden wird -> Also auf keinen Fall eine "far jar" deployen!

Und das Einbinden in anderen Projekten kann dann ganz einfach wie alle Abhängigkeiten erfolgen: Über Angabe von groupId, artefactId und version.


----------



## sascha-sphw (7. Jan 2022)

Beispiel zum Text von @mihe7 und @kneitzel 

Lib Pom:

```
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>my-lib</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>my-lib</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- your deps -->
    </dependencies>
</project>
```


```
mvn install
```

Die Lib wird dann von maven gebaut und in das lokale (~/.m2) Repository kopiert.

Application Pom:

```
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>my-awesome-application</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>my-awesome-application</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>my-lib</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
</project>
```


----------



## Mart (7. Jan 2022)

kneitzel hat gesagt.:


> Es wird Maven verwendet und Maven nutzt das lokale Repository. Daher macht es Sinn, die eigene Library einfach entsprechend zu deployen.
> Wenn man die Software nicht nur selbst nutzen will, dann deployed man seine Abhängigkeit zu einem Zielserver. Das kann Maven Central sein aber auch jedes andere Repository (Also z.B. selbst betrieben oder github oder ....).


#4


----------



## sascha-sphw (7. Jan 2022)

Mart hat gesagt.:


> #4



mvn deploy
Veröffentlichung der Lib in ein remote Repository (Maven Central, Nexus, JFrog, usw.) 

mvn install
Veröffentlichung der Lib nur im lokalen Repository (~/.m2)


----------



## Mart (7. Jan 2022)

> Wenn man die Software nicht nur selbst nutzen will, dann deployed man seine Abhängigkeit zu einem Zielserver. Das kann Maven Central sein aber auch jedes andere Repository (Also z.B. selbst betrieben oder github oder ....).


----------



## Mart (7. Jan 2022)

ich fühle mich lediglich konstruktiv ignoriert


----------



## kneitzel (7. Jan 2022)

Mart hat gesagt.:


> ich fühle mich lediglich konstruktiv ignoriert


Wir ignorieren Dich nicht sondern wir ergänzen doch lediglich. Es gibt weder eine Aussage, dass Dein Post falsch wäre noch eine Aussage, dass diese Information so ganz neu ist.


----------



## mihe7 (7. Jan 2022)

Mart hat gesagt.:


> ich fühle mich lediglich konstruktiv ignoriert


Das kenn ich


----------



## matze86 (12. Jan 2022)

Also nochmal für mich zum "mitschreiben". 
Ich habe ein Mavenprojekt mit der pom.xml siehe unten.
In den MavenProjekt habe ich 2 Klassen. Und in Maven wird die Bibliothek pi4j geladen.

Jetzt möchte ich unabhängig von der gebauten Jar eine Klasse erstellen, die die Klasse oder Klassen importiert.

Muss man zwingend mit Maven wieder ein Projekt erstellen oder einfach ein Java Projekt?

Hier die pom.xml

```
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>matze_matrix</groupId>
  <artifactId>matze_matrix</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>matrix</name>

      <dependencies>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>${slf4j.version}</version>
    </dependency>

    <!-- include Pi4J Core -->
    <dependency>
        <groupId>com.pi4j</groupId>
        <artifactId>pi4j-core</artifactId>
        <version>${pi4j.version}</version>
    </dependency>

    <!-- include Pi4J Plugins (Platforms and I/O Providers) -->
    <dependency>
        <groupId>com.pi4j</groupId>
        <artifactId>pi4j-plugin-raspberrypi</artifactId>
        <version>${pi4j.version}</version>
    </dependency>
    <dependency>
        <groupId>com.pi4j</groupId>
        <artifactId>pi4j-plugin-pigpio</artifactId>
        <version>${pi4j.version}</version>
    </dependency>
</dependencies>
 
 
 


 <properties>
  <slf4j.version>1.7.32</slf4j.version>
    <pi4j.version>2.0</pi4j.version>
        <main.class>matze_matrix.Tester</main.class>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>

        <!-- plugin versions -->
        <maven.compiler.version>3.8.1</maven.compiler.version>
        <maven.jar.version>2.1</maven.jar.version>
        <maven.shade.version>3.2.4</maven.shade.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.version}</version>
                <configuration>
                    <release>${java.version}</release>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>${maven.jar.version}</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>${main.class}</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>${maven.shade.version}</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
              </transformers>
            </configuration>
            </plugin>

        </plugins>
        
      
        
    </build>
 
 
 
 
</project>
```


----------



## mihe7 (12. Jan 2022)

matze86 hat gesagt.:


> Muss man zwingend mit Maven wieder ein Projekt erstellen oder einfach ein Java Projekt?


Du hast irgendwie noch immer eine falsche Vorstellung von den Zusammenhängen. Ich vereinfache das mal stark.

Java-Files werden beim Kompilieren in Class-Files übersetzt. Ein Jar ist einfach ein ZIP, das die Paketstruktur (Verzeichnisse) inkl. der Class-Files enthält. Es spielt aber keine Rolle, welche Tools Du verwendest, um diese Aufgaben zu erledigen.

Maven ist ein solches Tool (Buildsystem), das alle möglichen Schritte übernimmt, unter anderem wird eben auch ein Jar erzeugt, das Du z. B. im target-Verzeichnis des Maven-Projekts findest.

Mit einem "mvn install" (das ggf. von der IDE automatisch ausgeführt wird), wird das Jar von Maven in das lokale Maven-Repository installiert, so dass es von anderen Maven-Projekten aus über eine "dependency" in der POM referenziert werden kann. Das hat aber nichts mehr mit Java zu tun, sondern ist eben eine Eigenheit von Maven.

Du bist somit natürlich keineswegs dazu gezwungen, Maven in einem Projekt zu verwenden, nur weil eine Lib mit Maven gebaut wurde. Ein Jar ist ein Jar.

Es ist also kein Problem, ein x-beliebiges Buildsystem (z. B. ant oder IDE intern) zu verwenden, Du musst lediglich dafür sorgen, dass Du das Jar Deiner Lib (und ggf. etwaige Jars, von denen die Lib abhängig ist) dem Buildsystem passend zur Verfügung stellst.


----------



## matze86 (12. Jan 2022)

mihe7 hat gesagt.:


> Du musst lediglich dafür sorgen, dass Du das Jar Deiner Lib (und ggf. etwaige Jars, von denen die Lib abhängig ist) dem Buildsystem passend zur Verfügung stellst.


Genau das meinte ich, wenn ich blanco auf dem PC oder Raspberry einen Java Quelltext erstelle, wie binde ich dann meine erstellten Klassen, die ich jar gepackt habe dann ein?


----------



## Mart (12. Jan 2022)

in dem du ein package management benutzt... 

das ist zb
-maven 
-dein build path
- gradle
- deine ide die den build path verwaltet


----------

