Is it possible to get all apache commons at once? - java

Sorry for such question since it is more my duty to search for it, but I looked everywhere and didn't find answer for it.
Is it possible to get all apache commons components in one jar or there is no such archive?

No, we don't have a "all-of-commons" jar (nor should we). It'd be large, and the functionality would be a pretty bizarre mix. You could always (attempt) to create one yourself, but you might need to do some shading if there's any version mis-matching.

I highly doubt it. It makes no sense to combine such a broad array of functionality into a single jar. Most of the projects have nothing to do with one another and it is unlikely to require them all for a single application.

You can download the whole of spring in one hit. I have seen project "using" Spring, not as a container but as a way of including lots of libraries which can work together. i.e. no actual Spring class is used.
However I suggest you use a proper dependency management tool such as maven and you shouldn't need to download a jar yourself ever again. ;)
A good web site for finding dependencies is http://mvnrepository.com/ which have the XML you need to add to your pom.xml to get any version of most JAR you need.

Related

How can I use my utility classes in different git-projects at once?

I'm a beginning programmer and I apologize if my questions is trivial but I haven't found a sufficient answer to my problem.
I have a git repository called "toolbox" with some utility classes that I frequently use in other projects. Until now, I have manually copied those class files from this project in other projects whenever I needed them.
This if of course not a good way of doing it. I frequently add new features and fixes in whatever project I'm currently working on to these files. It makes version management a nightmare.
What I'd like to to is to import the toolbox-classes directly into the IntelliJ-Project(s) (which is also on the same git as the toolbox repo) and whenever I make a change to those files in the toolbox-repo I want the other projects to be able to automatically pull those changes as well.
If possible I'd also like to be able to share my toolbox-repo easily with others who might need those classes. But that is not a requirement. I'd just be nice to be able to do so.
I tried to use git submodule. It included the entire toolbox-repo in the target-repo but unfortunately I wasn't able to use the utility classes. I asked someone more experienced and they told me that I need to define "SourceSet" in the gradle.build but I wasn't able to configure that due to my lack of knowledge.
How can I include/import/use my utility classes from my toolbox-repo within other projects?
Thanks for any advice.

Using the openNTF Domino API as a dependency in Plugin dev

I have been using the openNTF Domino API (ODA) for a while now and am very happy with it. In fact I am so happy that I want to use it with my own OSGi Plug-ins as dependencies, and I am having trouble with that.
The following is what is going on.
When I just start the plug in and do not use anything from ODA, everything is good. I can select my new library as required in Notes Designer and I can use my classes and all seems well.
The second thing I do is I go into the /META-INF/MANIFEST.MF and I mark org.openntf.domino as a dependency. From what i see, this is the correct plug in because it contains the ODA Document, View, Session etc. Classes that i want to make use of. If I should be using a different plug-in, please tell me.
I go into my class which extends the com.ibm.xsp.library.AbstractXspLibrary and I get a little stuck with the Library.getDependencies(). I am not really certain what to include here to mark my dependency on ODA. I have tried a few different strings, but in the end, I am not even sure if I need to mark it here as a dependency.
I have tried:
"org.openntf.domino"
"org.openntf.domino.xsp"
"org.openntf.domino.xsp.XspLibrary"
I think I tried a few other things but cannot exactly remember what.
The main issue is that I can no longer select my plug-in library in Notes Designer and I cannot use it(obviously). So my question is, how do I correctly add my dependency to other plug-ins installed separately? I will not only be using ODA, but also the ExtLibs.
I am very grateful for any help!
I know that "org.openntf.domino.xsp" depends on "org.openntf.domino.plugin", in the same way I think you want your library to depend on ODA. It also depends on Extension Library. Looking at that, my suggestion is to try:
On plugin.xml, Dependencies tab, add "org.openntf.domino.xsp". This tells it to look for that plugins already on the server, otherwise don't run, in which case I think tell http osgi diag com.myplugin would throw an error. org.openntf.domino.xsp is already dependent on org.openntf.domino.plugin, so that's the only plugin you need as a dependency.
I don't think you'll need to tick "Reexport this dependency". I think you'd do that if you didn't want to install the ODA plugin on the server itself as well. Also, I don't think you'll need to add any exported packages on the Runtime tab.
In getDependencies(), add "org.openntf.domino.xsp.XspLibrary". This loads the XspLibrary class when you load your XspLibrary.

Java: Libraries within Libraries and Classpath Issues

We are having a discussion at work and an interesting point came up:
Say you are developing a small library, call it somelib. Say that somelib needs to do some logging, but you don't want to reinvent the wheel, so you decide to use a 3rd party logging library.
Additionally, you want to make integration of somelib as painless as possible, so you distribute a single JAR file (somelib.jar), which has the other logging JAR, call it logger.jar, embedded inside of it. Much like what Maven's jar-with-dependencies assembly does.
Now comes the issue. Since your product is a library, what if your customer is using somelib and also happen to be using a different version of the same logging library on their own. Now we have a classpath problem.
This seems to me like it would be a common problem for people that write libraries, so what is the typical solution?
Do they avoid using JAR bundling methods altogether? Even if we do that, there is still an issue with a user's code expecting version X of the logging library, and somelib's code expecting version Y.
Do they somehow insert a dummy package prefix so that the logger classes in somelib won't conflict?
What about dynamic loading of the logger library? (though this still has versioning problems from 1.)
You may consider to use OSGI or wait for JDK 8 and its Jigsaw project.

JAR Hell Hacks for Non-OSGi Developers

