Module dependency to generated jar - maven-2

I have one project (called EJB server) that contains X-Doclet annotated EJB service and a client project (module) that depends on client jar generated from server project.
What is best practice in maven for setting such dependencies when one project (module) depends on JAR which is generated from other module?

There are two possible scenarios:
If you develop these two modules in parallel and are part of the same project then create a parent POM and declare the two modules. Depending module (client) should declare as a dependency the declaring one (server).
If both modules are developed separately then release the server, declare that client depends on server and let the maven retrieve the server from your private repository.

Related

Access classes from other module

I have an minecraft forge workspace that is made by gradle, I have an project in which I have an module with the mod I'm working on and one module with my library mod, I want to somehow access classes from my library mod from the other module, I imported modules by using their build.gradle and now I have 2 different modules but I can't access one module from another one.
You need to add a dependency from the working module on the library module. If this is a multi-module Gradle build where both projects are modules, you can simply add a project(':library') dependency. If those are separate Gradle builds, you need to add a normal dependency like 'your.group:library-module:1.0' and then either install the library module to some repository like the local maven repository with the mavenPublish plugin to be able to use it from the working module, or use a composite build to replace the dependency by the automatically built result of the library module. For more information on how to do either, you should read the Gradle Userguide.

Invalid ejb jar: it contains zero ejb.

