Deploy Java App on Heroku which depends on my own Maven artifacts - java

Heroku supports deployment of Java apps based on Maven
They also give advice for app deployment if a lib is needed that is not available in a public maven repository
But:
I have two Maven projects, where one depends on the other one. When I locally mvn install the dependent artifact I can mvn package the other one and everything works fine. However, I cannot push it to heroku, because heroku can't access my local mvn repo.
What can I do? Will it be necessary to setup a private maven repo accessible to heroku on the web (e.g. artifactory) or are there any other ways to deploy such an app with a custom dependency on heroku?
Thanks.

There is an alternate deployment path for Heroku called Anvil that might help here. With this path, you would build everything locally with any private libs you need and copy all dependencies into your target directory, and then use Anvil to build and release the whole thing to your Heroku app. By default, Anvil will detect your app as Java and try to build it again, but you can override this by specifiying the null buildpack, which tells it to take your files as is because you already did the build locally. This is probably better shown with an example:
Install Anvil:
heroku plugins:install https://github.com/ddollar/heroku-anvil
Clone this example app that already has copy-dependencies configured in its pom.xml. You would need to configure this in your own app:
git clone git://github.com/heroku/template-java-jaxrs.git
Go into the dir and build the app, which will run copy-dependencies. This is critical because you need all your dependencies in your app's target dir, not in ~/.m2/repository so Heroku will be able to find them:
mvn package
Create the Heroku app:
heroku create
Use Anvil to build with the null buildpack and release to the app:
heroku build -b https://github.com/ryandotsmith/null-buildpack.git -r

Take a look how we do it with a live open source web app: pom.xml. The app is deployed to Heroku using Maven and Ant. We automatically do git clone, then copy new files into the folder, and then do git commit && git push. What's important is that we use maven-invoker-plugin in order to download artifacts inside the Heroku slug.

You need a Maven repository. If your projects are on GitHub then you can use JitPack for this. It will build your code and publish a jar.
There are instructions and docs on the website. Basically add JitPack as a repository and then add your project as a dependency.

As of August 2018 I would recommend using Heroku Maven Plugin
It allows to build application locally and then push artefact to Heroku.
It solved my issues with local maven dependencies.
Sample configuration for Spring Boot app:
<build>
<plugins>
<plugin>
<groupId>com.heroku.sdk</groupId>
<artifactId>heroku-maven-plugin</artifactId>
<version>2.0.5</version>
<configuration>
<appName>${heroku.appName}</appName>
<processTypes>
<web>java -Dserver.port=$PORT $JAVA_OPTS -jar target/${project.build.finalName}.jar</web>
</processTypes>
</configuration>
</plugin>
</plugins>
</build>
If you are using Heroku CLI then ${heroku.appName} will be automatically resolved.

Related

Spring boot app deploy to appengine from azure dev ops

I can make the Azure ops pipeline but my question is I have checkedin my code into repository where we should not checkin the application property file.
That means on the deployment time i should have to download the application property file from some secure place and build my spring boot app before i deploy into app engine right.
So, what i did so far is, I downloaded my application property file into azure agent at run time. I passed the property file into maven build command but it did not work out. [Note: I already searched a lot read a lot of answers and applied as well but nothing worked]
Command line I used:
mvn -f myapp-springboot-api/pom.xml
-Dspring-boot.run.jvmArguments="-Dspring.config.location=file:/home/username/application.properties"
clean package appengine:deploy
I also tried with
mvn -f myapp-springboot-api/pom.xml
--spring.config.location=file:/home/username/application.properties
clean package appengine:deploy
This also did not workout.
Also, I tried passing the whole property file location via pom.xml
pom.xml changes:
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>1.1.1.RELEASE</spring-cloud.version>
<property.file.location>${property.file.location}</property.file.location>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-1</version>
<configuration>
<files>
<file>${property.file.location}</file>
</files>
</configuration>
</plugins>
</build>
Than I tried to build with:
mvn -f myapp-springboot-api/pom.xml
-Dproperty.file.location="/home/username/application.properties" clean package appengine:deploy
Than also I was not able to load the define external property file.
Thanks in advance, please help your help is highly appreciated.
The commands you are using won't actually pass the external properties files to the application engine (As it exists on a different server) and would only be scoped to the running maven process that is packaging + deploying.
So if you have copied your property file onto the external agent before building I would just replace the default one you have checked into source control.
So your build steps would be for example:
Download property file
Overlay:
mv /home/username/application.properties myapp-springboot-api/src/main/resources/application.properties
Build + Deploy
mvn -f myapp-springboot-api/pom.xml clean package appengine:deploy
So now your compiled and deployed jar file would include your new properties file, an alternative that recently came out would be to use something like Azure App Configuration.
If you want to not have to do another command you could also use the Maven Resources Plugin to perform the copy for you.

Deploying Java EE Web App to Wildfly/JBoss EAP

