# Maven und Intellij



## benjamin222 (24. Jun 2021)

Hallo,

ich hab folgendes Problem. Wenn ich eine neue Maven dependency in die pom.xml reinschreibe dann erkennt Intellij das nicht und ich muss jedes mal per "File/Invalidate Caches/invalidate and restart" erzwingen, dass Intellij einmal zu geht und dann erst beim erneuten aufmachen klappt es meistens.

Jetzt kommt noch hinzu, dass ich das https://mvnrepository.com/artifact/opencv/opencv/4.1.1 gerne einbinden würde, aber das wird leider nicht gefunden. Ich hab die dependency einfach ganz stumpf in die pom.xml kopiert mehr nicht.

Ich vermute, dass es daran liegt, dass es nicht in dem Central repository liegt. Aber was genau ich jetzt tun muss ist unklar.


----------



## kneitzel (25. Jun 2021)

Die erste Frage wäre ggf, wie Du die pom.xml anpasst: Aus IntelliJ oder extern? Wobei das nicht ganz so wichtig ist, denn IntelliJ sollte erkennen, wenn eine Datei extern verändert wurde.

Generell werden Änderungen an der pom nicht sofort übernommen (so man dies nicht eingestellt hat). Wenn Änderungen an der pom.xml vorgenommen wurden, dann blendet IntelliJ per default einen kleinen Button innerhalb des Editor-Fensters ein im Bereich der oben rechten Ecke. Darauf kann man zum neu laden der pom klicken. (Der Button sieht aus wie ein kleines m mit zwei entgegengesetzten Pfeilen in Kreisform oder so)

Ansonsten hast Du auch die Möglichkeit, über das Maven Toolfenster (wird in der Regel recht mit angezeigt - da solltest Du einen "Tab" Maven finden). So das maven Toolfenster nicht geöffnet ist, erreichst Du es über View -> Tool Windows -> Maven. Im maven Fenster hast Du dann auch wieder den reload Knopf.

Bei Problemen kann es manchmal Sinn machen, auf der Kommandozeile zu prüfen, ob aus Maven Sicht alles ok ist. Wenn im IntelliJ Projekt irgendwas zerschossen ist, ist es am einfachsten, einfach ein neues zu generieren (also .idea Verzeichnis und alle iml Dateien löschen). Aber das ist nur sehr selten notwendig nach meiner Erfahrung (Aber eine Problematik, die auch bei anderen IDEs auftreten kann, so ich das richtig beobachtet habe).

Bezüglich weiterer Repositories kann ich nur empfehlen:




__





						Maven – Guide to using Multiple Repositories
					





					maven.apache.org
				




Da wird dies recht gut beschrieben. Ich würde also einfach empfehlen, in dem pom mittels repositories/repository das Repository einzutragn. Die URL bekommst Du ja, wenn Du in Deinem Link auf das Repository clickst (Das blau hinterlegte EBIPublic). id / name kannst Du frei vergeben.


----------



## Jw456 (25. Jun 2021)

Hallo Intelli J benutzt Gradle als build System. Also trage die  dependency auch in das Gradle File ein. Und nicht in das XML.


----------



## thecain (25. Jun 2021)

Jw456 hat gesagt.:


> Hallo Intelli J benutzt Gradle als build System.


Nein


----------



## kneitzel (25. Jun 2021)

Jw456 hat gesagt.:


> Hallo Intelli J benutzt Gradle als build System. Also trage die  dependency auch in das Gradle File ein. Und nicht in das XML.


Nur um da etwas mehr als nur das "Nein" zu sagen:
Wenn man Maven als Build-System nutzt, dann greift IntelliJ natürlich auch auf Maven zu und die Abhängigkeit gehört in die pom.xml.
Und dann gibt es natürlich auch kein Gradle File. Ein Gradle-File gibt es nur dann, wenn man auch Gradle als Build System benutzt.