I have 2 modules: ejb and war, and ear module, that contains them. Modules build successfully, but when I try to deploy ear to glassfish, I recieve this error:
glassfish3.1.2|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|_ThreadID=17;_ThreadName=Thread-2;|Exception while deploying the app [EarModule] : Invalid ejb jar [BackEnd-1.0-SNAPSHOT.jar]: it contains zero ejb.
Note:
1. A valid ejb jar requires at least one session, entity (1.x/2.x style), or message-driven bean.
2. EJB3+ entity beans (#Entity) are POJOs and please package them as library jar.
3. If the jar file contains valid EJBs which are annotated with EJB component level annotations (#Stateless, #Stateful, #MessageDriven, #Singleton), please check server.log to see whether the annotations were processed properly.|#]
I really don't know what to do, I've found a lot of questions like mine, but there was no solution.
I understood, what was wrong. The problem was in run configurations, I'm using Intellij Idea and in run configurations there was build and make before run of my ear module. I removed this and after maven install it deployed successfully.
You have to add an EJB into your WAR or EAR file. Just Create a new Class and annotate it with #Stateless
I know this is very build specific and it uses Netbeans instead of the OP's IDE but because I was lead here and this will likely be useful to some users:
I had the following build:
Netbeans Enterprise Application with Maven
Glassfish 4.1
Java EE 7
I had tried migrating from a previous non-maven enterprise application and the clone didn't quite work the way I expected, there was some old ejb jars lying around that I deleted.
I had done quite a few things to fix it:
Ensure theres no ejb jars lying around that shouldn't be there. Ensure that you don't have accidently have the ejb module jar included more than once as this can result in the same error too (Manually deploying the ear and deployment through netbeans sometimes gave me different errors).
I used the #Remote interface on my EJB applications. Now you should not be importing your EJB into your War, you should use the annotations correctly as described https://docs.oracle.com/javaee/7/tutorial/ejb-intro004.htm
(This is more of a note) When you update any of your war or ejb, clean and build them before cleaning and building your ear (sounds funny right?).
If you are using interfaces for your session beans then you should put them in a separate jar, make a new project maven > java application. Do the same thing with your persistence entities. Add these as dependencies to both your ejb and war project.
This doesn't relate to me in particular but you should have at least 1 #stateless (or I think #stateful) annotation in a java class inside your ejb module for it to run (for the module to be considered an ejb).
I likely had to do a few more things that I forgot but if you still run into issues comment below and I'll try to update.
Just try to build & install your project using Maven , and then , deploy it in glassfish ( do not run your project directly from your IDE )
I encountered this problem as well. It occurred when I had imported a new EJB project into my Eclipse workspace. The project didn't have a reference to the Glassfish libraries then, since it was not yet included in the EAR deployment assembly.
Upon saving the Bean file, the IDE automatically imported javax.inject.Singleton instead of javax.ejb.Singleton. This made the code compile without warnings, but throw the same error as in the original post.

Maven2: Possible to deploy depends on artifact classifier?

In fact I have 2 different problems, but I think they are kind of related:
I have an artifact, with an assembly descriptor set which will build an extra JAR (with extra classifier). By default, Maven2/3 will deploy the assembly generated together with the main artifact to remove Maven repository. Is there any way that I can deploy only the main artifact but not the assembly?
I have an artifact, in which I have jar plugin generate another artifact with different classifier (more specific, an EJB artifact, and I generate an client JAR). I want to deploy only the client JAR to Maven repo coz I think the main EJB artifact is not really going to be shared by other project. Is it possible to do so?
Thanks a lot
editied to provide more info:
The reason for avoiding deploy the EJB, is because the EJB main artifact is not going to be depended by other project except the containing project. The containing project will build a EAR (which contains the EJB), and normally we only need that build locally (by mvn package). However, the EJB client is something that we will deploy to our repo to let other project share when they need to communicate with our application.
Honestly it doesn't harm to deploy the EJB too, but I just want to see if I can save unnecessary waste of disk space on our repository.
Similarly, for deploying assembly, it is because the project is something we want to deploy to let other project to depends on. However, when building that project, we also have a separate assembly created on the same time (for example, an all-in-one executable jar) which we only need that built locally, and it is not something that other projects will depends on.
Turn off the 'attach' option to the assembly plugin. Then it won't be officially an artifact and it won't deploy; it will just lurk in the target directory, sulking that you don't love it as much as it's elder sibling and plot revenge.
Based on your first question i would like to know why do you create the supplemental assembly which is usually deployed as well as the main artifact. If you wan't to prevent you can put the creation of the assembly into a profile but this means you will not generate the supplemental artifact in your usual build only by activating the profile.

Maven: Combine web projects

I have following Maven projects set up:
PM-Core
PM-Web (with a dependency to PM-Core)
Now, this project is used for several clients but for each client there are some small differences: mostly differences in configuration files but some clients also require additional java files (which may not be installed for the other clients).
I've been considering several alternatives on how to support this with maven but am still looking for the perfect solution.
The best solution I can think of is to create a separate maven project for each client (e.g. PM-CLIENT1, ...) which contains only the client specific configuration files and additional java files or jsp's, ... . Next step would be to consider the PM-Web project and the client project as one web project, meaning: have them combined (packaged) into 1 war file with files from the client project having precedence over files from the PM-Web project.
More concrete: running mvn package on PM-Client1 would take everything from PM-Web, add/replace the files from PM-Client1 and then package this into a single war.
So the question is: how to achieve this with maven?
Yes, this can be done using Overlays. The sample on the webpage is exactly what you are talking about.
For the project structure, you could have something like this:
.
|-- PM-Core
|-- PM-WebCommon (of type war, depends on core)
|-- PM-Client1 (of type war, depends on webcommon)
`-- PM-Client2 (of type war, depends on webcommon)
And use overlay in PM-Client1 and PM-Client2 to "merge" them with PM-WebCommon and package wars for each client.
UPDATE I won't cover all the details but I think that declaring the war dependency with a scope of type runtime is required when using overlay, this is how overlay do work (actually, the whole overlay thing is a kind of hack). Now, to solve your eclipse issue, one solution would be to create a JAR containing the classes of the PM-WebCommon project. To do so, use the attachClasses optional parameter and set it to true. This will tell maven to create a PM-WebCommon-<version>-classes.jar that you'll then be able to declare as dependency in PM-Client1 (with a provided scope). For the details, have a look at MWAR-73 and MWAR-131. This is also discussed in the FAQ of the war plugin. Note that this is not a recommended practice, the right way would be to move the classes to a separate module (and this is the other solution I wanted to mention).
UPDATE (201001018): I've tried the attachClasses parameter and it works with version 2.1-beta-1 of the plugin.
You could use profiles see http://maven.apache.org/guides/mini/guide-building-for-different-environments.html and use classifiers to distinguish between the artifacts from the different builds for the same version.
In this setup, you could create additional optional modules for each of your clients specific customisations under the parent project i.e.
+ PM
++ PM-Core
++ PM-Web
++ PM-Client1
++ PM-Client2
Or you could look at using use the maven assembly plugin
Compare also the answers for question different WAR files, shared resources .

maven-assembly-descriptor include this very module

In a single-module project, I don't see how to get a 'classified' artifact from the project itself into the descriptor and thus the assembly. Do I list it as a dependency?
Did you try the Build Helper Maven Plugin (I'm thinking to build-helper:attach-artifact)? See Attach additional artifacts to your project in the plugin Usage page.
If it doesn't work, then indeed declare your 'classified' artifact as dependency using one of the advanced identity pattern.