Building a non-uberjar Docker image with leiningen - docker

I have a clojure project that depends on a Java library, that does not work, when it gets included in an uberjar. (It needs different XML descriptors using the same filename in different JAR files.)
Everything I find on using Docker with leiningen depends on building and packaging a uberjar. That's also how I built all clojure Docker images so far.
Is there any leiningen plugin out there, that understands to package a Docker image using several jar files like io.fabric8/docker-maven-plugin does?

Whenever packaging (uberjar, war) the big file that is created contains .class files and a directory structure. Where are these XML files supposed to be (class)loaded from? You can experiment with packing manually. After all it (whether uberjar, war or jar) is just a zip file.
When you know exactly the layout you need SBT is flexible enough to insure you can package from the many input jar files. Unfortunately lein plugins will do things like always overwrite duplicates, and you can't control the packaging behaviour. I can't remember exactly the inflexibilities, but I couldn't control how the packaging process went, what decisions were made.
For doing it manually I use a Linux something called Archive Manager, which I found to be much better than what I used when on Windows. Doing it manually may be all you need. The downside of SBT of course being that you have to learn it, which includes a bit of Scala.
It needs different XML descriptors using the same filename in different JAR files.
Just thinking about this, is it that you need to append the contents of each file that is in a different jar into the one file that is in the uberjar? You can try it out. If it works and you need to package up often enough that manually creating and renaming a zip file every time becomes a pain, then I believe that SBT will be your best bet.
I have to package my container with the original jar file and then reference this jar in the classpath when starting the application
The classloader loads classes rather than jars. It is the container's job to unpackage all the things you give it, such as .class files, (uber)jars, wars. Any program that dynamically loads from the classpath is loading either classes or resources (things like .xml files). I suppose a .jar file could be a resource, in which case you would put the jar file in the uberjar. So it is still possible to package it up.

Related

How can I tell Which bazel aspect outputs are still relevant

As part of our efforts to create a bazel-maven transition interop tool (that creates maven sized jars from more granular sized bazel jars),
we have written an aspect that runs on bazel build of the entire bazel repo and writes important information to txt files outputs (e.g.: jar file paths, compile deps targets and runtime deps targets, etc.)
We ran across an issue where the repo's code was changed such that some of the txt file were not written anymore. But the old txt file from previous runs (before the code change) remained!
Is there a way to know that these txt files are no longer relevant?
You should be able to run with --build_event_json_file=file.json and try to locate generated artifacts. For example we use it on ci.bazel.io to locate actual test.xml file that were generated: https://github.com/bazelbuild/continuous-integration/blob/09975cbb487a84a62ca1e43aa43e7c6fe078f058/jenkins/lib/src/build/bazel/ci/BazelUtils.groovy#L218
The definition of the protocol can be found in build_event_stream.proto

Publishing GulpJs minified/concatenated javascript via MSDeploy and Teamcity

Apologies if this question has been asked before. I have found variants on this theme but nothing that seems to fit our particular configuration.
We have developed a custom GulpJS task which parses a .json file located inside our folder assets/javascript. This json file contains an array of relative paths to javascript files (both our own and library) in a specific order for minification. They are then outputted to the folder assets/javascript/build and concatenated. The javascript source files are in the project but the minified and concatenated versions of the scripts, in fact the entire build folder itself, are not included in the Visual Studio project.
Ideally, I would like to have a step in the MSDeploy configuration which would copy all the files in the javascript build folder to the destination. Otherwise I could potentially include another step in Teamcity to do so.
Has anyone successfully instituted a similar build configuration and could share some insight? I tried using the MSBuild copy task but that didn't seem to copy the files to the output location. One option that I am considering is including the minified scripts in the project file but this might potentially trip up other developers who don't have Gulp running in their development environments (hilarious as that might be)

Create war without manifest

I need to create a war file through ant build without a manifest file. I want the war to me created without the manifest file.
I am using tag in build.xml to create the war.
you can use <zip/> task with .war extension for destfile attribute to achieve the same result as the <war/> task (without manifest.mf).
<zip destfile="..\...\WarFile.war"basedir="..\basedir" update="true"/>
in case WarFile.war already exists, although you've written I need to create a war file , the attribute update="true" will be of use (by only updating and not overwriting the file).
All a war file is is a zip file in a specific format. That is libraries go in a particular place, class files go elsewhere, etc. The <war> task has sub-entities like <classes/> and <lib> that make configuring a war file correctly without knowing exactly where everything has to go.
However, you can correctly format the war yourself, and use <zip/>.
Why don't you want a manifest file? A manifest, if you don't specify anything, will contain nothing but the Java version used for the build, and the Ant version and won't affect the execution of your war at all.
What you can do is put useful information into the manifest. For example, we use Jenkins for our builds, and we put in the Jenkins project name and the build number which helps us understand what was included in the war.
There's no reason not to use a manifest file. And, a manifest file can contain useful information (which is accessible to the Java program too).

