How to create a cross project source release with Maven - java

I have a project I need to release the source for. The problem I have is that I need to create a source release for all code that we have developed. The code is across multiple projects, but I want to leverage maven so that only the source for the jars we are actually using is released.
For example:
core code project (multi module maven project)
web app project (multi module maven project). Contains we app module plus some supporting jar modules. Depends on some jars from core code project.
Now I want to release all the source for the web app project but only the source for the core code project that the web app uses.
Can I do this with maven?
I have a feeling it is possible with assembly plugin and source plugin but it is not clear to me how to put this together.

First of all your question is bit unclear. let me assume certain things and proceed.
I believe that following is your folder structure.
web app project
some source code folder
pom.xml
core code project
some source code folder
pom.xml
Take the core code project and change the version from previous version in pom.xml.
let 's say if it was 1.0 change it to 1.1
<groupId>core code project related</groupId>
<artifactId>core code project</artifactId>
<name>core code</name>
<version>1.1</version>
Make your changes to accomodate the web app project in core code project.
later,
in web app project add dependency for core code project in pom.xml
<dependency>
<groupId>core code project related</groupId>
<artifactId>core code project</artifactId>
<name>core code</name>
<version>1.1</version>
</dependency>
In this way, 1.1 version of core project will have only web app related code.
Currently we are using this method. Hope it helps. let me know if you want something else.

I have a feeling it is possible with assembly plugin and source plugin but it is not clear to me how to put this together.
If I understood the question correctly, one solution would be to create an "aggregator" project listing all wanted modules (the relevant modules from the webapp and the relevant modules from the core) and to use the source:aggregate goal from the Maven Source Plugin.

I'm unsure why you want to do this, the pom from your web app project will explicitly list the versions of your code dependencies used, so you can find the source easily. It sounds like you want to store the same artifact twice. So if your web app uses core-x-1.2.3.jar and core-y-4.5.6.jar you would produce a web app sources artifact containing the source from both those core jars in addition to the actual web app source?
You can use the maven versions plugin to update your web app pom to use the latest versions of your core dependencies, I've automated that by running a shell script in a CI server in the past. That means whenever you release a new version of your web app you will be using the latest release of your core code, and all you need to do is update your web app pom from version control.

Related

Gradle Plugin dependency

