How to determine if a jar is an uber-jar? - jar

Once we get a jar, how do we determine whether it is a normal jar or an uber-jar?
Is there an automated way to tell, other than by looking at them one by one?

Related

how to set Bazel --warn_duplicate_resources flag in java rules?

I'm trying to figure out how to set a flag in the Bazel BUILD file or .bazelrc file so that I can turn on the --warn_duplicate_resources or --no_duplicates flags when building a Java jar (actually Scala in my case, but the answer should be the same). I want to make it so that if Bazel sees duplicate files when packaging a jar (such as two different logback.xml files) the build will fail instead of picking one file and discarding the other.
I had some issues with shadowing of different resources when building a new jar using an old jar. After rummaging through the internet I found the --warn_duplicate_resources flag in the bazel code base in a few different places as well as a --no_duplicates flag. These seem like they would be helpful making sure to avoid the problem of multiple jar files defining the same resource file.
https://github.com/bazelbuild/bazel/blob/master/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/SingleJar.java
https://github.com/bazelbuild/bazel/blob/master/src/tools/singlejar/output_jar.cc
However, I have no idea what flags to put in the BUILD or .bazelrc files to get the --warn_duplicate_resources or --no_duplicates flags turned on. The java_library rule doesn't seem to have any direct connection and simply adding "build --warn_duplicate_resources" to the .bazelrc caused the build to fail.
https://docs.bazel.build/versions/master/be/java.html#java_library
Any help will be much appreciated, thanks!

Sbt fat jar (which excludes unused code)

So I've been trying to do some AWS lambda with scala and sbt. And one of the recommendations is
Minimize your deployment package size to its runtime necessities. This
will reduce the amount of time that it takes for your deployment
package to be downloaded and unpacked ahead of invocation. For
functions authored in Java or .NET Core, avoid uploading the entire
AWS SDK library as part of your deployment package.
I've been using sbt-assembly to create fat jars for my code and dependencies, but it seems like sbt-assembly will package all library dependencies when I only use like 10% of the aws-core library which adds a lot of content. Was wondering if there is something I can do to cut down on the number of dependencies to what is actually imported in my code (and their dependencies).
As far as I know, there is no direct and safe way to selectively contains the dependent classes in a fat jar generated by the sbt-compile plugin.
First of all, you should understand that sbt plugins just provide a settings and jar files required to invoke methods in your project. It means that the dependent plugin is brought to your project with the pre-compiled jar file, which is determined by the version that you specified on your build setting (e.g., plugins.sbt in your project dir).
For example, the jars of sbt-assembly are brought to your project from this link when you specify that you want to use the sbt-assembly (although it is brought to your project when you use recent sbt version by default).
Therefore, at least you may have two choices to shrink your jar files.
Compile the jar file from the scratch
For the sbt-aws, its source code is provided on this link, so you may selectively compile the source codes to get the classes that your program is going to use.
Use the tool for shrinking jar file
There are several tools to shrink your jar file based on the dependencies. The most popular tool is proguard; it seems that there is a proguard support for sbt.
Warning
As mentioned in another stack overflow answer, selectively choosing some classes from the jar may cause your program crash depending on the input value and several other conditions. You've said that only 10 percent of the jar file is used, but you cannot ensure whether other classes are required from your code and library that your project depends on. When you use the tool for helping you to shrink the jar file, be careful when the program is security critical one.

Can MR-Jars overwrite classes from other jars?