IntelliJ selbst hat ansonsten sein eigenes Projektfile und Format, welches man nutzen kann. Es erkennt aber auch andere Build-Systeme und kann auf diesen basieren (Maven, Gradle, Ant, ...) Wenn man mit IntelliJ auf andere Projektformate zugreift, dann macht es z.B. Sinn, die IntelliJ Dateien aus der source Verwaltung raus zu halten (.idea Verzeichnis, *.iml Dateien, ....), Denn wenn das IntelliJ Projekt (Das es auf Basis des eigentlichen Projekts auch geben wird) irgend welche Inkonsistenzen aufweist, dann kann es sinnvoll sein, di einfach zu löschen und dann IntelliJ das Projekt neu öffnen zu lassen. (Das gilt übrigens für alle IDEs. Das habe ich auch schon bei Eclipse und Netbeans erlebt!). Erkennbar ist sowas, wenn das Build in der IDE nicht durchläuft, aber auf der Kommandozeile alls sauber läuft.

Das einfach einmal als lange Erläuterung.


----------



## Jw456 (25. Jun 2021)

Dann schau dir den link von ihm an. Was hat er angeklickt Gradle. Also will er es auch benutzen.

Wenn er ein anderes build System unter Intelli nutzten will muss er auch die dependency in diesen Format machen und mich im Gradle Format. In der XML. 
Da nützen alle Erklärungen nicht viel.


----------



## mrBrown (25. Jun 2021)

Jw456 hat gesagt.:


> Dann schau dir den link von ihm an. Was hat er angeklickt Gradle. Also will er es auch benutzen.


Der Link zeigt Gradle an, weil *DU* auf der Seite Gradle ausgewählt hast.


----------



## Jw456 (25. Jun 2021)

Nicht ich habe das ausgewählt sondern der TE.


----------



## mrBrown (25. Jun 2021)

Jw456 hat gesagt.:


> Nicht ich habe das ausgewählt sondern der TE.


Nein.

Der Link enthält keinerlei Informationen über das gewählte Build-System (sieht man an dem Link ja auch). mvnrepository merkt sich aber, was man selbst als letztes ausgewählt hatte, und zeigt es danach standardmäßig an.


----------



## Jw456 (25. Jun 2021)

Ok kann sein


----------



## mrBrown (25. Jun 2021)

Kann nicht nur sein, ist so  kannst du zB im local storage deines Browsers angucken


----------



## Jw456 (25. Jun 2021)

Ja ist gut.


----------



## benjamin222 (26. Jun 2021)

Hallo, leider klappt es immer noch nicht d.h. nachdem von Hand hineinschreiben des repository und dem reloaden des Maven projects kommt die Fehlermeldung:   "cannot resolve opencvpencv:4.1.1".

Ich kopiere jetzt einfach meine pom.xml mal hier rein:


```
<?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>org.example</groupId>
    <artifactId>TestingProjekt</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.7.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>javax.mail-api</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>opencv</groupId>
            <artifactId>opencv</artifactId>
            <version>4.1.1</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>EBIPublic</id>
            <name>EBIPublic</name>
            <url>https://www.ebi.ac.uk/intact/maven/nexus/content/repositories/public/</url>
        </repository>
    </repositories>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

</project>
```


----------



## Jw456 (26. Jun 2021)

meiner Meinung müsstest du den link zum Repos auch unter repeositores angeben. 

https://mvnrepository.com/artifact/opencv/opencv


----------



## mrBrown (26. Jun 2021)

In EBIPublic existieren keine Artefakte mehr, irgendwas ist da kaputt...

Du kannst dieses nutzen: https://mvnrepository.com/artifact/org.openpnp/opencv


----------



## benjamin222 (26. Jun 2021)

mrBrown hat gesagt.:


> In EBIPublic existieren keine Artefakte mehr, irgendwas ist da kaputt...
> 
> Du kannst dieses nutzen: https://mvnrepository.com/artifact/org.openpnp/opencv



