I'm looking into a solution that displays the subversion revision number and last modification date in my application (written in GWT, therefore reflection is not available). Encode the revision in subversion keyword doesn't work as it applies only to the current file. Is there a better solution using annotation? (e.g., a separate class that's executed during the compile time, grab the latest revision # on the whole project and inject the revision and last modification date to the source code)
I kn
#SvnRevision("$Id$")
public class Foo {
}
Then your classes are all annotated with their version. You need to make sure the annotation is defined as having runtime retention so it can be queried at runtime.
EDIT
OK, since SVN doesn't have that feature, I'd write a Maven plugin to emulate it. Maven has access to the SCM information for every file so during the build phase you could have it do the same keyword expansion.
Annotations are not really designed for this. It's easiest to do it as part of the build.
Using Ant you can generate a file that contains the version information, include it in your application's JAR, load it as a resource on the server, and serve it out to the browser-side code by RPC. Ant can also do string replacement in files as it copies them, which you can use to include the version number in your application's HTML files (no need for RPC then).
No idea about Maven, but I would be very surprised if it could not do the same kind of thing.
Subversion still has the $Id$ feature, but it needs to be enabled explicitly using the svn:keywords property on the files (set it to 'Id').
See also: http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html
So the idea of Jherico above with #SvnRevision would work.
Related
I have a set of Java projects that use the same library. The problem is that the previous version of the library included classes which methods names started from upper-case characters like MyClass.DoSomething(). The next version of the library became more "Java-friendly" and method names were changed to lowerCamelCase like MyClass.doSomething().
Now I need to rename all these methods in all of my projects, but doing it manually is a long and boring task.
I wonder is there exists some IDE plugin or tool that may perform this task automatically.
Most (Any?) modern IDEs have method rename refactoring feature. In Intellij Idea it is Shift-F6 when your cursor is at the method name. So one of the options is to rename each of the methods.
You could also write a hacky script which I think should work for most of the cases and all other cases could be done manually. It would search for entries like .DoSomething( and replace them with .doSomething(.
What IDE? Netbeans allows you to do project-wide search and replace, so you just need to do that once for each function.
Alternatively you can open up the old version of the library project (if it is open source) and change your library dependency to be a project one. Now go through and refactor the library project to the new names and it will rename all the old references in your code at the same time. Once you are done ditch your copy of the project and switch back to the library but the changes from refactoring will remain.
When using multiple APIs in a single project, the JAR files required for each API are added to the project in addition to other needed libraries such as Apache Commons, logging, etc. that are already used by the project. This sometimes results in a large number of jar files.
When a certain API or library is no longer used, it would be nice to remove the JAR files associated with it. However, there is a risk that another API or library requires it. This would NOT always become apparent during the building of the project. Sometimes, JARs that are missing throw errors only at runtime.
I have the following questions:
What is the best way to deal with this issue? In other words, be able to remove JARs without running the risk of runtime errors later?
I have been told that Maven solves this problem. Does it? Would it work if the external APIs used are not Maven-based? Would I be able to remove JARs without worrying about runtime errors? Do I need to rewrite my entire project to be based on Maven?
How do non-JVM platforms deal with the issue of shared libraries and removing them? Is Java lacking in this area or it is a common issue for all platforms?
Yes I agree Maven could help you in this case. Basically in Maven compile & runtime dependencies for each artifact (jar/war/ear/etc) are declared on pom.xml file. If multiple dependencies depends on same artifacts the latest version is used -- for example:
A-1.0.jar -- depends on --> C-2.0.jar
B-1.0.jar -- depends on --> C-2.1.jar
Only C-2.1.jar is is included in your project.
If a required dependency couldn't be found / taken out, Maven build will automatically fail. So to avoid runtime dependency missing, you can declare a dependency in runtime scope to a particular artifact -- and when you no longer need it you just take it out
There is an old trick I used to use on UNIX many years ago, it might still work for you. First use UNIX "touch" to set the date/time on all your files to the current date/time. Then wait for at least one minute. Then run your application. Then run UNIX "ls -lut" to list all your files, but this time the ones that were not used will have the date/time set in the first step whereas those that were used will have a more recent date/time due to the "u" switch reporting the last used date/time.
I was just curious to know this, when i give mvn install without doing 'clean', maven compiles only the modified java files. How does maven identify a java file is modified or not? I believe it is not using the last modified property of the file.
Reason for my belief: I had a module, after merging a change from svn, i gave mvn install and it didn't compile the modified file and when i looked at the change i saw that 'long' were modified to 'Long' in getters and setters.
So i just want to know how maven identifies if a java file has changed or not?
(P.S I'm using Apache Maven 3.0.3, if that matters)
I believe the Maven compiler plugin uses last modified dates on the source and class files to determine whether recompilation is necessary.
The compiler website is rather short on information, but the compiler:compile goal page has information on the following attribute, which finely tunes the staleness calculations: http://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#staleMillis. That's about the only official statement regarding staleness.
Without knowing much about maven, I can tell you that generally speaking, "make"-like tools use the "last changed" timestamp, which would explain the issue you had with svn ( see Wikipedia on Subversion's weaknesses.
Robert Scholte's comment at https://issues.apache.org/jira/browse/MCOMPILER-205 explains the process. It depends on the "useIncrementalCompilation" option of the "maven-compiler-plugin" (and on the version of it btw, I've only managed to have "useIncrementalCompilation" work with 3.1, not 3.0):
I see there's some confusion, so something needs to be changed, maybe
improving documentation is good enough. Looking at the code, you'll
see that non-incremental will only look at changed sourcefiles.
Incremental will also verifies if dependencies have changed and if
files have been added or removed. If it has changed, it'll remove the
complete classes-directory. The reason is that the default java
compiler is quite fast, likely much faster than analyzing per file
what to do with it. IIUC the eclipse compiler is a real incremental
compiler, so we could decide that based that based on the used
compiler not to drop the classes directory.
I've a chunk of code that works fine in isolation, but used a dependency in a clients project fails. A call to
Document doc = impl.createDocument(null,null,null);
fails (looks like the problem at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4913257). The instance of 'impl' in my unit tests is an instance of com.sun.org.apache.xerces.internal.dom.DOMImplementationImpl. In my clients code, its an instance of org.apache.xerces.dom.DOMImplementationImpl.
How do I trace back this dependency? I've tried manually going through all classes and jar files in the classpath, but cannot find the provider of org.apache.xerces.dom.DOMImplementation. Is is possible to observe when classes are loaded (and why)? How is the particular DOM implementation selected? Can I for now force the jvm to use a particular implementation?
The implementation in the "com.sun.org.apache..." package is the Xerces that's packaged as part of the JRE. The one starting "org.apache..." is the standalone distribution from Apache. They can be run together in the same application, but it can get quite confusing.
Your client's project would appear to contain a copy of the standalone apache distribution (probably xercesImpl.jar). Ask them to rem,ove it and see if it starts using the built-in JRE code.
Most likely you do not have xercesImpl.jar in the client project's classpath
I think you could deal with endorsed standards stuff.
I've trying to use Eclipse JDT AST parsing classes. After including the initial JAR, and sorting out a couple more dependencies, it is with 7+ JARs and I still having NoClassDefFoundError exceptions. This situation arises whenever I'm trying to test libraries with little or no documentation. Trial and error seems a very dumb (and annoying) approach to solve this problem.
Is there a way to automatically sort this out using Eclipse?
Update: Later I found that adding all the JARs you have, and using Ctrl-T (to view/locate types), lets you manually locate the JAR. That was the solution that Google provided so far. Is there a better way?
If you refer to this SO question Finding unused jars used in an eclipse project, you also have:
ClassPathHelper, which can quickly focus on unresolved classes:
It automatically identifies orphan jars, blocked (obscured) classes, and much more.
The only limit is dependencies that are not defined in classes, e.g. in dependency injection framework configuration files.
I have found setting up a workspace exclusively for browsing the eclipse source code incredibly useful. In this manner, you can use PDE tools like the Plug-in Spy, bundle dependency analysis, browsing the documentation, etc much like you would your own plugin projects. I found this article at Vogella a very useful guide.
If you know which bundle your desired class is you can generate the transitive closure of dependencies by creating a new OSGi launch configuration, with just the single bundle selected. By hitting the Add Required button, you can see all bundles necessary to use the one you're interested in.
Edit:
From your question it wasn't clear as to the environment you want to run the compiler in. If you're interested in an embeddable Java compiler to be run outside of an OSGi environment, may I suggest Janino.
You could use a dependency analyzer like:
JarAnalyzer
This will parse a directory full of Jars and give you an XML output dependency map, for which there are several tools for displaying in either graphical or text form.