I made a simple Maven project for my class. According to the teachers tutorial we cannot upload it to our school repo due to some server issues, so we have to store it locally using altDeploymentRepository. I have the following pom.xml:
<?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.dpp</groupId>
<artifactId>simple_lib</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<altDeploymentRepository>internal.repo::default::file://${project.basedir}/../${project.name}-mvn-repo</altDeploymentRepository>
</configuration>
</plugin>
</plugins>
</build>
</project>
So in the directory with my Maven project I have two directories:
sample_lib
sample_lib-mvn-repo
In the second one, deep down in : sample_lib-mvn-repo\com\dpp\sample_lib\1.0-SNAPSHOT I have a .jar file which I want to import (but not using just .jar file like passing the path to it - I need to do this "Maven way", import it as Maven lib). Can I do it if the file is not stored on any remote repository, but on my hard drive?
Running simply mvn install will install the file in your local repository. The local repository, by default, is in your home directory, under .m2\repository.
Using your pom above, after running mvn install, you would have jar (and some other files) in .m2\repository\com\dpp\sample_lib\1.0-SNAPSHOT.
To import this subsequently in another project, you would create a dependency in that project's pom like:
<dependency>
<groupId>com.dpp</groupId>
<artifactId>simple_lib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
This all takes place only on your machine, and will not use any remote repository.
Now you have a local simulation of a repository.
You can import it using the repository tag as described in https://maven.apache.org/pom.html#Repositories. To specify a file make it a file url like file:
Yes, you can add maven repository and point it to a local directory:
<repository>
<id>local</id>
<name>local</name>
<url>file:${user.dir}/sample_lib-mvn-repo</url>
</repository>
https://maven.apache.org/guides/introduction/introduction-to-repositories.html
Given that your jar file is here sample_lib-mvn-repo\com\dpp\sample_lib\1.0-SNAPSHOT.jar, you then can add it as a dependency:
<dependency>
<groupId>com.dpp</groupId>
<artifactId>sample_lib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
It's not exactly what you're asking. But a quick and dirty solution is to make a POM project (no source code).
Inside the POM project you have the main and external projects.
You can simply make a dependency on the other project.
Related
Here is my situation:
I'm trying to migrate from Ant to Maven
My project has 3 artifacts: shared api (jar), web app (war), desktop swing app (jar). Latter 2 depends on shared api.
At this moment I'm trying to make web app part work. So I've created 4 poms: eftracker (root pom), eftracker-parent, eftracker-shared, eftracker-web.
If I run mvn package on eftracker all works just perfect -- I have eftracker-shared.jar and eftracker-web.war created as expected
I added tomcat7-maven-pluginto run web app with maven goal tomcat7:run to test changes made during development
I also added eftracker-shared as a project to eftracker-web build path.
My goal:
Now I want to work comfortably in Eclipse, meaning I want to change files, hit Run and in couple seconds be able to test my changes.
During development I will change both: shared and web projects.
My problem:
If I never run mvn install than an attempt to invoke tomcat7:run will lead to error: Failed to execute goal on project eftracker-web: Could not resolve dependencies for project com.skarpushin:eftracker-web:war:1.503.0: Could not find artifact com.skarpushin:eftracker-shared:jar:1.503.0 in central (https://repo.maven.apache.org/maven2)
It appears I have to mvn clean install shared project (or even on root module) each time I change it before I can execute tomcat7:run on web app and see recent changes.
Question is:
Is it possible to make this process automatic?
...OR maybe there is other way how to minimize "maven overhead" during development?
eftracker.pom
<?xml version="1.0"?>
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.skarpushin</groupId>
<artifactId>eftracker</artifactId>
<version>1.503.0</version>
<packaging>pom</packaging>
<name>eftracker</name>
<modules>
<module>eftracker-parent</module>
<module>eftracker-shared</module>
<module>eftracker-web</module>
</modules>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
</project>
eftracker-parent/pom.xml
<?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.skarpushin</groupId>
<version>1.503.0</version>
<artifactId>eftracker-parent</artifactId>
<packaging>pom</packaging>
<name>eftracker-parent</name>
<!-- ...some common properties, dependencies, build plugins... -->
</project>
eftracker-web/pom.xml
<?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">
<parent>
<groupId>com.skarpushin</groupId>
<artifactId>eftracker-parent</artifactId>
<version>1.503.0</version>
<relativePath>../eftracker-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eftracker-web</artifactId>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<port>8080</port>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warName>ROOT##${project.version}</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.skarpushin</groupId>
<artifactId>eftracker-shared</artifactId>
<version>${project.version}</version>
</dependency>
<!-- ...other deps -->
</dependencies>
</project>
Try to use M2Eclipse
https://www.eclipse.org/m2e/
M2Eclipse provides tight integration for Apache Maven into the IDE
with the following features:
Launching Maven builds from within Eclipse
Dependency management for Eclipse build path based on Maven's pom.xml
Resolving Maven dependencies from the Eclipse workspace without installing to local Maven repository
Automatic downloading of the required dependencies from the remote Maven repositories
Wizards for creating new Maven projects, pom.xml and to enable Maven support on plain Java project
Quick search for dependencies in Maven remote repositories
So it appears there are 2 things needs to be done:
run mvn compile on parent project in that way all classes will appear in ../parent/target/classes folder. Note that they'll be automatically updated by Eclipse if you change source code
edit Eclipse run configuration and put this checkbox "Resolve Workspace artifacts"
Now I was able to run project as Maven build... with goal tomcat7:run and it worked without the need of parent project to be installed
That might be a dumb question but somehow I cannot figure it out (even with the lots of already given answers on stackoverflow) how to do it:
I created a maven project
I called mvn package and can execute the jar file with java -jar ... and everything works fine.
After I deploy the jar into the remote repository, I want everyone in my team to be able to just call a maven command (like mvn exec:java or something like that) on the command line and Maven shall download the jar file from the remote repository and execute it.
Independent of the current directory in which the user is. How do I do that? Currently I get the error message that I need to be in a directory with an existing pom.xml file.
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<groupId>handof.nod</groupId>
<artifactId>clirunnertest</artifactId>
<version>1.0</version>
<name>CLIRunnerTest</name>
<description>Kleines Testprogramm um zu testen wie Spring Boot auf der Command Line funktioniert</description>
<packaging>jar</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Package as an executable jar/war -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>java</executable>
<arguments>
<argument>-jar</argument>
<argument>target/clirunnertest-1.0.jar</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>
Your requirements are quite specific, there are ways to do what you want, but you may not find them suitable for your needs. In a nutshell, your requirements are:
Download a Maven artifact from a repository and execute it (supposing it is available on a repo)
BUT this needs to be "independent of the current directory in which the user is", i.e. your user should be able to run the command line from anywhere - that's the tricky part, because most Maven plugins require a pom and none will be available.
Solution 1:
What you can do is, in a single command line, download your artifact from the repo and execute it, with something like:
mvn org.apache.maven.plugins:maven-dependency-plugin:3.0.2:copy -Dartifact=handof.nod:clirunnertest:1.0.0:jar -DoutputDirectory=. && java -jar clirunnertest.jar
What it does is:
Download the jar file using the maven-dependency-plugin (which does not require any POM, lucky us)
Run a java command with your freshly downloaded jar (there are variants such as java -cp clirunnertest.jar MyMainClass
Solution 2:
Solution 1 require your user to specify the java command and its argument, not very flexible. With this solution you'll be able to change the way the command runs without impacting the end user.
First you will need to create a small project containing your exec:java or exec:exec configuration and upload it in your Maven repository, alongside with the jar you want to execute. You only need to write a standalone pom.xml with your jar dependency and related exec configuration such as:
<?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>handof.nod</groupId>
<artifactId>clirunnertest-pomrunnerproject</artifactId>
<version>0.1</version>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>run-java</id>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>handof.nod.clirunnertest.MainClassOrWhatever</mainClass>
<arguments>
<argument>bla</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>handof.nod</groupId>
<artifactId>clirunnertest</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
Once this project is available on your Maven repository, you can run:
mvn org.apache.maven.plugins:maven-dependency-plugin:3.0.2:copy -Dartifact=handof.nod:clirunnertest-pomrunnerproject:0.1:pom -DoutputDirectory=. && mvn exec:java -f clirunnertest-pomrunnerproject-0.1.pom
That will download the pom for this project and execute it like any other Maven project.
You can also do it in two times, first download the pom with the copy goal somewhere on your machine, and then run it from anywhere by specifying the path to the downloaded pom using the -f parameter:
mvn exec:java -f /path/to/the/pom/clirunnertest-pomrunnerproject-0.1.pom
This allow you to run this command from anywhere as long as you specify the path of the pom.
As you see, though they work, these solutions (and many variant you can imagine like these, such as having a bash script available on Nexus, having said configuration in a parent pom and using a sub-project with the -f parameter to use it from anywhere, etc.) are not really flexible nor easy to use and distribute. Maven may not be the best tool to achieve what you want, though implementing your own plugin as you discussed may be a solution ;)
There is not a single step to do so, and Maven generally wants to be able to use the ~/.m2 folder as a working area. You can however do it in two steps.
Download the artifact directly with dependency:get -
see How can I download a specific Maven artifact in one command line? for details.
Then they have the jar file and can start it as usual.
You can also create a pom.xml file for it which the users can download (again as an artifact) and then set it up for mvn exec:java.
If this is something you want to do on a regular basis, I will suggest a regular deployment! Java WebStart works well if you have a webserver somewhere you can store the files.
I know there are a dozen questions like this out there but I didn't find any of their solutions suitable for my case!
So, I'm trying to pack a jar file for a Spring-Boot project using Maven. I've created the whole project using IntelliJ IDEA and it runs under IDE. In order to build the package, I use mvn package from the command line.
The generated .jar file can be run on my development machine too but when I copy the .jar file to some raw docker container, it gives out the following error:
Exception in thread "main" java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/lucene-highlighter-5.4.1.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
And here's my pom.xml file:
<?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>project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.2.0</version>
</dependency>
</dependencies>
</project>
As it turned out, it had nothing to do with Maven and/or Spring-Boot. In case someone else might face the same issue, here's what I've done that led to this problem:
As a part of my deployment process, I would unzip the jar file, revise the config.properties and zip it again. It seems for some reason (unknown to myself), the generated .jar file is not executable and leads to the mentioned error.
My workaround was not to uncompress the .jar file, instead just replace the config.properties with a single command, like zip ./project.jar ./config.properties, while the project.jar is already in the current path. This one works!
I also faced this issue and tried the following way which worked well for me.
NOTE : Dont' extract and build new jar again. Simply extract and update existing jar with modified file.
For example, there is a jar namely myjar.jar in lab_directory
i) move to lab_directory and extract myjar.jar ( which has dir1/config.properties file )
ii) copy dir1 in extracted folder to lab_directory folder
iii) modify lab_directory/dir1/config.properties
iv) Run following command in lab_directory
jar -uf myjar.jar dir1/config.properties
That's it. Existing myjar.jar has been updated with modified config.properties file now.
It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
It just means that we should use no compression by a command like this:
jar -uvf0 example_app.war DIR_TO_ADD
Where "0" means that no compression will be used.
See "0" options in:
https://docs.oracle.com/javase/7/docs/technotes/tools/windows/jar.html#options
Such a way helped me to add the directory with files and run the java without errors like in the subject.
I have installed maven and I created a project using this command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
The result is there are 2 folder and 1 file created in my-app folder: src, target, and pom.xml.
Then I modify the pom.xml in order to get the all of required apache POI jars.
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.my-app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- This is what I added -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
</dependencies>
</project>
Then I run:
mvn package
but no jars downloaded into the project folder although I got message "BUILD SUCCESS".
What you've done is correct. However, the poi jars won't download to your project folder but to your local Maven repository. This is exactly what Maven is supposed to do so that you don't have to manage many libraries/jars yourself and get all in a mess. If you do a search of your local Maven repository, you should find it there.
I also suggest you read up on how Maven uses external dependencies, this is all explained here:
http://maven.apache.org/guides/getting-started/index.html#How_do_I_use_external_dependencies
If you want to package up all of your dependent jars in to one big jar look here:
How can I create an executable JAR with dependencies using Maven?
Your project has a jar packaging type. Java not support nested jar and then maven package doesn't put any jar in your project . To do this you have to use Maven Assembly Plugin or use Spring-boot to make your uber jar
I'm new to maven, and trying to understand how to release my project. I have the following project setup in svn:
trunk
|-deployer
| |-pom.xml
|-webapp
| |-pom.xml
|-utils
|-pom.xml
While developing webapp, I always want to develop against the latest snapshot version of utils, so I declare the dependency on utils in webapp/pom.xml via:
com.company
utils
1.0-SNAPSHOT
Webapp itself is also currently versioned at version 1.0-SNAPSHOT. It's pom.xml has the declaration:
<artifactId>webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Sample Webapp</name>
So everything is working great, but now I want to release my software. In deployer, I have the following in 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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>deployer</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>Project Release</name>
<modules>
<module>externals/webapp</module>
</modules>
<properties>
<url.svn>http://<my-server>/<project>/trunk</url.svn>
</properties>
<scm>
<connection>scm:svn:${url.svn}</connection>
</scm>
<build>
<plugins>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.3</version>
<configuration>
<tagBase>
http://<my-server>/<project>/tags
</tagBase>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>Releases</id>
<name>Releases</name>
<url>http://<nexus-server>/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>Snapshots</id>
<name>Snapshots</name>
<url>http://<nexus-server>/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
</project>
Within the deployer folder itself I have a folder called "externals" which has an svn-externals set to check out my webapp project (I added this because maven complained about not being able to find it), so my modules path should be correct.
Questions
1.) I want to release a version of my web app, but when I run a mvn release:prepare and mvn release:perform in my deployer project, my only tangible output is my trunk tagged in svn and a pom uploaded to my nexus repository. This makes sense in that my deployer artifact packaging is type "pom", but it also doesn't get the job done of getting me a war of my webapp (I should note here that if a do a release in the webapp project by itself though, that I will get the war). I need to release multiple modules, and so I thought I could use maven aggregation from the deployer project to accomplish this, but it doesn't seem to be working.
2.) Is there a better way to achieve what I am trying to do?
Thank you for any insights you can provide.
You should run the maven-release-plugin against each module that you intend to release. I've never seen someone have a special "deployer" module that releases the other modules, this is not how things are commonly done.
Normally to release the webapp module you would run the commands against the webapp module, and to release the utils module you would run the commands against the utils module.
If you have a parent module that ties webapp and util together then I believe you can just run the release commands against that.
As matt b says, simply adding a maven-release-plugin entry at the top pom will probably do what you want. If you want to collect several artifacts into a proper release bundle, you want to create a module for this, but then you want to look at the maven assembly plugin. It can collect various jars (wether from modules or external dependencies) and resources into a directory, zip file or similar.