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.
Related
I started a project as a maven-quickstart and added JUNIT5.
There was no 'resources' folder anywhere. It builds using a pom.xml and up to "package" goal.
Some time after, one of the testers wanted to add a test that reads from a CSV file.
He had some trouble setting up and I recalled from just memory that it will look in test/resources.
We are all fine now but I just can't stop wondering: Is 'test/resources' hard-coded into JUnit? Or is it somehow derived from the project archetype?
Is there a way to edit this reference in the project settings, vm settings or maybe in the very test method?
From https://junit.org/junit5/docs/5.3.0/api/org/junit/jupiter/params/provider/CsvFileSource.html
used to load comma-separated value (CSV) files from one or more classpath resources.
The way to load resources with this annotation (if they are not on the classpath) is to put them on the classpath.
So, to answer your question - yes you can change this setting by changing the classpath.
How you do that depends on what you are using to build, e.g.:
For java, you use java -cp ..., maven, gradle, ant all have different ways and since you have not posted a specific question we can't give a specific answer.
EDIT - Since you're using Maven - create a src/test/resources (or src/main/resources) and unless you're overriding the defaults Maven will automatically make those part of the test classpath (and classpath, respictively). Put your file in src/test/resources and it should work.
I'm using Springboot and would like to replace the property values in the org.apache.catalina.util ServerInfo.properties file when building the project. The file is buried in a dependent jar: tomcat-embed-core-8.5.2.3.jar. So my app jar will have the replaced values but the tomcat-embed-core-8.5.2.3.jar in the repos will remain as is.
I looked at Maven filters but that looks like it only works if the property file is reachable within my project only (like in src/main/resources), not if the file is in another jar. Is that right?
What's the best way to do this? A Maven solution or something simpler is okay.
Please help me with evaluation whether maven could be used for a problem I am faced with. Hopefully you can give me some hints on maven or suggest using a different tool.
Problem:
We have a template archive containing resources. We need to create a new archive based on the template using custom files/data.
some files from the template have to be replaced with custom ones.
some files have to be processed and placeholders in these files have to be replaced with custom variables. (i.e ${filename} -> "my_file_name.txt")
The pom file should describe which files should be replaced and where custom files should be taken from. Also it should describe which files to be processed by place-holder processor and where to get the variables values.
It is possible to write a java program to do all these stuffs, but Java code must be changed again and again for a different set of custom files and new placeholders. Hopefully with help of maven (also custom plugins if required) this task could be a simple configuration task.
Example:
Template folder:
/src/main/resources/file1.xml
/src/main/resources/file2.xml
/META-INF/MANIFEST.MF
file2.xml:
<file>${file_name}</file>
Custom folder:
/src/main/resources/file1.xml
/src/main/resources2/file3.xml
Custom Property File:
file_name=my_file_name.xml
Result:
/src/main/resources/file1.xml
/src/main/resources/file2.xml
/src/main/resources2/file3.xml
/META-INF/MANIFEST.MF
file2.xml:
<file>my_file_name.xml</file>
Questions:
How to put the unmodified MANIFEST.MF into target folder.
I tried to use
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifestFile>src/main/resources/template/META-INF/MANIFEST.MF</manifestFile>
</archive>
but it simply disables 'maven' part of the META-INF. The manifiest.mf was still generated by maven
How to implement placeholder/variable processor?
How to zip the resulting set of files into .zip file?
How to invoke a maven build from a java class?
Is there an alternative tool which might be more suitable for my task?
regards,
ilia
That's a lot of questions, but I'll try to answer:
Move the META-INF/MANIFEST.MF to /src/main/resources/
It is already implemented on http://maven.apache.org/plugins/maven-resources-plugin/ for replacing properties on resources files with ${propertyName}
Zips can be created with http://maven.apache.org/plugins/maven-assembly-plugin/
Don't do that, Maven is invoked from command line, IDE or continuous integration server.
On tool would be Gradle, or the older Ant for naming some of them.
I have a java project and i need to create jar file from my project . any body can tell me what is the simplest way to make this?
The basic format of the command for creating a JAR file is:
jar cf jar-file input-file(s)
The options and arguments used in this command are:
The c option indicates that you want to create a JAR file.
The f option indicates that you want the output to go to a file
rather than to stdout.
jar-file is the name that you want the resulting JAR file to have.
You can use any filename for a JAR file. By convention, JAR filenames
are given a .jar extension, though this is not required.
The input-file(s) argument is a space-separated list of one or more
files that you want to include in your JAR file. The input-file(s)
argument can contain the wildcard * symbol. If any of the
"input-files" are directories, the contents of those directories are
added to the JAR archive recursively.
The c and f options can appear in either order, but there must not be
any space between them.
From scratch.. with CMD
The command line is what almost every other application will use to build your JAR file. They just wrap it up a little nicer for you. In truth, it's very simple to do yourself. Obviously Java have explained this way in detail so there is no sense in me repeating it.
Note: You need to have your JDK/bin directoy appended onto your %PATH% system variable to be able to use this method.
Double Note: As pointed out in the comments, I'd suggest you keep trying this method until you understand it. It is very important that you get these things at a low level, so if something goes wrong with the IDE, you have a much better understanding of how to solve it.
Eclipse
Eclipse offers a nice interface for it. You can find a step by step tutorial here. The long and short of it is..
Right click on Project -> Export -> JAR File -> Select the Java files to include
When you've done this, hit finish and you're golden. The tutorial also adds some additional tips in to make it as seamless as possible.
IntelliJ IDEA
My personal favourite IDE. This question offers a nice explanation for how to export as a JAR file. Again, the long and short of it..
File -> Project Structure -> Artifacts
In there, you can then create a new artifact by clicking the + icon. This will give you an option for the file type, which is .JAR and which modules you want to include in your artifact. When you're done, you go to..
Build -> Build Artifacts
And it will create the JAR file from your project.
Using Maven
I've often found this to be a pretty awesome tool, and definitely one worth considering. In IntelliJ, by double clicking the install procedure in the life cycles..
This will create a new JAR file in your .target directory.
Note: Some IDEs (like IntelliJ) will hide the .target directory by default. Make sure you make it visible in the project settings.
A JAR file is nothing but a ZIP file with added meta-information for the Java Runtime Environment. So the easiest way is to actually zip your classes files including that META-INF folder by hand, then rename the file to JAR. How you get your classes files however is a different story.
The easiest practical way is to hit the build button in your IDE, which will then compile your code into class files, create an appropriate set of meta information and then conveniently zips the whole thing into a JAR file.
Asking for a maven solution, you would need to specify a single pom.xml in your project
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>you.specify.something.preferably.a.domain.name</groupId>
<artifactId>name-of-project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
</project>
And with this you can do a
mvn package
To build the project. However, it relies on a lot of defaults, you would probably want to differ.
To build a jar file from a module
On the main menu, choose Build | Build Artifact.
From the drop-down list, select the desired artifact of the type JAR.
see this
I use maven-assembly plugin to create a zip file for a release in my target folder. This package with dynamic name includes a configuration file;
/target/dailyrelease-4234.zip/cd/lib/conf/wrapper.conf
Now I also use maven-dependency plugin's build-classpath goal to output the dependencies as a string.
I want to write this output string to the configuration file created by the assembly plugin
I have 2 problems:
1- How can I access this conf file in the dynamic named zip?
2- I want to add some extra .jar paths to that string created by maven dependency plugin, but it only copies the names from local repository. is there a way to modify this output, or show dependency plugin to use another folder to pick the jar names and not from local repository?
Or even better make the creating dependency names task as a part of assembly-plugin so I dont need to access and modify that zip anymore.
1 - It sounds like your mechanism for dynamically generating that number '4234' exists outside of Maven, and you're trying to figure out how to access that number from within Maven, correct?
If so, I suggest using the buildnumber-maven-plugin which generates a number which you can then access from within Maven via the ${buildNumber} property.
2 - I suggest switching your callout from dependency:build-classpath to dependency:list -DoutputFile=xyz.txt. The latter gives you a cleaner output of just groupId/artifactId/version which should be easy to edit.
Or better yet... Do the above, and simply use <phase> configuration to ensure dependency:list gets called before the assembly plugin runs (typically at the end of package phase), and ensure the resulting output file sits somewhere that the assembly plugin will pick it up.
Hope that helps.