More of a "what's best practice?" kind of question.
We have a number of Java EE web applications currently deployed manually through the web interface to JBoss EAP 7.0 application servers. I'm looking at automating these and have a simple Jenkins build which will deploy to our UAT environment using Jenkins promoted build plugins and the Wildfly maven plugin.
Whilst this is ok, we clearly have a defined "build" and "deploy" setup which i want to refine. My issue however is that when we run the "wildfly:deploy" goal, it's runs the maven install section of the build!
Essentially, deploying to different environments rebuilds the app, therefore we can't guarantee byte-for-byte parity with the build that was tested.
Is there a best practice way of deploying a built final release through environments using Jenkins/Maven onto JBoss EAP/Wildfly?
Thanks all!
I'm not sure why you need to deploy with Maven. Why not use the jboss-cli tool? With that you can do something like:
jboss-cli.sh --connect --command="deploy target/your.war --force"
This is the "localhost" version and it assumes you haven't created any users for Wildfly but it gives you an idea of what you can do. The CLI Docs get into different ways to deploy applications and expands greatly on the security aspect.
Jenkins can run a shell or batch script about as easily as it can run a maven build so this shouldn't be too difficult to implement in Jenkins.
Well in development workflow it is perfectly ok to deploy with maven, it saves time and context switching.
You can create a dedicated maven profile for deployment - this way you have the flexibility, either use maven just for build and deploy however you want, or run maven with your deploy profile, and let it do build+deploy.
Head over to Wildfly maven plugin for more info. It can do many tasks apart from deployment, including configuration tasks via jboss cli, but for the sake of deployment, this is all you need:
<profile
<id>jboss-deploy</id>
<build>
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.2.1.Final</version>
</plugin>
</plugins>
</build>
</profile>
Now you can simply run mvn clean package -Pjboss-deploy and maven will compile and package your app, and then deploy the resulting war or ear to your running JBoss/Wildfly instance. You can also invoke the deployment manually via mvn wildfly:deploy
Have fun.

How to add java library without no repository to pom file?

I'd like to add one project A as my dependency, but unfortunately, there's no repository host this library. I know that I can install it to local repository manually, then refer this in pom file. But I have a travis build job where there's no such artifact, is there any way that I can install this library to local repo automatically ? Thanks
I would recommend to use the clean approach and uploading this library into your own repository. If you don't have one: time to get one running.
If you're really not up to this task the maven install plugin: http://maven.apache.org/plugins/maven-install-plugin/install-file-mojo.html can install a jar in the local repository. This will work both locally and on a CI server.
To upload a jar in a remote repository there is the deploy plugin: http://maven.apache.org/plugins/maven-deploy-plugin/deploy-file-mojo.html
If you bind the execution of this plugin to a very early phase in the maven life-cycle (validate) you might be able to avoid a build step required prior of your own build.

Quickest POM settings to turn an existing Eclipse web project in a Maven-managed project?

I'm converting an existing Eclipse-based web project to a Maven-managed one.
Since the project has lots of dependencies, many of which are custom (they're either internally made or they've been taken from sources that have no public repository), is there some 'magic' Maven POM setting that will let me load every jar from WebContent/WEB-INF/lib and make the project work as before right now, so that I can configure each dependency and do the necessary refactoring to turn it to a proper Maven project with a little more time and care?
I have already seen this question, but the project must continue to compile inside Eclipse, so - or at least I guess - it is not just a matter of using the Maven war plugin
What you want to do is called "installing" your non-mavenized JARs into your maven repository. This can be a local or remote repo that you host.
The command to install to your local repo is something like this: mvn install:install-file -Dfile=My-lib.jar -DgroupId=com.mycompany -DartifactId=My-lib -Dversion=1.2.3 -Dpackaging=jar
You'll want to review the various options for install to suit your project.
Once the non-mavenized dependencies are installed to your repo you can add them to your pom like any other maven dependency. They will be fetched from your local repo.
You will have to set up your own remote repo (like Artifactory) or install each plugin for every developer and CI server in your environment for others on your team to build the project. I strongly reccomend Artifactory, it makes it easy on your and your team to use maven and get dependencies.

Travis CI not using extra Maven repository provided in pom.xml

I have a Java-based GitHub project, fitnessjiffy-spring (I'm currently focused on the "bootstrap" branch). It depends on a library built from another GitHib project, fitnessjiff-etl. I am trying to configure both of these to be built by Travis CI.
Unfortunately, Travis is not as sophisticated as Jenkins or Hudson in dealing with Maven-based Java projects. Jenkins can easily handle dependencies between projects, but the same concept doesn't seem to exist with Travis. If one project depends on another, then that other project must already be built previously... and its artifact uploaded to some Maven repo where the first project can download it later.
My "fitnessjiffy-etl" library is building and deploying just fine. I'm using Bintray for Maven repository hosting, and you can clearly see my artifacts over plain HTTP at:
http://dl.bintray.com/steve-perkins/maven/
In my "fitnessjiffy-spring" project, I am adding this Maven repo location directly in the pom.xml, so that Travis will be able to find that artifact dependency. Here is the state of my POM at the time of this writing. Note the <repositories> element at the bottom of the file.
When I build this project locally, it works just fine. I can see it downloading the Maven artifact from "http://dl.bintray.com/...". However, when I try to build on Travis CI it fails every time. I can see in the console log that Travis is still trying to download the artifact from Maven Central rather than my specified repo.
Does this make sense to anyone else? Why does Maven utilize a custom repository location in a POM file when building locally, but ignores this configuration when running on a Travis CI build?
From digging into this further, I discovered that Travis uses its own proxy for Maven Central, and has configured Maven to force ALL dependency requests through their proxy. In other words, it does not seem possible at this time to use additional Maven repos specified in the POM file of a project built on Travis.
In my case, I ended up refactoring such that project would not need the outside JAR dependency. I also switched to Drone.io, so I could manage my settings on the build server rather than having to carry a YAML file in my repository (which always struck me as a bit daft).
However, even on Drone it's still a major hassle to manage dependencies between multiple projects (extremely common with Java development). For Java, I just don't think there's currently an adequate substitute for Jenkins or Hudson, maybe running on a cheap Digital Ocean droplet or some other VPS provider instance.
In your install phase add a $HOME/.m2/settings.xml define your custom repository.
cache:
directories:
- "$HOME/.m2"
install:
- curl -o $HOME/.m2/settings.xml
https://raw.githubusercontent.com/trajano/trajano/master/src/site/resources/settings.xml
- mvn dependency:go-offline
script:
- mvn clean install site

Categories

Resources