Blackberry 5.0 - Add reference to a Java Library Project

It seems to me that what I'm trying to achieve is incredibly simple, yet is becoming incredibly painful.
I have ProjectA which is a BlackBerry Application project. I have ProjectB which is a Java library project. I want to refer to ProjectB from ProjectA. I can add a reference but when I run ProjectA, it doesn't work. I have source code for both the projects and both are compiled using Java compiler 1.4
I have tried multiple things but everything fails for some reason:
1. pre-verify.exe on ProjectB
It fails with an error "JAR file creation failed with error -1" I can see that the cod and jar files have been created but when add the jar file to ProjectA and run it, it doesn't work. Not sure if I need to add the .cod file.
2. Create new BlackBerry Library Project and reference it in ProjectA
I create a new project ProjectC and then add the jar of ProjectB to it. Then I add a reference to ProjectC in ProjectA. But I cant import classes from ProjectB
Pls suggest a way out.
I'm using Eclipse Plug-in and relying on Eclipse's build capabilities
Figured out answer myself. Publishing here in case someone stumbles upon this. Here are the steps:
Create your library and export as JAR (or download the 3rd party JAR)
Run preverify.exe on the JAR
preverify.exe -verbose -classpath "C:/Program Files/Research In Motion/BlackBerry JDE 5.0.0/lib/net_rim_api.jar" jarname.jar
If you are lucky, you won't run into any issues and you will be done. But I wasn't lucky enough. I got the below error
Error: No such file or directory. JAR file creation failed with error -1
There are two possible causes of this:
jar.exe is not added to your PATH. If so, add it (found in your JAVA
installation directory) to PATH
cvfm or -cfm option on jar.exe fails to execute. I'm not aware of the reason but the way to fix this is to use -cf option, point to the .class files but don't use the manifest file. here is an
example:
"C:\Program Files\Java\jdk1.6.0_26\bin\jar.exe" -cf "output\json-1.0.jar" tmp12996/
tmp12996 contains the preverified .class files.
You may run into different issues other than the one I've listed above.
Once jar is created from above step, make sure that it's structure is as you anticipate. One way to check is to rename the .jar to .zip, unzip it and then check it. If it is not as you need, you can change the structure and then repack it (I wouldn't do any major changes though)
Then add this newly built jar to your BlackBerry application as a reference i.e. add to Java Build Path in your eclipse and Check it in Order and Export window.
That's it! You are good to go! Run you app!
You may face error indicating that the module contains verification errors when you try to run in the simulator. One possible cause of this issue is that your library (the original JAR) contains APIs that are not compatible with J2ME or BB JRE. You may not get a compiler error when you build your library independently as it is compiled against Java 1.4 (or whatever your version is). Best to figure the issue out is to move all your code into your BB App project and then build it. That will tell you all the issues upfront. You make the changes as required and then move the code back to the library. If you don't have source code for the library you are using (like a 3rd party library), you may be out of luck! Also remember that there could be other issues than what I've hit upon and solved.
I'm documenting this at length as it has taken an awful amount of time for me to figure all this out; and to say the least, was most frustrating!
I found another solution. If you get error -1 while preverifying your JAR file, just run your library application once. Because if you don't run the application, the deliverables folder will be empty. Make sure this folder is not empty.

Cleanup Antscript

Are there any tools available that allow the cleanup of a ant script?
I especially need to remove unecessary jar files... The Ant script I have to clean has more than 500 entries and has grown uncrontrolled over time.
There's no automated way of cleaning up jar files. You can look at the various include statements in your Java code, but they merely mention classes to include and not the jar themselves. Even if you can determine that a particular class is served by jarA.jar, it could be that jarA.jar is dependent upon jarB.jar.
You can even start removing jar files one at a time to see what breaks your build. That can be somewhat automated, especially if you specify your classpath via fileset instead of each specific jar. However, what if you actually need a jar for runtime, and not for the build?
My suggestion is to use Ant with Ivy. Ivy gives you the same Maven jar dependency capabilities without converting your project to Maven.
Take a look at Ivy and see how it works with Ant. Then, if possible, ask your developers to determine exactly what jars they need and what versions of those jars they need. You will have to help them. You might have to go through the jars in your repository and attempt to figure out what versions of the jars are in your repository.
You don't have to worry about jars that other jars depend upon. Ivy will take care of that for you. What you simply need are the jars that your developers depend upon, and they should know because they're the ones who use the include statements in their programs to specify a particular dependency.
Once you've determined the primary jars (and revisions) you need, you can easily convert your build.xml files to take advantage of Ivy's jar dependency system. Once you've done that, you can remove all the jars from your source repository since Ant with Ivy will download the required ones from the Internet based Maven repository system.

Resources