I have a project with a million jars (well, a lot). They came to me by maven, and I only use a small set of functionality. For cleanness sake, I was wondering with jars I could do without.
My first thought was to run the program with a code-coverage tool, and then find the classes that are touched.
Has anyone done this before? Or are there smarter tricks to achieve the same?
You can run the project using the -verbose:class VM option. This will print for all loaded classes where they are loaded from. Using some smart parsing app/grep/regexp will allow you to filter the jar names into a set of unique entries and tell you which are used.
I think this would be easier because it will automatically tell you if a class is used and if so in which jar.
Of course the problem with this and code coverage is that it will be possible that you delete a jar that is only used in some exceptional case, but your compiler will complain if you deleted one or two too many, leaving you with the (mostly not too complicated) task of finding which jar the class is in.
Possible suggestion when using linux:
java -verbose:class <your startup command here> | grep "\[Loaded" | grep -o "from .*\]" | cut -c 6- | sort | uniq
If you aren't using linux, then save to a file, get a linux machine and run on linux (or use something to run bash commands on windows)
Consider using a tool that already exists, like Dependency Finder or JDepend.
As with all static analysis tools, the use of reflection or DI frameworks can throw this off; I've resorted to custom tools that use this and other inputs to figure things out, although it's still static.
For full runtime usage info you can use Thirler's solution, although whether or not it's complete may depend on which code paths are followed.
You can use Maven Dependency Plugin for analysing your dependency tree. It will also suggest you the dependecies which are downloaded/added to your project because they are dependent to any other jars.
Do run a mvn dependency:tree and see if you are using few unrequired jars.
Related
I have a simple pre-processing step that infrequently needs to be performed on some resources in a Maven/Eclipse project, this involves a simple OS command using a utility executable, for example:
glslc triangle.frag -o spv.triangle.frag
The glslc executable processes the triangle.frag shader module and generates the spv.triangle.frag output file (in the same directory).
Ideally I would like a maven goal that performed the above for all modified .frag files within a given directory structure, rather than having to switch to a terminal, or create shell scripts, etc.
I assume an ANT plugin for Maven is the way to go (assuming that's the simplest and most common mechanism available). I have tried adding a maven antrun plugin but I'm struggling to work out how to configure it for multiple/modified files. I'm sure it's relatively straight-forward but it's been a long time since I've had to fiddle with ANT and I'm at a bit of a loss where to start. Had a look online but can't find any decent examples or tutorials, probably because I'm not searching for the right things.
Note that the files do not change that much but it would be very convenient to have a quick-and-dirty (or hot-deploy) means of generating the output file file(s) that have changed.
Also note that these resources do not need to be part of the maven build/deploy process, i.e. they are only used during development and testing.
Alternatively is there an equivalent Eclipse mechanism that that can be used to do the same thing? Again this is a convenience so something relatively 'manual' is fine.
I'm looking for any pointers to relevant examples, tutorials, repos, etc. as a starting point or hint from which I can then implement a solution.
I'm trying to run the open-source Java cookbook using chef-solo and although it shouldn't require any other cookbooks, chef keeps saying that a cookbook required to run this one is missing. First it asked me to install apt, then homebrew, then _build_essentials_. It seems like a never ending list of cookbooks. What am I doing wrong?
This is how I'm running the cookbook:
chef-solo -c solo.rb -o recipe[java]
Where solo.rb is a configuration file with the path to the cookbooks folder.
The same thing also happens when I try to run the WAS cookbook.
In short: Chef does not (yet) support conditional dependencies. That's why all cookbooks that provide resources or recipes that might be used need to be declared as dependency.
The Java cookbook uses resources from many other cookbooks to install Java on different systems, e.g., Windows, Linux, MacOS etc. Therefore, it makes use of other cookbooks, that provide resources for e.g. installing a package under Windows, adding an APT repository etc.
In order to allow the cookbook to either include a recipe or use a resource (e.g. apt_repository) from another cookbook, this one has to be specified as dependency so that it is loaded prior to executing the cookbook (e.g. Java). Otherwise, this resource/recipe would not be known to Chef.
So all of these cookbooks will be loaded during the Chef run, but their code will not be executed. While this feels a bit annoying, esp. in your case when you obviously manually download the cookbooks, this isn't so disturbing when you use Berkshelf for dependency resolution. This is highly recommended.
At my current company we build major releases about twice a year, and throughout the year, when bugs are fixed or new enhancements added, we build service packs to release.
A service pack would basically be a .jar file that is dumped onto the clients machine, and since it is first on the classpath, that is then the code that will execute. (If you do not know what I am talking about - sorry, this might be old school).
The jar file contains only the changed class files and it is normally assembled by hand, by the developer on the job.
I am using hudson for above mentioned steps. If it is possible to specify that hudson to look at two revisions and put the differences between them to a service pack (class files into a sp.jar). This would enable us to automate our deployment of enhancement or bug fixes and it would definitely have added advantage.
If anyone know of such functionality or setup, could you please share your online resources?
Thanks
Using ant script you can achieve the output:
See some tool which can help you.
clirr
java -jar clirr-core-0.6-uber.jar -o OLD.jar -n NEW.jar
Or JAPICC
japi-compliance-checker OLD.jar NEW.jar
Or PkgDiff
pkgdiff OLD.jar NEW.jar
I have a Java project that's paired with a bash script to make it easier to deploy on Linux. The script is a lot more complicated than this, but the part that matters is a section like this:
directory="/default/install/directory"
jarName = "myApp-0.0.1.jar"
command="/usr/bin/java -DARG=$argValue -jar $directory/$jarName"
When I update the version to 0.0.2, I would like maven to automatically change this line in my script, simply to:
jarName = "myApp-0.0.2.jar"
I'm sure this would involve maven-release-plugin in some way - possibly with sed -i, but my development machine is Windows so such tools are not so readily available (though I do use cygwin) - but I'm not really sure how. Thanks!
This is typically done by placing these kind of scripts as Maven resources.
Using Maven properties ('jarName = "myApp-${project.version}.jar"') instead of hardcoded values, and activating filtering on these resources will make this straightforward.
If these scripts should be packaged in a different way than just inside the JAR produced, the assembly plugin will be able to do the job.
I'm trying to figure out how a system works. When I do a 'ps -A' I see several java processes. Is there a way to run a command that will examine a java instance and let me know what all jars or classes are loaded from that instance (preferably without stopping the instance)?
You can use jconsole or visualvm to get the details of the running JVM. These require xwindows if you are using linux.
Further, jps -v will let you know what was the command line argument used to start the JVM. From there you should be able to see what jars where used for the classpath.
You will need to use some Java specific tool such as VisualVM to do what you are inquiring about.
ps -Af
Will show you the exact command used to launch the process. It can not, however, tell you exactly which libraries that the invoked JAR file has loaded (although you do presumably get the classpath so you can make inferences).
For more detail you'll need a tool that interrogates the JVM.
In case of Java application server running web or enterprise (EAR) application, you cannot deduce all used jars from command line. But you can use e.g. lsof command to list all files that given java process is using. And filter jars from them.