I'm using the maven-ejb-plugin to generate ejb client for my client, in the standard way
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.3</version>
<configuration>
<ejbVersion>3.0</ejbVersion>
<generateClient>true</generateClient>
</configuration>
</plugin>
So the client use its dependecy
<dependency>
<groupId>en.foo.ejb</groupId>
<artifactId>artifact-ejb</artifactId>
<version>1.0.0</version>
<type>ejb-client</type>
</dependency>
I'm having 2 issues so far:
Launching mvn clean install or mvn clean deploy install ALSO the whole ejb package jar, so in the end I'll have both
artifact-ejb.jar
artifact-ejb-client.jar
I'd expect to install only the second one, because the artifact-ejb.jar should not be installed on the repository
The ejb artifact includes a parent pom, so when the client try to resolve all the dependencies it says the parent pom cannot be found on the repository, however the parent it is not meant to be distributed because it is only a reference.
(see also https://howtodoinjava.com/maven/maven-parent-child-pom-example/)
How can I solve these issues ?
Your artifact-ejb-client.jar contains only the interfaces. At runtime, you need to have the implementations as well. So if you want to build a proper ear or war, you need both artifact-ejb-client.jar and artifact-ejb.jar. The only exception that comes to my mind is RMI communication where you would be fine having only the client (on the calling side). So think about whether you really want to keep the artifact-ejb.jar out of your repository.
If you decide to do so, split your project into two separate projects, one containing the interfaces and one containing the implementations. The impl-project needs the client-project as dependency. Then you can freely build and deploy just one of the two.
For the parent poms: All parent poms of your artifacts need to be in the repository, otherwise the builds will break. If you depend on an artifact, you need to resolve its parent pom. It cannot be kept "secret".
Related
The java application I develop should run on servers I have not direct access to. Sometimes dependency conflicts arise. I mean that on some servers the app works perfect and on other ones same application fails. And the errors indicate libraries version conflict. I would like the application informs about the library version conflict rather than just crashes with NoSuchFieldError, NoSuchMethodError, NoClassDefFoundError etc.
I may obtain libraries list on the application building platform with mvn dependency:tree
So, I need the application reads the libraries versions on platform where it runs, compare it with libraries list on building platform and report about versions mismatching. So, how the application could define libraries in runtime? Or maybe there exist more convenient way to automate dependency conflict discovering?
I believe you need resolve this kind of problem before deployment. You cannot rely on Running Tool to save. So I would suggest solve them at much earlier stage.
If you use maven to manage dependency. You can try below:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<configuration>
<rules><dependencyConvergence/></rules>
</configuration>
</plugin>
</plugins>
Then
mvn enforcer:enforce
You can read this good material
I have a maven module (let's call it frontend) which contains no java code but instead uses frontend-maven-plugin to build a js frontend. Another (backend) module uses the built data from the frontend module and embeds it in itself via the maven-assembly-plugin like this.
<fileSet>
<directory>${project.parent.basedir}/frontend/target/dist</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
This works, however when running maven install on the project containing these two modules, backend module seems to always build first, which means it either doesn't pick up the front-end files (in case of a first time build or clean install) or it always picks up the previous build. I've read that maven decides the build order by checking if the modules depend on each other either as dependencies or plugins or something, however as the frontend module is not java, it can't work as a dependency. Is there any other way I can hint to maven to consider building frontend first?
You need to explicitly mention the type of the dependency
<dependency>
<groupId>xxx</groupId>
<artifactId>yyyy</artifactId>
<type>pom</type>
</dependency>
Sorry if this is too trivial, but I've recently jumped into Wep Applications from standard console java projects, and since in java projects I successfully used maven to download jars and include them into the classpath... in the web app I don't know how to accomplish the same stuff and downloading to the lib folder on WEB-INF instead of just adding the jars to my classpath.
I have searched stack overflow and the google for an answer, but since I haven't found any single answer, I'm afraid I should be completely wrong with my approach for this.
I have just created my webapp on eclipse, then converted it to maven project, and then added this dependencies in pom.xml, as I used to do in a normal java project:
<dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
Everything seems to be ok, and no error is shown, but the jars are not downloaded into the WEB-INF/lib folder.
Thanks in advance for any help you can provide.
If your project is correctly configured as "Maven project" there should be a folder called "Maven Dependencies" in your package view.
A good hint if your project is configured as Maven project is a little "M" on the top level folder.
Eclipse will download in a so called "Repository". This is mostly located in $HOME/.m2
Generally you don't have to care about jars directly. Maven will download them and create a classpath transparently for you.
The eclipse maven integration is called m2e.
The concept of Repositories is central to maven. They are the place where your dependencies and external dependencies are stored. Two repositories you can always assume to exist are the already mentioned local one and the other so called "Maven-Central" see here. Beside that you can setup , for example, company wide Repositories with tools like Nexus or Artifactory.
To upload a dependency in your local Repo use the mvn install command.
What maven within mvn install is executing the install lifecycle.
and then uploads the resulting artifact (generally a jar or war, but not necessarily) and some metadata (your pom mainly) to the repository.
You can then develop against these dependencies via the dependency mecahnism.
Dependencies in you installed in your local Repository are always of type "SNAPSHOT". There is more to know about the difference between SNAPSHOT and Release (only version number) and how to deploy/release them, but these questions are already awnsered several times.
Adding this plugin to pom.xml will help to get jars in lib folder.
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>WebContent/WEB-INF/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
I am really new to maven. I am bit confused about the dependency feature. I know that I can add dependency in the pom file like this
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
What does this actually mean? Does it mean that I dont need to import the slf4j jar files into my project? If so how does my project get access to those libraries?
I have read about dependency from maven site but didnt help me much.
Can some one explain it in a simpler way.
Thanks
Nutshell: It means your project has a dependency on slf4j, version 1.6.1.
Furthermore:
If you build your project with Maven (or your IDE is Maven-aware), you don't have to do anything else in order to use slf4j. (Aside from normal source-code considerations, like a reasonable import statement, etc.)
slf4j v. 1.6.1 will be retrieved from a default Maven repository to your local repository, meaning...
... ~/.m2/repository is your repository. slf4j will be put in $M2_HOME/org/slf4j/$(artifactId}/1.6.1 and will include (in general) a jar file, a pom file, and a hash file.
Slf4j's dependencies will be downloaded into your local repository as well.
Dependencies of those dependencies will be downloaded ad infinitum/ad nauseum. (The source of "first use of a library downloads the internet" jokes if there are a lot of dependencies; not the case for slf4j.) This is "transitive dependency management"--one of Maven's original purposes.
If you were not using maven, you would manually download and use the dependencies that you needed for your project. You would probably place them in a lib folder and specify this location in your IDE as well as your build tool.
maven manages these dependencies for you. You specify the dependency your project needs in the prescribed format and maven downloads them for you from the internet and manages them. When building your project, maven knows where it has placed these dependencies and uses them. Most IDEs also know where these dependencies are, when they discover that it is a maven project.
Why is this a big deal? Typically most open source libraries release newer versions on a regular basis. If your project uses these, then each time a newer version is needed, you would need to manually download it and manage it. More importantly, each dependency, in turn may have other dependencies (called transitive dependency). If you do not use maven, you would need to identify, download and manage these transitive dependencies as well.
It becomes complex the more such dependencies that your project uses. It is possible that two dependencies end up using different versions of a dependency common to them.
When compiling your project, Maven will download the corresponding .jar file from a repository, usually the central repository (you can configure different repositories, either for mirroring or for your own libraries which aren't available on the central repositories).
If your IDE know about Maven, it will parse the pom and either download the dependencies itself or ask Maven to do so. Then it will open the dependencies' jars, and this is how you get autocompletion: the IDE "imports" the jars for you behind the scenes.
The repository contains not only the ".jar" file for the dependency, but also a ".pom" file, which describes its dependencies. So, maven will recursively download its dependencies, and you will get all the jars you need to compile your software.
Then, when you will try to run your software, you will have to tell the JVM where to find these dependencies (ie, you have to put them on the class path).
What I usually do is copy the dependencies to a target/lib/ directory, so it is easy to deploy the software and to launch it. To do so, you can use the maven-dependency-plugin, which you specify in the <build>:
<build>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</build>
There are a variety of servers on the internet that host artifacts (jars) that you can download as part of a maven build. You can add dependencies like you show above to describe what jars you need in order to build your code. When maven goes to build, it will contact one of these servers and download the jar to your computer and place it in a local repository usually
${user_home}/.m2/repository
The servers that maven contacts must be configured in your maven project pom file, under a section like
<repositories>
<repository>
</repository>
</repositories>
The prototypical server can be seen at repo1.maven.org
The nice thing about maven is that if a jar you list is needed, it will pull not only that jar, but any jars that that jar needs. Obviously, since you are pulling the jars to your machine, it only downloads them when it can't find them on your machine, thus not slowing down your build everytime (just the first time).
This question is not really about best practices or architecture, but about how to specifically configure Hudson and Maven to accomplish what I want. I'm a bit lost.
I have a Java application which uses SWT, and I need to build copies for different platforms. For now, all I need is Linux i386 and Linux amd64, but in the future, I need to add Windows x86/x64 as well, so I want to make sure I set it up "right" the first time around.
My application has all of the dependencies and other information listed in the Project pom.xml, including the different SWT jars to grab depending on OS, arch, and family.
My question is, how do I do builds for both linux i386 and linux amd64 with a minimal amount of configuration duplication? Right now I'm doing the following:
Project specifies all dependencies in pom.xml, and this project is set to build in Hudson and deploy the resulting .jar to Nexus
Builder-linux-i386 runs after Project and specifies any JNI files for i386 and uses the de.tarent maven-pkg-plugin to grab the project jar from Nexus and assemble it along with all dependencies into a single 'fat' jar file, and then into a .deb file for installation.
Builder-linux-amd64 does the same, but for amd64 files
I have been trying to specify which dependencies to use in the Builder projects by adding -P profilename to their Hudson projects, where profilename is a profile named in the Project pom. Maven doesn't seem to like this and prints that it is not activating that profile. It only uses the default profile from Project's pom.
What is the correct way to set this up? I want to have all of my dependencies specified in my Project pom, and have a Hudson project which compiles the jar for that project and deploy it to Nexus, and then independent projects which grab that jar and assemble it along with platform-specific files for release. I don't want to build the entire original project repeatedly, and I don't want to have a ton of duplicated configuration info or copy-pasted poms.
I have it working for unix-amd64 only because that's what the build machine is, so Maven targets that architecture. Also, I feel like the setup isn't as clean as it could be. Advice?
You have an syntax error. It needs to be -Pprofilename. It works for me this way.
Edit
Since the profile is read. There might be an syntax error in your profile configuration. I found a profile in one of projects, that I integrate into our CI environment. It defines some dependencies, it might help you.
<profile>
<id>junit</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>false</skip>
<testNGArtifactName>none:none</testNGArtifactName>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
Profiles should work in the way you desciped it (you could post an other question about this).
But at (least for web applications) there is an other way: Try to use classifier instead of profiles to build for different environments. -- You can have a look at this blog: http://blog.jayway.com/2010/01/21/one-artifact-with-multiple-configurations-in-maven/
The purpuse of this solution is, that you are able to build (if you want (controlled by an profile)) for all environments at once.
The builder projects do not see the profiles from the main Project because it is not actually a parent. I cannot define it as a in the builder projects because my projects are not set up that way, and I'm building using variables like ${SVN_REVISION}, which maven does not like.
I have given up and instead copy-pasted the profiles into the 'builder' projects. This isn't the prettiest but for now it works.