Running a multi project Maven-built webapp on Heroku? - java

I'm migrating my multi project Java webapp from Cloudbees to Heroku. I have one main webapp that depends on 3 other library projects that I have written (also Maven+Java). On Cloudbees this was simple, you just build everything through Jenkins, the JARs get poked into their Maven repos then the main webapp gets built taking its dependencies from that Maven repos.
However, I can't for the life of me find a way of doing this on Heroku without doing something horrendous like this:
https://devcenter.heroku.com/articles/local-maven-dependencies
By doing so it would mean that every time I changed a library I would have to remember to deploy the built JAR to the main webapp project and push this to Git, somewhat defeating the point of using Maven!
I understand that the way to deploy your webapp on Heroku is essentially by doing a git push to their repo, but how can I tell heroku at the other end to find my library dependencies without having to bundle them in the main webapp like this article suggests?
I would assume that there is some way to set up a private maven repos on your heroku account but I can't find anything like this.

I think the best solution is to use a private Maven repository, and then add the config for that repo in the settings.xml of your main project. This article on using a custom settings.xml describes how to do that.
There are some services that host private Maven repos for you, such as JFrog. But I've even read of people using Github to host a Maven repo, too.

Related

Android library to work with local maven repository

I have an Android app which uses a library of my own. I am developing them at the same time so when I have a change in my library I want to test it in my app as well.
They are setup as different projects since my library will also be used by other developers. The way we work is we build the library using a CI platform adn deploy it to an artifactory server.
Then from the app I reference this library directly through artifactory. This way when my CI platform builds the app, the build process takes the lib from artifactory and CI works smoothly.
This is a good way to work but is a pain in the ass when developing them in parallel, because I have to commit the changes, create a pull request, merge it with the development branch and wait for CI to build it and deploy it on the artifactory server, just so I can test it on the app.
Coming from java EE development, I used maven install, which deploys the artifact in the local maven repo, then I could already use it from my web application.
I want to do soemthing similar, i.e. have gradle deploy my artifact on my local repo, so the artifact on the local repo is updated but not on the remote one. This way I can debug more easily while still keeping the CI setup in place.
But I have no idea how to do this on gradle. The artifactory plugin seems like it only allows deployment on an artifactory server.
any ideas?
If you're using the maven plugin, you can run the install task to deploy the artifacts to your local Maven repo [1]. After you have the Artifacts deployed to your local maven repo, you need to add mavenLocal() [2] as one of the repositories to be able to resolve the dependency. One strategy I use is to always set a custom version for my local copy so that I can be certain that the local version is getting picked up - but if you choose not to do that the dependencies get resolved in the order the repositories are listed (so you'll need to ensure mavenLocal is before your Artifactory server).
[1] https://docs.gradle.org/current/userguide/maven_plugin.html, https://github.com/dcendents/android-maven-gradle-plugin
[2] https://discuss.gradle.org/t/how-to-use-maven-local-repository-for-gradle-build/2244

Gradle Local Repository to share jars easily?

So we a re considering Gradle instead of Maven. What I cant figure out is how to EASILY share built dependencies between completely seperate projects at a local level that will work anywhere.
So imagine I have 2 projects DBService and Middleware. Middleware depends on DBService but they are completely seperate (not sub projects nor multi modules etc...).
I make changes to the DBService and then in Maven I could have changes go to local Maven Repo (not global as i need to test them first) using:
mvn clean install
I then start coding on Middleware and import the changes by running the same command as normal (Nice!). The maven POM requires nothing special at all (besides standard ). No path to local directory containing the jar in a lib folder (nasty IMHO) or anything else. it just works (out of the box).
How can I achieve this very simple and very common scenario in Gradle. I know I can use a local Maven repo but this is this a first class citizen in Gradle? Does it not need special/ad-hoc, or even worse, environment specific setup (UGHH) in Gradle?.

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)

Always deploy staged site by default for multi-module site?

I'm struggling to understand the complexities of deploying a multi-module maven site that has working links. This is complicated by the fact that I'm deploying to Google Code using the maven-scm-provider-hg.
According to the docs, I'm supposed to run mvn site:site site:stage to get a full working site. However when I run mvn site:deploy it deploys the parent pom site which is empty except for the images and css folders.
Next I try mvn site:stage-deploy. This fails because it adds staging/ to the url, which since I'm using Google code causes an error because http://code.google.com/p/myproject.site/staging isn't a repository. This also isn't a long term solution since I'm pretty sure the maven release plugin runs site:site.
What is the official way to deploy a full multi-module site with working links?
In order to run the site build of a multi module build with everything ready you have to run the site lifecycle phase site-deploy and not just the site plugin goal.
So I would run
mvn clean install site-deploy
or for deploy of artifacts and site
mvn clean deploy site-deploy
And of course you have to have the setup correct in terms of distribution management. Besides that you want to ensure that all modules have the same directory name as their artifactId and you have set up site.xml with the respective links and so on as documented on the site plugin website.
Depending on the site deployment protocol you might also have to add a build extension (e.g. if you use dav)
It certainly takes a bit of fiddling but it works. Also I would recommend to use the latest version of the site plugin (3.1) and Maven (3.0.4).

Maven: running Unit-Tests remotely

We are currently working on a distributed Java EE-Application and have therefore a separated test and production system.
Compiling and Bundling is done via an Ant-Task. Now we want to deploy the Jar-Files of the different servers to the test-servers and run the JUnit Integration / Function-Tests there. If they succeed, then the current version should be deployed to the live-servers.
Plain Unit-Tests are executed by Hudson.
Is that possible with Maven and is there any information or best practice available?
Yes. Hudson has maven integration. Take a loot this wiki and this link.
You can set unit test case thresholds for your job to see if it does not pass a certain number of test cases. In that the deploy plugin will not get invoked and the app will not get deployed.
Take a JAR built from Ant and reuse it. I would add a Maven repository to your environment such as Artifactory, Archiva, or Nexus and deploy to that using Ivy. You almost certainly need to use a Maven repository to be happy with Maven for anything other than small scale personal projects. http://ant.apache.org/ivy/
Use Maven to grab the JAR from the Maven Repository. For this, just use a normal Maven dependency declaration.
Run Maven on the QA server, with the JUnit tests declared in that project. If that succeeds, deploy the JAR to the production server. For this, the details depend on the production server. If it's a WAR, I would use Cargo, but if it's a JAR it really depends on what's executing the JAR - you might need some sort of file copy, scp, etc. http://cargo.codehaus.org/
Hudson and TeamCity both have deployment features as well. You just set up a job to run (in this case the Maven job) and tell the CI server to deploy on success.

Categories