Obtain Spring and other framework version numbers in a JVM - java

I'm trying to create a 'skeleton' framework of sorts for a basic java app.
One thing I'm looking to add is a version page/display that list the current framework/libs attached.
For example:
Skeleton version: 1.0.0
Spring: 2.5.6
Hibernate: Malbolge
The purpose of the Skeleton project was to make it very easy for a new developer to quickly start a robust app.
I figured the worst case scenario is that I could search through every framework jars manifest and use that... but that's no fun...
Anyone have a different suggestion? This would be a no brainer if the project was going to use Maven... I could just parse the pom.xml or something to that extent...
I guess a more defined question is:
Given a folder of libs; is there a way to dynamically gather the jars/frameworks version # without touching the manifest?

You can get the Spring version using the SpringVersion class.
I had a code snippet in a previous question:
Need Spring version# - only have spring.jar file

Using System.getProperties() gives you a listing of JVM properties including the different version ids of the JRE, JVM and specification. Not sure if this will give Spring etc versions.

Related

Where to keep and how to handle the version of a Java application?

I am working on a Java application and want to show the version number as part of an "About" or "Help" dialog.
UPDATE: As a clarification: I do not want to display the Java version but the version of the application.
At the moment I keep the current version information in the build.gradle and ideally, I do not need to keep track of the version in different places for runtime and while building.
I found some very old articles which suggested to get the current version from the JAR`s manifest but I am not sure if this is still the way to go.
My natural approach would be to have an application.properties file in the classpath which contains entries like application.name, and application.version. If I am not wrong those properties can be accessed by Gradle while building the distribution and as well by the application during runtime.
Are there any other ways to do such a thing I am not aware of?
System.getProperty("java.version") should do it – provided you are looking for the Java version.
If you are looking for the application's version instead, you can propagate that to the application's /META-INF/MANIFEST.MF and read it from there.

How to add data derived from source code file name or content to a resource at build time

Background
I'm adding database migrations to an existing project using the open source project mongobee. The actual migrations are all handled by mongobee and its concepts of changelogs and changesets. Part of this enhancement involves checking the current MongoDB database migration version at runtime and comparing it against the version expected by the java application. The reasoning behind this is we'd like to have an installation of our product download code updates (new *.wars) and upon logging in the new version of the application, the admin user would be prompted to update the database if their database version is lower than expected.
We're currently using Maven to package and build our software.
Problem
The one area that's nagging me is how to handle tagging the database version the Java source code expects. I'd like to avoid manually entering this each time we do a build and add a migration.
My proposed solution may not be ideal. My initial thought is to use a convention for the changelog file and class names like "v0001_first_migration" and then at build time, use maybe the maven AntRun plugin to call a separately compiled java file that traverses the migration changelog directory and looks for the latest migration number and then stores that result in a resource file, probably XML. The application can then read that XML file at runtime to get the database version it expects.
1 - Is this feasible?
2 - Is there a way to do something like this in pure Maven without using AntRun?
3 - Is there another option to accomplish this easier?
As an alternative to my proposed solution above, I used a reflection project found here: https://github.com/ronmamo/reflections and iterated through all of the classnames in my migrations directory that follow the aforementioned convention (v0001_first_migration, v0002_second_migration). I parse those using regex to get an Integer and do comparisons to determine the migration version expected by the app. The database side was a lot easier so I won't go over that.
Now, instead of using Ant tasks I'm just popping the expected app migration version into a singleton (gross I know) or alternatively just calling the function that finds the expected app migration depending on where it's used.
WHY a Singleton? The parsing process is expensive and I expect to use this data on each REST call that wants to touch our database. In the REST layer I created the singleton because of some limitations with our current project. The better way here is in the case of Tomcat, create a ServletListener and assign the migration version as an attribute of the ServletContext. Due to the way our REST layer works, I'd be modifying a TON of function signatures to pass in the #Context ServletContext. We don't have Dependency Injection containers either so my options were limited if I didn't want to touch almost every action in the REST layer. The Singleton gets the expected app migration version at startup and that's it so it's still easy to test with mocks and there are no concurrency issues that I can see.

How to find out which dependencies need to be included?

I'm fairly new to Java/Spring and am trying to put together a simple app which will include some basic CRUD operations and I'd like to use Hibernate for data access.
I'm using Maven as my build tool. My question is: how can I find out which dependencies are required to use Hibernate? For example, I'm using Spring 3.0.6, but how would I know what version of Hibernate to use with that version of Spring? More over, if there are multiple possible Hibernate dependencies, how would I know which ones to include for the functionality I need? So far this seems to be partially reading documentation and partially trial and error.
Is there a definitive way of knowing which Maven dependencies to use with certain version of other dependencies? Any which dependencies to use for particular bits of functionality?
Thanks,
James.
I follow these steps when starting to use a new framework:
Go to framework's web site. In your case hibernate web site and try to find latest (or a specific) version. For hibernate it is 3.6.8-Final at the time of writing.
Search for a maven dependency definition on the framework web site. If you can not find any dependency definition, them simply google for "frameworkname _version_ maven dependency" and you'll most probably find necessary definition, as well as the necessary repository information. For example you can find the dependency definition for hibernate on mvnrepository.com and necessary artifact repository information on Hibernate 3.6.8 release page:
The artifacts have all been published to the JBoss Nexus repository under the org.hibernate groupId at http://repository.jboss.org/nexus/content/groups/public-jboss/
The question of which dependencies are necessary and which are optional depends entirely on the framework to be used. So for example in order to use hibernate, as stated on Hibernate Quick Start Guide:
hibernate-core: The main artifact, which contains all the Hibernate classes, in packageorg.hibernate. You need these to build applications using the native Hibernate APIs. It includes capabilities for using native Hibernate mapping in hbm.xml files, as well as annotations.
About compatibility issues (which version of hibernate is compatible with spring 3.0.6), all I can say is you have to read about integration manuals for those frameworks. Since Spring and Hibernate are two exclusively distinct frameworks, I don't think you can find a constant location to look for version compatibility matrix or something like that.
The purpose of Maven is to avoid handling dependencies by hand. Just choose which version of Hibernate to use and include it in your pom; Spring supports many different versions.
If you know what parts of Spring you want to use, just include those parts in your pom; they'll include their own requirements.
Is there a specific module and/or version combination you're having an issue with?
The only way to know for sure that you've got all dependencies is by running your app.
Maven resolves for you transitive dependencies so you can quickly detect missing ones by compiling the java code.
However, in a web app there are many dependencies that are required in runtime only, so they are not detected at compilation time.
you can find out the dependencies by running mvn dependency:tree and analyze if they are required or not by running mvn dependency:analyze.
Taking the newest ones usally works as long as they are stable.
Start with hibernate and spring core, context, tx.
After you added some could you will probably recognize that something else is missing.
Try and error doesn't sound good, but its working pretty well for spring dependencies.

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.

Ready configurations for Spring + Hibernate

Sometimes, it's very tediously to make own configuration, find all libraries, check it ...
So, is there any ready typical (template) config for appropriative task?
AppFuse can be used for generating project templates for your given choice and combination of technologies.
Spring Roo is designed for this. It's on RC2 for their 1.0 release now.
It has a command shell environment that allows you to pick and setup the parts of the Spring application you'd like to use. It generates the Spring config files, Maven setup, and templates the Java classes for you.
Besides being great for templating, it's also a good way to get yourself introduced to other parts of the Spring application stack (Web Flow, Security).
Maybe you'll find what you're looking for here: http://code.google.com/p/project-template/.
There is no ready made runtime config for your application but you can use things like Maven or Ivy to manage all the JARs you need automatically.
You could start from one of the examples as provided in the Spring download package and modify it to suits your need.

Categories

Resources