Okay, danke. Leider geht es direkt mit dem nächsten Problem weiter. Wenn ich teste ob alles funktioniert mit einem Minmalbeispiel an Code bekomme ich zur Laufzeit einen Fehler und zwar:

" Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java451 in java.library.path: ..."


```
System.out.println("OpenCV configuration simple test:");
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat m = Mat.eye(3,3, CvType.CV_8UC1);
        System.out.println("OpenCV matrix = " + m.dump());
```


----------



## benjamin222 (26. Jun 2021)

So update, leider sehe ich keine editier Funktion für meinen Beitrag #16.


```
System.out.println("OpenCV configuration simple test:");
        nu.pattern.OpenCV.loadShared();
        System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);

        Mat m = Mat.eye(3,3, CvType.CV_8UC1);
        System.out.println("OpenCV matrix = " + m.dump());
```

Gibt zwar die Matrix wie gewünscht aus, aber davor noch reichlich Fehlermeldungen:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by nu.pattern.OpenCV$SharedLoader (file:/C:/Users/****/.m2/repository/org/openpnp/opencv/4.5.1-2/opencv-4.5.1-2.jar) to field java.lang.ClassLoader.usr_paths
WARNING: Please consider reporting this to the maintainers of nu.pattern.OpenCV$SharedLoader
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release


Irgendwie hab ich in Erinnerung das Maven die Sache vereinfachen sollte...


----------



## kneitzel (26. Jun 2021)

Das sind erst einmal nu Warnungen und die hängen nicht mit Maven zusammen. Die kommen von Java zur Laufzeit, denn Du nutzt Java 9 oder später (In der pom.xml ist 11 vorgegeben) und damit hast Du Module. Und da müssen Zugriffe entsprechend vorgegeben werden. So ein "reflective access" müsste erlaubt werden über eine Angabe, dass eben java.lang.ClassLoader für das OpenCV Modul geöffnet wird.

Die Warnung könnte man los werden per:
- --add-opens Parameter um dann dies entsprechend vorzugeben. Der Pfad könnte problematisch sein, denn vermutlich wird OpenCV noch ein anonymes Modul sein ... das liesse sich dann auch noch beheben aber das wird dann ein kleiner Rattenschwanz. (Daher die Empfehlung, die einfach nur sagt: Hau das den Entwicklern um die Ohren!) (Hier evtl. auch noch --illegal-access=permit angeben, um noch weitere Stellen zu finden!)
- --illegal-access=permit dürfte die Warnung einfach unterdrücken - aber halt mit der Gefahr, dass es irgendwann nicht mehr geht.

Das wäre so auf die Schnelle meine Sichtweise darauf.


----------



## mrBrown (26. Jun 2021)

kneitzel hat gesagt.:


> damit hast Du Module. Und da müssen Zugriffe entsprechend vorgegeben werden. So ein "reflective access" müsste erlaubt werden über eine Angabe, dass eben java.lang.ClassLoader für das OpenCV Modul geöffnet wird.


Wobei das nur indirekt mit Modulen zusammen hängt, das sind ja Zugriffe die auf guten Gründen nicht „einfach so“ möglich sind, sondern explizit freigegeben werden müssen.




kneitzel hat gesagt.:


> Die Warnung könnte man los werden per:
> - --add-opens Parameter um dann dies entsprechend vorzugeben. Der Pfad könnte problematisch sein, denn vermutlich wird OpenCV noch ein anonymes Modul sein ... das liesse sich dann auch noch beheben aber das wird dann ein kleiner Rattenschwanz. (Daher die Empfehlung, die einfach nur sagt: Hau das den Entwicklern um die Ohren!) (Hier evtl. auch noch --illegal-access=permit angeben, um noch weitere Stellen zu finden!)
> - --illegal-access=permit dürfte die Warnung einfach unterdrücken - aber halt mit der Gefahr, dass es irgendwann nicht mehr geht.


Letzteres ist ab Java 16 nicht mehr möglich, add-opens sollte man dafür generell immer nutzen – mit ALL_UNNAMED auch für anonyme Module.


