Can MR-Jars overwrite classes from other jars? - jar

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.

Related

Is it possible to manage a hierarchical product structure in SBT which has more than just one level?

We have a multi module project consisting of two modules, modA and modB.
modA depends on modB.
modB in turn depends on a list of libraries (libA and libB) where we also have the source code. This sources have already been adapted by us.
At last, libB and libC are independend from each other, but depend on a third library, libC.
What I want to have is a setup, where the three libraries (which are in principle also a multi-module SBT project) can just be "included" in the top level project.
The point here is also that these libraries can be re-used for other projects, too, so the changed sources should not belong to this super project only.
Currently I tried to solve it by including the library as GIT submodule.
Unfortunately SBT does not (seem to) support hierarchical sub modules, so I cannot really just have a second, also multi-module SBT file for all libraries which just gets included in the "super-super" project.
This current setup is clearly not the SBT way.
What is the intended method of solving this?
Just adapting the library separately and re-using it just as JAR file in the super project is possible, but clumsy, because the using project(s) are the main reason to hack the library, so it would be nice if this works in a smooth way.

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.

Is it necessary to use gradle with roboelectric for android unit testing?

I and my team have built up an android library project. it is built up on eclipse but we are using ant to build it. Presently we aren't using gradle. I have a roboelectric with dependencies jar file instead. But when I use this, while running the unit tests, the following error comes up
WARNING: multiple versions of ant detected in path for junit
[junit] jar:file:/Users/prateekarora/Desktop/eclipse/plugins/org.apache.ant_1.9.2.v201404171502/lib/ant.jar!/org/apache/tools/ant/Project.class
[junit] and jar:file:/Users/prateekarora/trunk/client/android/MCCMobileClient/test2/libs/robolectric-2.3-with-dependencies.jar!/org/apache/tools/ant/Project.class
When I remove the apache ant from eclipse's plugin folder, this stops working.
Can Anybody explain why this is happening?
Also, is it necessary to use roboelectric with gradle? If no, where can I find the roboelectric's jar files with/without dependencies?
It is not necessary to use gradle with robolectric. It is just about running specified java class (from junit) with proper classpath (including you source, test code and dependencies). Fixing your case is not something that is easy to make over stackoverflow (it will be some challenge even if you sit behind same computer).
Here are possible solutions:
Migrate your project build to the gradle
Keep using ant but move from dependency management from manuals jars to ivy
Keep using ant and manual jars dependency, but try to get robolectric.jar with all dependencies except ant one
The first one option is the easiest option as for me. It will require to change mindset a bit but this is officially only one supported build tool by Google as well there are a lot of examples and people that could help.
The second one also require you to learn how to use new tool. As well there less examples about ivy usage especially in android projects.
The third one will require to write custom script that removes ant from jar file or to rebuild robolectric-all.jar without one (ant) dependency. This will require to dive into maven build tool learning

What is the implication of exportjars := true?

I've just started using an sbt plugin for packaging JavaFx/ScalaFx applications sbt-javafx. This under Java 7.
While the plugin seems to work pretty well, it is not able to properly package multi-module project. A workaround they have found is to use exportsJars := true in all the modules on which the JavaFX modules depends on.
I also have IntelliJ IDEA that can produce a JavaFX application for me, though that would break the automated build. I'd very much like to have the executable automated.
I need to understand the broad implication of that parameter on my sbt build. Why is the setting needed to be true?
Here is the help definition:
Determines whether the exported classpath for this project contains classes (false) or a packaged jar (true).
It sounds like by default it's false. Why?
p.s. If someone has a cleaner solution to package JavaFX/ScalaFX applications using sbt, please feel free to share.

"Make" system for Actionscript?

In working on larger Actionscript/Flash projects, I've started to really feel the need for some kind of "make" system, but I haven't found it yet. Does anyone know if it exists?
Required features:
Ability to associate SWCs with their source code and/or FLAs i.e. "this swc is compiled from this source"
Ability to mark my current project as depending on these SWCs (either as compile-time or runtime libraries)
A single, big shiny button, that when pressed does the following:
Checks to see if any of the source files have changed, and if so, recompiles their associated SWCs
Recompiles and relinks the main .swf, if necessary
Runs the main .swf
Have yet to find a way to get something like FlashDevelop to do this (but I don't know it well enough to be sure). Support for both code and FLA sources is preferred.
You are looking for http://projectsprouts.org/ which is based on Rake the Ruby version of Make. It can do all of that stuff and much more.
If you have Ruby and RubiGems installed which I think are installed by default on Macs you can install it by typing this into your command line.
sudo gem install Sprout
It will take a while because it installs many things. After this is all set you can create a project like this.
sprout -n as3 ProjectName
and then build it with this,
rake deploy
It manges things based on the runtime they are created for, this project was created for as3 but all of the other types of projects also. The build scripts are all writen in Ruby and can be modified to involve more complex multi-step compiles pretty simply. It also has a bunch of generators so that classes automaticly have unit test that are associated with them and many other features.
Might be a stupid suggestion, but if you want make, why not just use "make"? You can use it for any language by defining the right rules.
Apart from that, I've seen a lot of Flex/Actionscript projects use Apache ant, an XML based build system.
As said by wump; why not use Make?
There are some ANT scripts included in the Flex SDK, so you could explore and expand those. I've also spoken to people who use Maven and Cruise Control for automated build process.
Here is some info on Maven Flex: http://code.google.com/p/flex-mojos/
And some info on Cruise Control w/ Flex: http://www.eyefodder.com/blog/2006/05/continuous_integration_with_fl_5.shtml
Well, there are several options. One I would recommend is the Maven plugin for Flex flex-mojos, now maintained on the Sonotype site. If Maven isn't your cup of tea, they do have an Ant plugin, I don't know if NAnt can call Java Ant tasks directly or not. The third is the most complicated, but Adobe does include an OEM version of the compiler, I believe it comes by default with the SDK download. This is the one I used in the Maven plugin I developed for my company. The reason we didn't use the flex-mojos one basically boils down to a...disagreement about the "Maven way" of one project = one artifact. Their interpretation is that 1 SWF file is one artifact, so is one Maven project. My definition for my project is that all 80+ modules, each a SWF file, are no different than JSPs, all bundled in the same WAR file. So I've got one project with a LOT of modules and 1 maven pom.
You could check out Antpile which according to said link "is a collection of Ant Scripts which cover everything from building a SWF, SWC, AIR, Android and even Unit Testing."

Resources