Edit: After reviewing the play, the example I used below is a tad misleading. I am looking for the case where I have two 3rd party jars (not homegrown jars where I have access to the source code) that both depend on different versions of the same jar.
Original:
So I've recently familiarized myself with what OSGi is, and what ("JAR Hell") problems it addresses at its core. And, as intrigued as I am with it (and plan on migrating somewhere down the road), I just don't have it in me to begin learning what it will take to bring my projects over to it.
So, I'm now lamenting: if JAR hell happens to me, how do I solve this sans OSGi?
Obviously, the solution would almost have to involve writing my own ClassLoader, but I'm having a tough time visualizing how that would manifest itself, and more importantly, how that would solve the problem. I did some research and the consensus was that you have to write your own ClassLoader for every JAR you produce, but since I'm already having a tough time seeing that forest through the trees, that statement isn't sinking in with me.
Can someone provide a concrete example of how writing my own ClassLoader would put a band-aid on this gaping wound (I know, I know, the only real solution is OSGi)?
Say I write a new JAR called SuperJar-1.0.jar that does all sorts of amazing stuff. Say my SuperJar-1.0.jar has two other dependencies, Fizz-1.0.jar and Buzz-1.0.jar. Both Fizz and Buzz jars depend on log4j, except Fizz-1.0.jar depends on log4j-1.2.15.jar, whereas Buzz-1.0.jar depends on log4j-1.2.16.jar. Two different versions of the same jar.
How could a ClassLoader-based solution resolve this (in a nutshell)?
If you're asking this question from an "I'm building an app, how do I avoid this" problem rather than a "I need this particular solution" angle, I would strongly prefer the Maven approach - namely, to only resolve a single version of any given dependency. In the case of log4j 1.2.15 -> 1.2.16, this will work fine - you can include only 1.2.16. Since the older version is API compatible (it's just a patch release) it's extremely likely that Fizz 1.0 won't even notice that it's using a newer version than it expected.
You'll find that doing this will probably be way easier to debug issues with (nothing confuses me like having multiple versions of even classes or static fields floating around! Who knows which one you're dealing with!) and doesn't need any clever class loader hacks.
But, this is exactly what all the appservers out there have to deal with. Pretend that your Fizz and Buzz are web applications (WARs), and Super-Jar is you appserver. Super-Jar will arrange a class loader for each web app that "breaks" the normal delegation model, i.e. it will look locally (down) before looking up the hierarchy. Go read about it in any of the appservers's documentation. For example http://download.oracle.com/docs/cd/E19798-01/821-1752/beade/index.html.
Use log4j-1.2.16. It only contains bugfixes wrt 1.2.15.
If Fizz breaks with 1.2.16, fork and patch it, then submit those patches back to the author of Fizz.
The alternative of creating custom classloaders with special delegation logic is very complex and likely to cause you many problems. I don't see why you would want to do this rather than just use OSGi. Have you considered creating an embedded OSGi framework, so you don't have to convert your whole application?

Using serviceloader on android

I am very new to java and android development and to learn I am trying to start with an application to gather statistics and information like munin does. I am trying to be able to load "plugins" in my application. These plugins are already in the application but I don't want to have to invoke them all separately, but be able to iterate over them. I was trying to use serviceloader but could never get the META-INF/services into my apk. So I am wondering if it is possible to use serviceloader on android
Thanks
EDIT: I am asking about java.util.ServiceLoader, I think it should, but I can't figure out how to get my services folder into META-INF on the apk
There is an open bug report against this issue. See https://code.google.com/p/android/issues/detail?id=59658
The META-INF folder is deliberately excluded from the APK by ApkBuilder; the only comment in ApkBuilder.java is "we need to exclude some other folder (like /META-INF)" but there is no other explanation.
Even after adding META-INF with ant, you will still get in trouble if you want to use Proguard, which refuses to replace the content of META-INF/services/* files or rename them (that's another story, the author wants to keep Proguard agnostic).
However, people using maven may want to check https://github.com/pa314159/maven-android-plugin (the branch named "modified"), that tries to solve both issues. It is a fork from the original "android-maven-plugin" I modified one month ago for my own Android projects.
It also provides a patch for Proguard-4.7
Hope this helps, any feedback is welcome.
I've figured out a solution that may work for some situations. Instead of ServiceLoader, I'm using the org.openide.util.Lookup class / library that comes with NetBeans - it is a superset of ServiceLoader. It does not require NetBeans itself and seems to work ok with Eclipse. It is necessary to replace whatever ServiceLoader functionality you are using in your application with Lookup equivalents, and add the org-openide-util-lookup library. Then, you can just do something like this:
Lookup lookup = new ProxyLookup(Lookup.getDefault(),
Lookups.metaInfServices(myClass.getClassLoader(), "services/"));
And move your ServiceLoader files from META-INF/services/ to services/.
Note that, because of the ProxyLookup, this will continue to work on standard Java environments unchanged (i.e., in those cases it will continue to look in META-INF/services).
Here is a link to the documentation for the library: http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/Lookups.html
UPDATE
After working with this for a couple of days, it seems to function well - I move between environments (standard Java and Android) and it works properly in each location. The primary downside is having to manually copy the files to the /services directory.
It is possible. You may want to check http://developer.android.com/reference/java/util/ServiceLoader.html
ServiceLoader is stuff from the Java language that is not really relevant on Android. I recommend not using it. If you just want to find a list of classes within your .apk to load, there are all kinds of ways to do this -- put in XMl file in res/xml that lists them, use reflection, annotations, etc.

Categories

Resources