----------



## benjamin222 (26. Jun 2021)

Danke, aber wo genau muss ich das "--illegal-access=permit" oder "--add-opens" denn reinschreiben?


----------



## kneitzel (26. Jun 2021)

mrBrown hat gesagt.:


> Letzteres ist ab Java 16 nicht mehr möglich, add-opens sollte man dafür generell immer nutzen – mit ALL_UNNAMED auch für anonyme Module.


Ah, ok. Das hatte ich mir so gut noch nicht angesehen. Danke für die Info.

(Ich muss zugeben, dass ich so Libraries, die es in fast 4 Jahren nicht geschafft haben, entsprechend zu reagieren, auch nicht einsetze. Also unabhängig von diesem Fehler - auch generell bei fehlenden module-info bekomme ich Bauchschmerzen... (Wobei ich das schon vor Java 16 hatte. Java 11 ist Sept. 2018 raus gekommen und ab Mitte 2019 hatte ich dann schon kein Verständnis mehr für Libraries, die da nicht reagiert haben. Das ist in meinen Augen schon eine recht klare Aussage bezüglich: "Wechsel doch bitte zu einer Alternative". Ja, damit lehne ich mich stark aus dem Fenster und den muss man nicht folgen ... )


----------



## mrBrown (26. Jun 2021)

kneitzel hat gesagt.:


> (Ich muss zugeben, dass ich so Libraries, die es in fast 4 Jahren nicht geschafft haben, entsprechend zu reagieren, auch nicht einsetze. Also unabhängig von diesem Fehler - auch generell bei fehlenden module-info bekomme ich Bauchschmerzen... (Wobei ich das schon vor Java 16 hatte. Java 11 ist Sept. 2018 raus gekommen und ab Mitte 2019 hatte ich dann schon kein Verständnis mehr für Libraries, die da nicht reagiert haben. Das ist in meinen Augen schon eine recht klare Aussage bezüglich: "Wechsel doch bitte zu einer Alternative". Ja, damit lehne ich mich stark aus dem Fenster und den muss man nicht folgen ... )


Die Warnungen gibts nicht wegen fehlender module-info, sondern weil Dinge genutzt werden, die zur internen API gehören, die lassen sich ganz bewusst nicht anders nutzen 
Manche Dinge lassen sich anders nicht nutzen, je nachdem was die Lib machen soll.





benjamin222 hat gesagt.:


> Danke, aber wo genau muss ich das "--illegal-access=permit" oder "--add-opens" denn reinschreiben?


Besser wäre es, den Hinweis aus der Doku zu beachten:



			
				https://github.com/openpnp/opencv#api hat gesagt.:
			
		

> *Note: In Java 12+ loadShared() is not available. Use loadLocally() instead, and see notes below.*



Das sollte den Grund für die Warnungen beheben, anstatt sie einfach nur zu ignorieren.


----------



## kneitzel (26. Jun 2021)

Ah, ok - danke für die detaillierte Aufklärung. Da hatte ich dann nicht tief genug dieses konkrete Problem angesehen.


----------



## benjamin222 (26. Jun 2021)

Danke. Jetzt tauchen die Warnungen tatsächlich nicht mehr auf. Ehrlicherweise muss ich aber sagen, dass ich die Befehle 

```
nu.pattern.OpenCV.loadShared();
System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);
```

bzw. 


```
nu.pattern.OpenCV.loadLocally();
```

und die Logik warum einmal eine Zeile reicht, nicht verstehe. Aber vielleicht muss ich das als Anwender auch erstmal nicht...


----------



## mrBrown (26. Jun 2021)

benjamin222 hat gesagt.:


> warum einmal eine Zeile reicht


In beiden Fällen würde eine Zeile reichen 

intern laden beide Befehle die native Lib, beide etwas unterschiedlich, da sich ab Java 11 intern was geändert hat – wie und was und warum dürfte für die meiste Anwender aber wirklich uninteressant sein


----------

