Replace properties in jar - java

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.

Related

JUnit5: Where is the root of #CsvFileSource defined and can that definition be changed to refer to a different directory?

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.

Setting properties in maven JAR when building

I have a regular Maven project. I would like to set certain properties/variables in the JAR when building using mvn package, so that certain information can be picked up from individual JAR files.
For example, I could use:
mvn package -DbuildId=200
... and I would like to see this information stored (buildId = 200) stored in some file generated by maven. I know for a fact that certain properties are stored by Maven at build-time (for example, the files in META-INF/maven).
Is this possible without modification of the POM file, and without adding extra plugins? If so, what arguments do I need to pass?

Handling duplicate entries in shaded (uber/fat) jar file

I created a jar file, created from multiple jars (I used Gradle Shadow plugin in this case).
It turned out that the file contains duplicate files in /META-INF. Most of them are multiple license.txt from the original jar files, but some of them are Spring factories, which I'm interested in.
This behaviour seems common when using various fatjar-like tools with Maven or Gradle, and it looks like it is not prohibited by any means.
I've checked that java.lang.ClassLoader#getResources will return these entries as a list of the same URLs, eg.:
jar:file:/C:/temp/myJar.jar!/META-INF/spring.factories
jar:file:/C:/temp/myJar.jar!/META-INF/spring.factories
so once I get the URL, there's no way back to getting the contents of all duplicated files, programmatically.
Can Java process such duplicate files, somehow?
Or, maybe more general, is it a valid and supported situation, from specs' point of view, to have a jar with duplicate files inside? I've checked Jar File Specification and it didn't give me a clue, either.
In maven-shade-plugin this is done with an AppendingTransformer.
My interpretation of the gradle plugin documentation you are using is that this is done this way:
shadowJar {
append('META-INF/spring.factories')
}

Maven dependency plugin problems

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.

Creating a Jar File Containing Another Jar File

I've created an Android project that does some very simple network stuff. This project is standalone, and I've successfully exported it as a jar file and imported it into other projects I've worked on. When exporting this project, I am ONLY exporting the class files that are used for the project. (No system files: ie. Manifest, etc)
I want to leave this project as standalone since it is used in other projects and will be used more in the future.
However, we have other projects that need the features of the network jar and some other features. What I would like to do is create a new project, import the network jar file. Create wrappers for all the functions in the network jar file, then add more functionality.
Afterwards I want to package this project up as a jar file, so that I can use it solely for projects that require that extra functionality.
Having this project as a jar is important, because this component might be given to other people to use, and easy/simple integration is required.
This seamed like it should be pretty straight forward to me. But I am getting noClassDef errors and Verify errors.
I even stripped the project down to a single function that returns a static String from the original network jar and passed that through and still got a "could not find method xxxx referenced from method xxxx" log and then a unable to resolve static method warning, then a No ClassDefFoundError. Here's the logcat.
What is the proper way to do this?
Thanks!
Jar files that want to use embedded jars must define a custom class loader, like JarClassLoader.
If you want to use a single jar file you also have options like OneJar, JarJar, and ProGuard.

Categories