I have a node app which contains a node plugin that references a jar file. My question is this -
Is there a specific example of a heroku multi buildpack which loads all three -
...nginx.git
...java.git
...nodejs.git
In my root I have the following:
.buildpacks
.nginx
system.properties
package.json
Also, if this is a native nodejs app that is dependant upon a plugin which refrences a jar file and hence need to load the java environment, is it necessary that I also include a POM.XML file in my application's root?
Instead of the Java buildpack, use the jvm-common buildpack. This way, you won't need a pom.xml. You can put this line in your .buildpacks file:
https://github.com/heroku/heroku-buildpack-jvm-common
Or set it with the heroku buildpacks command.
Related
The documented way to add Azure Monitor OpenTelemetry to Java application is by downloading applicationinsights-agent-3.2.11.jar and using the following:
-javaagent:path/to/applicationinsights-agent-3.2.11.jar.
So in Spring Boot, the way it could possibly be run:
java -javaagent:path/to/applicationinsights-agent-3.2.11.jar -jar <jar-file.jar>.
But what happens if this path varies?
The problem is depending on the system it is running, and using maven (pom.xml) to get the artifact, how do we enable opentelemetry with applicationinsights-agent-3.2.11.jar since the location Maven stores the artifact changes from user accounts and computer?
Additionally, how do I specify a relative path to applicationinsights.json file for configuration (as Azure looks for this file inside the applicationinsights-agent-3.2.11.jar directory)?
If you specify a relative path, it will be resolved relative to the
directory where applicationinsights-agent-3.2.11.jar is located.
UPDATE
Regarding suggestions, How to define a relative path in java and this other suggested question
I am not looking to read files from relative paths.
The spring boot application needs to be invoked with a specific argument where it needs to be made aware of the location where maven downloads the the appinsights jar file.
Then when the app starts, the appinsights autoconfigure based on applicationinsights.json file, which once again, may vary by location.
Note that the latest applicationinsights-agent*.jar is available through GitHub and not through Maven repository. Therefore, I don't think that it can be downloaded as dependency to the project using the pom.xml
Now, the question here is not specific to ApplicationInsights agent, but for any java agent used for monitoring. The -javaagent parameter is supplied to JVM (java commandline) along with the path. Therefore, it will have to be supplied when JVM starts. How it is being setup would depend on the Server (or the standalone application) being used and its starting mechanism. One such solution is discussed here: How to attach a java agent on to a running spring-boot application. As there are many ways that the application can be deployed/run, the relative path would vary based on it.
If you are running standlone springboot application, you may also modify the mvnw or mvnw.cmd scripts to include %MAVEN_OPTS% with the -javaagent=agent path, where path could be relative to one of the variables defined in it, like %MAVEN_PROJECTBASEDIR%
Regarding the applicationinsights.json file, you can either have it in the same directory as the agent jar, OR set up environment variables to get the settings from there (instead of having the json file). You may refer to this link for details on available Environment variables to configure the agent. These environment variables can be set based on how/where the application is being deployed/run before the JVM initializes to make it available to javaagent.
I am trying to create a docker image from within maven which includes artifacts from a different maven project. But the examples I have copied do not appear to be working.
I think the problem here is I do not really understand how assemblies work and so am asking for help on what I want to do here. I have set up a contrived simple example of what I am trying to do here:
https://github.com/sodved/java-docker-demo/tree/0.0.1-0
pom.xml
sod-java/pom.xml
sod-java/src/main/java/sodved/Sod.java
sod-docker/pom-depency.xml
sod-docker/pom.xml
sod-docker/src/main/docker/setup.sh
sod-docker/src/main/docker/Dockerfile
sod-docker/src/main/docker/run.sh
So my project has two modules:
sod-java which builds an executable jar (which just writes a file to /tmp/sod.txt)
sod-docker which creates a java alpine image with Dockerfile
setup.sh is run when building the image. It runs the java to create the /tmp/sod.txt
run.sh is the default command writes the content of the /tmp/sod.txt file
I have tried two approaches to the inline <assembly> so far:
https://github.com/sodved/java-docker-demo/blob/0.0.1-0/sod-docker/pom-depency.xml Was my first attempt. Using dependecySet in the assembly. But I noted that the dependency was not even included in the /target folder (I assume because there is no actual java code to compile in sod-docker, so the dependencies were not copied).
https://github.com/sodved/java-docker-demo/blob/0.0.1-0/sod-docker/pom.xml Was my second attempt. It first explicitly copied the artifact into /target folder (which worked). Then used file in the assembly to try and copy the file.
In both cases I do not see the jar file copied anywhere by the assembly or in the tar file which the docker plugin creates and so I get an error when attempting to reference the jar in a Dockerfile COPY command.
I know the example is a bit contrived. But its simple and fitting with the standard way we do things at work. So I do not have a lot of flexibility in respect to tools, layouts etc.
The real case is used to build database images. Get base image, run java code to manipulate database, save as new image to be used downstream.
TLDR:
How can I specify a groupId, artifactId, version and have the corresponding artifact included in my docker image. The docker source itself contains no java.
OK, have figured it out.
The issue was that the pom.xml specified some external configuration
<external>
<type>properties</type>
<prefix>docker</prefix>
<mode>override</mode>
</external>
But as the doco here (http://dmp.fabric8.io/#property-configuration) says, this means the <build> configuration (including my assembly) in the pom.xml will be ignored. I am not sure why our standard uses the external configuration, will chase up our ops people on that. But removing this <external> section and everything works.
I can't open my app in Heroku - I get error H10. When I run my app in Eclipse or use executable jar file - everything work well. Here is my code : GITHub Below is my log file:
DropBox
You app is running on port 8080, but on Heroku it needs to bind to the environment variable $PORT. You can fix Spring to do this by adding the following to your application.properties:
server.port=${PORT:8080}
This will use $PORT if it's set, and default to 8080 if it's not.
I solved this error using Procfile, the Procfile is always a simple text file that is named Procfile without a file extension, For example, Procfile.txt is not valid, The Procfile must live in your app’s root directory. It does not function if placed anywhere else.
What to write in Procfile?
web: java -jar build/libs/your-project-name-version.jar
the version you can find inside build.gradle/pom.xml
Example:- web: java -jar build/libs/khatabook-1.0.jar
Where to create Procfile?
I have given my project structure image link for
[1]: https://i.stack.imgur.com/tsB35.png
My gradle file link
https://github.com/himanshujainpro/khatabook/blob/master/build.gradle
My application.properties
https://github.com/himanshujainpro/khatabook/blob/master/src/main/resources/application.properties
Project link for further reference
https://github.com/himanshujainpro/khatabook
Have a Spring Boot (1.5.4.RELEASE) based microservice which I deploy a jar to an AWS EC Instance (Linux environment). Now, I am also deploying an external log4j.properties file so I have to start the microservice like this:
java -jar myapp.jar -Dlogging.config=/path/to/log4j.properties
How can I configure this Spring Boot Microservice as a Linux service where I can start and stop it using these flags:
sudo service myapp start | stop | status | restart
Thank you very much.
Using a symbolic link to your springboot app you can make it controllable as service...
sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
Placing an application.properties into your myapp folder you can override the one bundled inside your app. This way you don't need to use command line switches. Simply specify the path to your log configuration as value to property key logging.config inside of it.
NOTE, though, that this solution is not really best practice. Once you're running a whole bunch of services in production, you probably rather want to go for something along the lines of spring cloud config for externalizing configuration and you probably also want your logs aggregated at a centralized service that allows for an overview of all your services' logs in one place.
As per spring-boot deployment,
A fully executable jar can be executed like any other executable binary or it can be registered with init.d or systemd
Make sure you build your app using the plug-in below (gradle version in shared link):
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
and as shown by Jörg, create a symbolic link inside init.d:
sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
That is the simplified version :)
More to your question, you need to customize the init and this can be done by a conf file - all specified in the documentation.
With the exception of JARFILE and APP_NAME, the settings can be
configured using a .conf file. The file is expected next to the jar
file and have the same name but suffixed with .conf rather than .jar.
For example, a jar named /var/myapp/myapp.jar will use the
configuration file named /var/myapp/myapp.conf.
such as:
myapp.conf
JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/custom/log/folder
Is there a way to include environment specific properties or configuration file while building war.
QA
entity.url=http://qa.test..
prod
entity.url=http://prod...
I need to make around 5 to 6 REST calls. Url is different for each environment. Hence is there any way to configure environment specific conf file?
thanks in advance
The Play Framework has the concept of 'ids' that can be used for different modes see here:
http://www.playframework.org/documentation/1.2.4/ids
This allows you to do:
%qa.entity.url=http://qa.test..
%prod.entity.url=http://qa.test..
The one thing that might not be clear by their documentation is how to set this in a war. When running as a .war file, the play ID is set to 'war' by default. This can be changed in the web.xml of the .war file. You can do that or you can specify the ID when you create the war:
play war -o PATH --%prod
Not that I am aware of (and reading the python source for building the war does not indicate this is available). The war file simply builds up your Play application, as is. If you want to have a different configuration, then this may simply require the loading of it from an external resource (a property file that lives outside of the WAR, that you ship with your WAR file).
Alternatively, you could modify the python script that builds the WAR file to custom add additional properties to your file. Look in the directory framework/pym/commands/ and look at the war.py to read the source for the python war command.