I have a jar that works on Java 8.
I would like to create a new jar, that is going to be Multi-Release JAR but empty, just with 'patched' classes in META-INF/versions.
I would like to have a separate jar, so people can include it on Java9, otherwise, they use the default one. Why? Because so many tools are not yet prepared for Java9 MR-Jars.
Would this be possible? Would Java9 MR-Jar override classes from others jars?
Why?
The idea behind Multi-Release jars is that they provide simple patching. In my humble opinion, the way MR jars works is not satisfying.
There are two reasons why I can't make 2 separate Jars:
try to make cross-compile source base that works with Java8 and Java9. You would end up with folders like java, java8 and java9... and then have the build produce two jars, two poms... Yeah, good luck.
Imagine that I even build a library for java9. What about transient dependencies? That would mean that all other libraries that uses mine, would need to have jre8 version that depends on my jre8 version. Just because there is Java9 version!
Here is the story:
My A is a Java library built on Java8 but packaged as Multi-Release Jar which means it contains additional classes for when jar is run on Java9. Additional classes are built separately on JDK9 and I copied them manually (yeah, I know, but it works for now).
Unfortunately, some tools and servers (Jetty) are not aware of MR Jars and this makes them NOT working.
For that reason, I have A-jre8 version of my library, that comes without any extra classes, so servers can use it.
However, if user is using library B that depends on my A, he will still get the MRJar version of A and this will fail again. I want to be able to prevent this somehow. And I can't say to B: hey, could you make B-jre8?
Possible solution
JAR is just about packaging!
Allow the separate jar to patch existing jar.
In my case, I would just include A.jar9 and Java would consider A.jar and A.jar9 together as a package. No need for META-INF/versions. Very clean. And, best of all, it would help in situations like above! If run on Java8, the jar9 jar would make no difference; if run on Java9 the jar9 jar would patch the jar with the same name. Simple as that. No transitive dependency hell.
Rename classes in META-INF/versions.
Common Oracle, have you ever heard about the classpath scanning? Could you at least rename the classes in versions to e.g. *.class9 so not to be caught by existing classpath scanners.
As it is today (Java v9.0.4) - no.

How can I build a hierarchical JAR file for a library with SBT?

I am working at a library needing some dependencies.
For ease of deployment, I want to create a JAR file containing everything, including the dependencies.
I have tried sbt-assembly - this works, but it may be inadvisable due to legal reasons, so I'm looking for a solution where the resulting JAR file has the original JAR files inside, and where the classpath entry in MANIFEST.MF is set up such that client classes may just add this "nested JAR file" into their classpaths.
Is something like this even possible? sbt-one-jar nearly does, what I want, but only for executables - my product will result in a library, so this is not a perfect fit.
As I've used SBT so far, an SBT plugin would be easiest to use, as it is rather too much work to convert everyting to maven or gradle or ... now.
After thinking a bit more about how class lookup works, we dediced to abandon this experiment.
Basically classes are loaded by ClassLoader instances, and the standard class loaders for applications use a fixed strategy of how to find classes in JAR files or directories.
It seems that to allow a library to be located in a hierarchical JAR file, we must also provide the user of this library (i.e. the library client) with a special classloader so that our client may load all needed classes from the hierarchical JAR.
This is too much work to be worth it - the whole idea of a hierarchical JAR was enteratained only to simplify deployment, and having to juggle own classloaders would nullify this simplification.
In short - possible, but probably not worth the effort.

Automatically run maven on save in MyEclipse, without committing project files

This may be a problem that others have had before, but I've not been able to find the right search terms if so.
I am using LESS CSS (a CSS pre-processor) in my webapp, and I need it automatically compile a CSS file whenever a LESS file is saved, such that I can just refresh my browser and see the changes. I have previously been successful in doing this by changing the project properties in MyEclipse, in order to point at an external maven executable, and the generate-sources phase within my project's POM.
We're now in the progress of transitioning to GIT (very slowly), and as a step on that path, we want to ensure none of the project files are in version control. Obviously this means that setting up an external executable in the project files is no longer viable, if I want all developers to automatically have this happen for them.
Can anyone please point me in the right direction for solving my problem?
You could try the web resource optimizer for java (aka wro4j). It can apply less css processor (or many other processors) using both: runtime solution (as a filter) or build-time solution (as a maven plugin with m2-wro4j eclipse plugin which is capable of identifying incremental builds).
Alternatively, there is a lightweight solution which process the less resources on the fly, using the LessCssFilter

Resources