What is the exact dependency I need to develop a Gradle Plugin in Java? Ideally I would like to get it from a well-known repository such as Maven Central or similar.
I have a Maven project with a core functionality and I just added two extra plugins, one for Ant, one for Maven. They are already tested and working; easy! Now, I wanted to add a third module for a Gradle plugin to make this functionality also available from any Gradle project.
However, I can't find the exact dependencies I need to develop a Gradle plugin.
The Gradle docs (such as https://docs.gradle.org/current/userguide/java_gradle_plugin.html) are not very well written to say the least. They mention:
the gradleAPI() dependency
or the java-gradle-plugin dependency
But they are quite unclear... no group, no version (really?).
If anyone can enlighten me to where I can get these dependencies from, I would be very thankful.
Gradle's public and internal APIs, aka gradleApi(), are bundled with the Gradle distribution and not independently published and therefore not easily consumable by Maven builds. There's the pending epic #1156 (Ensure plugin cross-version compatibility by allowing a user to depend on gradlePublicApi()) that might help here.
Since Gradle plugins are best to be built with Gradle, a pragmatic solution is to invoke the Gradle build from Maven and attach the produced artifact to the Maven build. Andres Almiray (aalmiray) once described this in the blog post Running Gradle Inside Maven (Web Archive Link). He describes the following high level steps:
Create a new Maven module (e.g. gradle-plugin) and add attach it to the parent POM
In the POM of gradle-plugin add a dependency to your core module. Use the maven-dependency-plugin to store dependencies to the Maven build folder, e.g. target/dependencies.
Create the build.gradle, add a Maven repository that points to target/dependencies (step 2) and let it depend on the core module as well as gradleApi(). Implement the Gradle plugin.
Use the exec-maven-plugin to invoke the Gradle build.
Use the maven-resources-plugin to copy the Gradle built plugin jars to the standard Maven build folder.
Use the build-helper-maven-plugin to attach the copied jars to the Maven build.
Sample project to be found here (gradle-in-maven).
https://docs.gradle.org/current/userguide/custom_plugins.html#sec:custom_plugins_standalone_project
In here it is mentioned that it is gradleApi() and I know that this works (from experience). The localGroovy() on that page is only needed if your plugin code uses groovy (does not apply if you only use groovy in the build.gradle of your plugin).
java-gradle-plugin is a library that makes it a bit simpler to make plugins, it is not required though. I personally prefer using gradleApi only.
EDIT:
It appears I've misunderstood the question. Here are the steps to get gradleApi jar:
Create a Gradle project with your desired Gradle version.
Add implementation gradleApi() dependency.
Import/run the project once.
Go to your .gradle folder (located in home folder in Linux-based operating systems).
Open caches folder
Open the version folder you want, e.g. 6.0.1
Open generated-gradle-jars folder.
Copy the jar to wherever you want and use it.
For me the 6.0.1 jar is at ~/.gradle/caches/6.0.1/generated-gradle-jars/gradle-api-6.0.1.jar
Please note that I have not tested this, I know the jar is there but I haven't tried using it.

JarJar'ed artefact and Maven deploy process

I am currently developing an SDK targetting both servers and Android devices.
My deliverable JAR is JarJar'ed, thus preventing any dependency leaks from happening in client apps (using maven-jarjar-plugin).
However, there is one issue that puzzles me. A standard Maven deploy will ship sources, POM and other things. The problem is that any Maven-compatible build tool (e.g.: Gradle) will first resolve our SDK according to the deployed POM, thus triggering the pointless downloads of my SDK dependencies (remember: they are JarJar'ed in the final JAR!).
How can I deploy my SDK so that any build tool will understand there is nothing but the SDK to download?
That strange, I'm surprised if the jar jar plugin doesn't support it natively. You may give a try to the shade plugin which is also allowing to relocate classes and for sure it creates and deployed a modified pom for your artifact that won't expose your embedded dependencies to others projects using yours.
See :
http://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html
http://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html#createDependencyReducedPom
cheers

Maven compile dependency instead of taking it out of the local repo

I am sorry i don't know maven good enough for the complex environment i am currently working in (1k+ applications, most of them are Java EE). I still give it a try to describe what i want to archive:
0.) There is a company framework that abstracts the Java EE World a bit and is used in all the Java EE components
1.) I checked out the maven project of the Java EE component i am working with
during the build it downloads the dependencys of other components out of the companys repository and stores it inside my local repo for compilation. So i can see the jar-files of the companys framework inside my local repo.
2.) I now want to change some of the frameworks functionality for a local test so i checked out their sources from another SVN repository. I made the changes and build that framework component with maven "clean install".
3.) I rebuild the component i am working with as well.
Inside eclipse i can now click on one of a frameworks classes method and it opens the according source. But this only happens because the local repo is meant to contain source-jars for any dependency as well. So in my editor i can see this source is from the jar of the framework in my local repo and i cant change anything.
Could someone please give me a hint how i can archive the following:
I can make changes to the framework (and build the frameworks jars with "clean install")
I can build my component and it uses the above compiled framework jars rather than the "old" ones from the local repo.
I will right now start to read the entire maven documentation and each and every section (i try to understand that dependency management since 1 year and still don't get it) but i would really appreciate if you could help me out a bit here.
I don't know how Eclipse manages maven dependencies, but
In IntelliJ IDEA this is simple - if maven dependency is in project then IDEA uses it instead of dependency from local repo.
So if u want to edit framework source code and use this changes immidiately - i think that framework should be in your Eclipse Workspace. And your module in Eclipse should reference framework artifacts directly - not over Maven dependency mechanism.
I think that this is a Eclipse Maven plugin responsibility. Do u have any installed Maven plugin for Eclipse? (M2Eclipse for example)

Using (Scala) library from Java Web App, getting NoClassDefFoundError

I've been working on a rather "standard" Java web application for a long time now. I develop in Eclipse using Eclipse's server plugin to run the app in Tomcat. The app's setup is straight forward: Spring for bootstrapping, Wicket for web, Hibernate for ORM, Maven for dependency management.
Today I have added Akka 2.0 to the project. I added it to my POM as per the manual:
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor</artifactId>
<version>2.0.2</version>
</dependency>
Maven finds the dependency and I can see it showing up in the Maven dependencies in Eclipse's package explorer. The referenced Scala Library also shows up (version 2.9.2 as it seems).
I can use the library just as one would expect: Eclipse finds the classes, I can jump to source files etc. Everything works perfectly. But once I start the app and it comes across any part of the program with references to Akka it throws a NoClassDefFoundError.
Since all other libraries still work as expected, my best guess is that is has something to do with the fact that Akka is a library developed in Scala. Since I've hardly used Scala myself though, I could not find any solution to the issue myself and Google isn't really that helpful when it comes to such generic exceptions.
Do you have any advice?
Verify that the required library (AKKA) is in your deployment assembly under Eclipse: open the project's properties and look for "Deployment Assembly" on the left.
[I'm using Eclipse Indigo]
You could verify the presence (or lack) of the expected jar file by examining the deployment under tomcat.

How to use Maven in my Java Project and Why?

I am trying to figure out the use of Maven and I got many articles describing its features and uses. But I am just not able to understand the actual use of Maven from productivity standpoint.
From what I am used to in our school projects was just create a new Java project in Eclipse, write your Code, create a .war (if web-based) and paste the code to the webapps folder of Tomcat and start the server!
So,
Where does Maven come into picture? I have used Ant and I understand Ants benefit of a standardized build process. But why do we need an advanced Ant in form of Maven?
In any case, I need to use it, so where do I get started - basic flow, some good tutorials?
Thanks
Maven is used to manage the build, testing, and deployment processes. It can separate the unit tests and integration tests so you only run them when necessary and cut down on build time.
It is also a dependency manager, which means when you realize the server piece of your project needs apache commons-logging 1.0.4 but the client conflicts with anything past 0.7.9, you can just add a couple lines to the respective pom.xml files, and Maven handles all of that (downloading, installing, and keeping track of the different versions of those dependencies).
I was not a believer before my current task, but after 2 years using it for large enterprise applications, I definitely respect what Maven brings to the table. There are a lot of online resources but if you are going to be the lead on this and really feel uncomfortable, I recommend getting a book -- the O'Reilly one is helpful.
Forgot to mention that there is an Eclipse plugin which makes it almost painless to use with Eclipse: m2Eclipse.
Second update for example pom.xml segment to answer OP question:
Your pom.xml will contain XML code such as:
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
These are downloaded from the central Maven repository (google "maven nexus") or you can configure your own additional repositories (like for your own projects, or if you are not Internet-connected).
I had exactly the same perception as you and for years I avoided Maven.
The thing is, it allows you to easily get the required jars your application may need( called dependencies - jars and other things - ) . So the next time somebody else run your project he will get the jars automatically.
I know that's a bit hard to grasp, until you work with an existing projects using it.
For instance I downloaded an open source project recently, which depended on 10 or 12 different on different jar versions. After downloading the source code and executing Maven, all those jars ( and a lot more others ) were downloaded for me.
The problem with Maven ( as a friend of mine told me ) is that to perform a "Hello world" program, it first downloads the world to greet him. :P
for all those wondering where the maven downloads the dependency jars, check out a folder named .m2 in the user root directory. eg. for me it is the c:\documentsand settings\myUserName.m2\
also i have researched a bit on maven and i have made some small scribbling like reminders. If it is worth a read then here it is ::
/*
mvn generate
mvn install downloads all necessary jars
mvn test tests the application made...
mvn site builds the site downloading dependencies
to deploy the site, we need to declare a location to distribute to in your pom.xml,
similar to the repository for deployment.
...
website
scp://www.mycompany.com/www/docs/project/
...
mvn site-deploy deploys the site
how to build structure of site :
The site.xml file is used to describe the layout of the site, and replaces the navigation.xml file used in Maven
A sample is given below:
Maven
http://maven.apache.org/images/apache-maven-project.png
http://maven.apache.org/
http://maven.apache.org/images/maven-small.gif
<menu name="Maven 2.0">
<item name="Introduction" href="index.html"/>
<item name="Download" href="download.html"/>
<item name="Release Notes" href="release-notes.html" />
<item name="General Information" href="about.html"/>
<item name="For Maven 1.x Users" href="maven1.html"/>
<item name="Road Map" href="roadmap.html" />
</menu>
<menu ref="reports"/>
...
so in effect, we need to link our html to this structure format to make the website layout
also in order for us to add any new css or such stuff, all we need to do is to put them into the resources part of the
src folder
then we can create a war file of our project and lay it out in the httpd folder of apache or such similar folder ofour web server
In case we need to generate projects, we need to add a few lines of code to our pom.xml file and that is:
...
org.apache.maven.plugins
maven-project-info-reports-plugin
2.0.1
...
also, site descriptors are to be set in site.xml
the details can be seen in the documentation of maven
maven structure with their importance:
project/
pom.xml - Defines the project
src/
main/
java/ - Contains all java code that will go in your final artifact.
See maven-compiler-plugin for details
scala/ - Contains all scala code that will go in your final artifact. ////not needed for our current project as of yet
See maven-scala-plugin for details
resources/ - Contains all static files that should be available on the classpath
in the final artifact. See maven-resources-plugin for details
webapp/ - Contains all content for a web application (jsps, css, images, etc.)
See maven-war-plugin for details
site/ - Contains all apt or xdoc files used to create a project website.
See maven-site-plugin for details
test/
java/ - Contains all java code used for testing.
See maven-compiler-plugin for details
scala/ - Contains all scala code used for testing.
See maven-scala-plugin for details
resources/ - Contains all static content that should be available on the
classpath during testing. See maven-resources-plugin for details
mvn validate this will validate that all the dependencies are satisfied and nothing is missing
mvn compile this will compile the project
mvn verify checks whether the package is valid or not
also in the project, the dependencies are to be inserted into the xml file
the example of dependencies injection is given below::
org.scala-lang
scala-library
2.7.2-rc2
junit
junit
3.8.1
test
Each dependency consists of several items:
* groupId - The group of the dependency to rely on
* artifactId - The artifact in the group to rely on
* version - The version of the dependency to rely on
* scope - The "scope" of the dependency. Defaults to compile (more details later)
* packaging - The packaging for the dependency. Defaults to jar (e.g. jar, war, ear)
You can integrate your static pages by following these steps:
* Put your static pages in the resources directory, ${basedir}/src/site/resources
* Create your site.xml and put it in ${basedir}/src/site
* Link to the static pages by modifying the menu section, create items and map them to the filenames of the static pages
mvn tomcat:deploy to deploy to tomcat or apache, you can go for this command
Free books about Maven can be downloaded from Sonatype (where the original developers of Maven come from).
Also see the documentation on the Apache Maven website.
Where does Maven come into picture? I
have used Ant and I understand Ants
benefit of a standardized build
process. But why do we need an
advanced Ant in form of Maven?
Maven introduced "convention over configuration" this helps if some colleagues write bigger ant scipts than code. plus dependency management, the only trouble is to convert monolithic projects with many artifacts.
In any case, I need to use it, so
where do I get started - basic flow,
some good tutorials?
I found these tutorials
And Maven: The Definitive Guide
helpful.
The latest netbeans also has a pretty good maven integration.
If you are within an organization, try to build a maven repository proxy. Artifactory is a good option.

Categories