I'm developing a LoB application in Java after a long absence from the platform (having spent the last 8 years or so entrenched in Fortran, C, a smidgin of C++ and latterly .Net).
Java, the language, is not much changed from how I remember it. I like it's strengths and I can work around its weaknesses - the platform has grown and deciding upon the myriad of different frameworks which appear to do much the same thing as one another is a different story; but that can wait for another day - all-in-all I'm comfortable with Java. However, over the last couple of weeks I've become enamoured with Groovy, and purely from a selfish point of view: but not just because it makes development against the JVM a more succinct and entertaining (and, well, "groovy") proposition than Java (the language).
What strikes me most about Groovy is its inherent maintainability. We all (I hope!) strive to write well documented, easy to understand code. However, sometimes the languages we use themselves defeat us. An example: in 2001 I wrote a library in C to translate EDIFACT EDI messages into ANSI X12 messages. This is not a particularly complicated process, if slightly involved, and I thought at the time I had documented the code properly - and I probably had - but some six years later when I revisited the project (and after becoming acclimatised to C#) I found myself lost in so much C boilerplate (mallocs, pointers, etc. etc.) that it took three days of thoughtful analysis before I finally understood what I'd been doing six years previously.
This evening I've written about 2000 lines of Java (it is the day of rest, after all!). I've documented as best as I know how, but, but, of those 2000 lines of Java a significant proportion is Java boiler plate.
This is where I see Groovy and other dynamic languages winning through - maintainability and later comprehension. Groovy lets you concentrate on your intent without getting bogged down on the platform specific implementation; it's almost, but not quite, self documenting. I see this as being a huge boon to me when I revisit my current project (which I'll port to Groovy asap) in several years time and to my successors who will inherit it and carry on the good work.
So, are there any reasons not to use Groovy?
There are two reasons I can think of not to use Groovy (or Jython, or JRuby):
If you really, truly need performance
If you will miss static type checking
Those are both big ifs. Performance is probably less of a factor in most apps than people think, and static type checking is a religious issue. That said, one strength of all of these languages is their ability to mix and match with native Java code. Best of both worlds and all that.
Since I'm not responsible for your business, I say "Go for it".
If you use Groovy, you're basically throwing away useful information about types. This leaves your code "groovy": nice and concise.
Bird b
becomes
def b
Plus you get to play with all the meta-class stuff and dynamic method calls which are a torture in Java.
However -- and yes I have tried IntelliJ, Netbeans and Eclipse extensively -- serious automatic refactoring is not possible in Groovy. It's not IntelliJ's fault: the type information just isn't there. Developers will say, "but if you have unit tests for every single code path (hmmmm), then you can refactor more easily." But don't believe the hype: adding more code (unit tests) will add to the safety of massive refactoring, but they don't make the work easier. Now you have to hand fix the original code and the unit tests.
So this means that you don't refactor as often in Groovy, especially when a project is mature. While your code will be concise and easy to read, it will not be as brilliant as code that has been automatically refactored daily, hourly and weekly.
When you realize that a concept represented by a class in Java is no longer necessary, you can just delete it. In Eclipse or Netbeans or whatever, your project hierarchy lights up like a Christmas tree, telling you exactly what you've screwed up with this change. def thing tells the compiler (and therefore your IDE) nothing about how a variable will be used, whether the method exists, etc. And IDEs can only do so much guessing.
In the end, Java code is filled with "boilerplate," but it's been kneaded into its final form after many refactorings. And to me, that's the only way to get high-quality, readable code for future programmers, including when those future programmers are you-in-the-future.
Two reasons why Scala might be a compelling alternative to Groovy:
Performance on par with Java
Static typing without clutter
One of the biggest things you lose when you use dynamic languages, especially in a large codebase is the ability to use an IDE to re-factor. Languages that allow dynamically adding code to objects simply can't be parsed by today's IDEs to allow the kind of easy refactoring methods you can get from Eclipse, etc. for Java, C++, etc.
It's not really a case of "Dynamic languages are better than Static". Use what's best for you. The really cool thing about Groovy in particular is you can mix and match Java and Groovy in the same project, and it all runs on the VM. Yes, Scala is another example.
I think the biggest issue is lack of IDE support compared to java, however the plugins for Eclipse and Netbeans are getting better all the time. Also, if I remember correctly Groovy does not support anonymous inner classes if you really need them for some reason. I would personally choose Groovy anytime though.
Related
I am a mainstream java programmer but recently, I've been taking interest in smalltalk. I must admit that I am totally blown by the immense power that the language gives to the programmer and I find dynamic typing as a big plus (personally).
I do not want to compare the two languages because I understand that java is a good fit for the enterprise reality that takes away much of the programmer's power for good (like the usage of pointers?) to lessen the scope for committing mistakes. Agreed. But I fail to understand why was the concept of blocks/closures eliminated not included in the language? Because I really find them very useful and I don't see a reason why such powerful a feature cannot be married into java, albeit the fact that it is static typed. Is there any specific reason for this?
AFAIK, it was not included because Java has based on languages which did not have this feature. Instead Java has alternatives which achieve the same thing but in relatively ugly ways.
Hopefully, it will be included in Java 8 if only to stop people complaining about it. ;)
I don't see a reason why such powerful a feature cannot be married into java
Can you think of a realistic example of something you can do with a closure, you can't do with Java already? The main difference is productivity and readability. While these are very important, its not like it can't be done.
[This is an empirical question about the state-of-the-art: I am NOT asking if Java is cooler or less cool than the dynamic languages that work in the JVM.]
Aside from cases where performance is a main decision factor, do companies/developers still willingly chose Java over Groovy, JRuby or Jython?
Edit: If the answer is "yes," why?
Personal Note: The reason I am asking is that, while I do some subset of my professional work in Ruby (not JRuby, for now), in my personal projects I use Java. While I have written non-trivial apps in Groovy, I prefer Java, but I wonder if I should just get over it and do everything in Groovy. I like Java because I feel that static typing saves me time and aids refactoring. (No, I am not familiar with Scala.) However, I feel that this very empirical, on-topic programming question may inform my decision.
non-statically typed languages don't "scale" well in the maintenance sense. Up to a few tens of thousands of lines of code they are maintainable. Past that they just take more effort to maintain, re-factor or update. This is true of any of the non-static typed languages, Perl, Python, Groovy, Ruby etc. The tools for working with half a million lines of Python code vs the same number of lines of code in C/C++/Java just aren't there. Now it is true that Python is about 1/3 to 1/5 the number of lines of code as an equivalent Java program. So this is never going to be apples and oranges, but there is a cut off point where the number of lines of code in a non-static language will have diminishing returns on maintenance. And everyone knows that maintenance is where the true cost of a software project has always been.
Static typing still is a big thing.
While it has been argued over and over again and proponents of the dynamic approach say that the problems that dynamic typing bring can be reduced (or even eliminated) with sufficient unit tests.
I don't want to argue whether or not this argument is correct, so I'll assume that it is, for this answer.
In that case there is still one problem, which is that many shops don't have the procedures/know-how/rules/management to produce a sufficient number of high-quality unit tests.
And if I have to choose between dynamically typed code without unit tests and statically typed code without unit tests, I'll choose the statically typed one every day.
A similar issue exists with double dispatch:
In Groovy method calls are dispatched based on the actual types of the arguments at runtime (which is almost required, because the static type is unknown and/or Object most of the time). This means that there is no reliable way to know which method is called at any given point at the code, when faced with extensible class hierarchies.
Any code that calls a method with the signature foo(String) most of the time may suddenly call foo(Integer) or foo(SomethingElseEntirely) depending only on the actual type of the argument at runtime. In the Java language that can never happen, because the exact signature of the method to be called is decided at compile time.
Much like other "dynamic" language features, double dispatch is occasionally a very useful tool and the lack of it can produce some ugly constructs in Java, but it has its cost in that it makes it even harder to read, understand and reason about code.
Yes, obviously.
Why are companies still "willingly" using Java?
Because companies are inherently conservative. They don't change technologies because they're cool, or even groovy. They change, reluctantly, when there's a prudent reason to do so. Early adopters pay very heavy penalties for being early adopters.
Edit: this is not "inertia" in the pejorative sense, as in "no reason to avoid change except resistance to change", but in the sense of prudence. It is right for companies to not abandon what's working, until there's something that's provably better.
And not in the "makes developers happy because it's cool" sense of better, but in terms of more quickly and reliably meeting whatever business requirements drive development in the organization.
Java offers:
Large base of trained, experienced developers. It's hard enough finding people who are able to do software development well, without picking a language which hasn't been around as long. And training people in a new language is expensive, in both time and money.
Brand-name recognition and an easily proven track record of successfully completed projects. This is nothing to scoff at: if I tell upper management I'm beginning a project in some groovy new language they've never heard of, I have to educate them on it, and they'll rate that as a risk. With any "established" language, I can skip that step.
Well-established, mature support tools, and third-party support.
These advantages accrue to any comparison between a long-established language and a new one, not just Java and your list. I expect that one day, Groovy, et al, will be the established language, and there'll be people asking the same question about some newer, shinier language. This is the cycle. It's how it's been for longer than I've been in the business.
Aside from cases where performance is
a main decision factor, do
companies/developers still willingly
chose Java over Groovy, JRuby or
JPython?
Yes, and I believe the main reason is inertia, either on the part of the developer or the company:
Company: existing investment in Java (in terms of staff skills and infrastructure), the risks of change are perceived to outweigh the benefits
Developer: there are plenty of Java jobs available, so why bother learning another language?
Lack of available resources is probably another reason, though this is something of a chicken-and-egg problem (or a Mexican standoff, or a self-fulfilling prophecy, or something else). I imagine there are a lot of companies watching Groovy, Jython, etc. but waiting for them to become more widely adopted before taking the plunge. Obviously, by postponing adoption themselves, they're exacerbating this lack of resources problem.
Personal Aside
I spent the last year working as a Groovy/Grails developer. I recently changed jobs and am now working as a Java 1.4 developer and (compared to Groovy programming) it's about as pleasant as gouging your eyes out with a rusty spoon.
Static typing is great in that it facilitates compile-time checking and code analysis tools like FindBugs, but no way does it compensate for the massive amounts of (boilerplate) code it takes to accomplish the simplest of tasks when writing Java (particularly if you're using a version earlier than 1.5).
I can tell you what is going on in my company. Our current application is done in java, but we have started a transition to grails/groovy and this will most probably be the platform for the next generation of our products.
Since you are asking an empirical question, and I assume looking for empirical answers:
Aside from cases where performance is a main decision factor, do companies/developers still willingly chose Java over Groovy, JRuby or JPython?
Yes.
I don't think there is anything else to say.
I just started exploring Scala in my free time.
I have to say that so far I'm very impressed. Scala sits on top of the JVM, seamlessly integrates with existing Java code and has many features that Java doesn't.
Beyond learning a new language, what's the downside to switching over to Scala?
Well, the downside is that you have to be prepared for Scala to be a bit rough around the edges:
you'll get the odd cryptic Scala compiler internal error
the IDE support isn't quite as good as Java (neither is the debugging support)
there will be breaks to backwards compatibility in future releases (although these will be limited)
You also have to take some risk that Scala as a language will fizzle out.
That said, I don't think you'll look back! My experiences are positive overall; the IDE's are useable, you get used to what the cryptic compiler errors mean and, whilst your Scala codebase is small, a backwards-compatibility break is not a major hassle.
It's worth it for Option, the monad functionality of the collections, closures, the actors model, extractors, covariant types etc. It's an awesome language.
It's also of great personal benefit to be able to approach problems from a different angle, something that the above constructs allow and encourage.
Some of the downsides of Scala are not related at all to the relative youth of the language. After all, Scala, has about 5 years of age, and Java was very different 5 years into its own lifespan.
In particular, because Scala does not have the backing of an enterprise which considers it a strategic priority, the support resources for it are rather lacking. For example:
Lack of extensive tutorials
Inferior quality of the documentation
Non-existing localization of documentation
Native libraries (Scala uses Java or .NET libraries as base for their own)
Another important difference is due to how Sun saw Java and EPFL sees Scala. Sun saw Java as a product to get enterprise customers. EPFL sees Scala as a language intended to be a better language than existing ones, in some particular respects (OOxFunctional integration, and type system design, mostly).
As a consequence, where Sun made JVM glacially-stable, and Java fully backward compatible, with very slow deprecation and removal of features (actually, removal?), JAR files generated with one version of Scala won't work at all with other versions (a serious problem for third party libraries), and the language is constantly getting new features as well as actually removing deprecated ones, and so is Scala's library. The revision history for Scala 2.x, which I think is barely 3 years old, is impressive.
Finally, because of all of the above, third party support for Scala is incipient. But it's important to note, though, that JetBrains, which makes money out of selling the IntelliJ IDEA IDE, has supported Scala for quite some time, and keeps improving its support. That means, to me, that there is demand for third party support, and support is bound to increase.
I point to the book situation. One year ago there was no Scala book on the market. Right now there are two or three introductory Scala books on the market, about the same number of books should be out before the end of the year, and there is a book about a very important web framework based on Scala, Lift.
I bet we'll see a book about ESME not too far in the future, as well as books about Scala and concurrency. The publishing market has apparently reached the tipping point. Once that happens, enterprises will follow.
I was unshackled from the J2EE leash last year wanted to do something new after 12 years of Java in the enterprise building very large system for some of the worlds biggest companies.
I had tried Ruby on Rails in the past. After building a few sample apps I did not like the feel of it or the fact that I would have to write a ton of unit tests to cover stuff that is normally done by a compiler.
Groovy on Grails was my next port of call. I have to say I do like this but it suffers from the same dynamic typing problems as ROR. Don't get me wrong I am not putting Grails down as it is an excellent framework and I will still use it. Each has its own place IMO.
I then jumped on Scala and have now built a hybrid application based on Scala and Spring MVC. At first working with Scala is difficult but it gets easier and more productive the more time you put into it. I've reached a tipping point where I now want to invest time in Lift as well.
The combination of "Programming in Scala" and David Pollak's "Beginning Scala" books is good for learning the language, the latter with a less academic bent.
Scala is still young and has some way to go. I think it has a bright future and I see momentum is already picking up. Recently one of the creators of the Groovy language said in a blog post he would never have bothered designing Groovy if Scala had been around at the time.
I think some more work on better Java API integration/wrapping will give Scala the boost it needs to win more followers. The basic integration is there already but I think its could be polished a bit more.
Yes IDE support is there but it is basic at the moment. The powerfully refactoring support of Intellij is not there yet and I miss that a lot. The compiler + IDE support with a mix of of other plugins is not mature yet. I sometimes get very weird internal compiler errors caused by how Scala sits with JDO enhancement for the Goggle app engine. However these are little things that can be easily fixed. Early adaptation of new technologies and languages always comes with a little pain. But this bit of pain can produce great pleasure in the future.
If I look at the capabilities of Scala compared to early Java its miles ahead. When I moved from C++ to Java the JVM was not ready yet regarding scalability. There used to be lots of weird crash and burn JVM core dumps on various OSes. All of this has now been fixed in Java and the JVM is rock solid. Scals runs in the JVM so it has been given a massive head start on native platform integration. Its standing on the shoulders of giants!
After years of building and supporting enterprise applications my vote is for a language where a compiler can catch most of the non functional bugs before even unit tests are built. I love the type checking mixed with the power of functional programming. I like the fact that I am doing OO++.
I think the development community will decide if Scala is the future or not. The downside of adopting Scala now would be if it did not pick up momentum and adaptation. It would be very difficult to maintain an Scala code base with very few Scala developers around. However I watched Java come from the skunk works into the enterprise to replace C++ and it was all pushed from the bottom up by the developer community. Time will tell for Scala but currently it has my vote.
Beyond learning a new language, what's the downside to switching over
to Scala?
Thinking, thinking, thinking..... nope, there is none :-)
I'll tell you my little personal experience, and how I found that it wasn't so easy to integrate Scala with existing Java libraries:
I wanted to get started with something easy, and as I thought that Scala was very well suited for scientific computation I wanted to do a little wrapper around JAMA (Java Matrix library)... My initial approach was to extend the Matrix type with a Scala class and then overload the arithmetic operators and call the Java native methods, but:
The Matrix class doesn't provide a default constructor (without arguments)
The Scala class needs one primary constructor
I thought one good primary constructor could be the one accepting an Array[Array[Double]] (first thing that sucks, that syntax is much more verbose and hard to read than Double[][])
As far as I know by reading the manuals, the parameters of the primary constructor are also implicitly fields of the class, so I would end with one Array[Array[Double]] in the Scala subclass and another double[][] in the Java superclass, which is pretty redundant.
I think I could have used an empty primary constructor that initialized the superclass with some default values (for example, a [[0]]), or just make an adapter class that used the Jama.Matrix as a delegate, but if a language is supposed to be elegant and seamless integrated with another, that kind of things shouldn't happen.
Those are my two cents.
I don't think there are any downsides. Actually learning new language is very helpful for broadening your programming knowledge. You might gain from Scala such things as generic classes, variance annotations, upper and lower type bounds, inner classes and abstract types as object members, compound types, explicitly typed self references, views, and polymorphic methods.
It consistently breaks backwards compatibilty.
Community size is small.
IDE support isn't there yet.
Otherwise its fine.
It is just a young language, it will get there eventually.
Great for hobbyists, not ready for enterprise.
The two, by which I mean four, biggest downsides I'm seeing are:
Many working as developers in the professional community aren't trained and are unwilling to learn how to use a functional language, they won't even give it a go so they can understand why it's a better approach. This means you'll always be fighting an uphill battle getting adoption until it's mandated at the corporate level.
RDBMS integration is still a bit spotty. Plenty of solutions, but nothing that really sticks out as becoming a standard. For me though, this might be an advantage rather than a disadvantage. JPA2 is a mess and causes more issues than problems it solves. Hibernate criteria queries aren't much better.
IDE support is still lagging, but mostly in the area of debugging at this point. Code inspection is doing pretty good (at least in IntelliJ).
You'll never want to write another line of Java again! Likely you'll want to punch a wall or break something when forced back into the awkward syntax of Java.
The answers here are somewhat dated circa 2022 so I thought that I would contribute with an update. I have been working in a tech company that started using Scala at about the same time this question was originally asked. I recently blogged about lessons learned in that shop when trying to teach Java developers how to work with a code base written in idiomatic Scala so this topic is top-of-mind for me right now.
Just about all of the maturity issues in tooling, educational
collateral, and integration are gone. Version 2 of Scala is just as
rock solid a programming language as version 8 or 11 of Java.
Some of the most obvious advantages in switching to Scala are no longer
relevant because those language features have been added to newer
versions of Java.
Where Scala continues to outshine Java is in terms
of modularity and readability which affords idiomatic Scala as able
to handle code complexity better than Java.
That improved code scalability comes at the cost of a higher
learning curve which makes Scala less attractive to junior developers
who tend to make up the majority of your engineering group.
I'm in the process of reviewing a code base (~20K LOC) and trying to determine how to migrating it from 1.4.2 to 5. Obviously, it's not an overnight project and the suggestion which I have received is to write new code against Java 5 and migrate the old code in a piece-meal fashion. Also, I'm no expert in the new features in Java 5 (i.e. I know of them, but have never written any for production use).
My questions:
What features of Java 5 are typically used in production code? (i.e. generics, auto-boxing, etc.) Are there features to be avoided / not considered to be best-practices?
What are the best refactoring strategies which I can use migrate a code base of this size? (i.e. make changes to classes one at a time only when a class is edited, etc.) Objective - reduce risk on the code base. Limitation - resources to do refactoring.
Any advice is appreciated - thanks in advance.
UPDATE - a year too late, but better late than never? =)
Thank you for all of the comments - lots of great points of view. In the life of a software developer, there's always going to be the projects you strive to finish but never get around to because of something more "urgent".
With respect to the use of Java 5 (at that time), it was something which was required in the client's production environment, so that was why we did not use Java 6.
I found that the stronger typing for collections, enums and unboxing of primitives were the features I tend to apply the most, both to old and new code. The refactoring was fairly straight-forward, but code comprehension improved significantly and standards became easier to enforce. The ones I had the most trouble with was the generics; I think it's a concept which I still haven't had a chance to fully grasp and appreciate yet, so it was difficult for me to find previous cases where the application of generics was appropriate.
Thanks again to everyone who contributed to this thread and apologies for the late follow up.
Java 5 is almost completely backwards compatible with Java 4. Typically, the only change you must make when you migrate is to rename any usages of the new enum keyword in the Java 4 code.
The full list of potential compatibility problems is listed here:
http://java.sun.com/j2se/1.5.0/compatibility.html
The only other one that I've run into in practice is related to the change in the JAXP implementation. In our case, it simply meant removing xerces.jar from the classpath.
As far as refactoring goes, I think that migrating your collection classes to use the new strongly-typed generic versions and removing unnecessary casting is a good idea. But as another poster pointed out, changing to generic collections tends to work best if you work in vertical slices. Otherwise, you end up having to add casting to the code to make the generic types compatible with the non-generic types.
Another feature I like to use when I'm migrating code is the #Override annotation. It helps to catch inheritance problems when you're refactoring code.
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html
The new concurrency library is very useful if your code uses threading. For example, you may be able to replace home-grown thread pools with a ThreadPoolExecutor.
http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html#concurrency
I would definitely take the approach of updating the code as you change it during normal maintenance. Other than the compatibility issues, I don't think there is a compelling reason to use the new Java 5 features unless you're already changing the code for other reasons.
There is one very real issue with the "viral" nature of generics; once you start introducing them at a given layer in an architecture you generally want to introduce it at the layer above & below as well. I have found that introducing generics is probably best done in full "verticals". But you do not have to do all the verticals at once.
This is a really hard question to answer because it depends on what code will be affected and how critical that code is.
First and foremost, when migration is a nontrivial undertaking, do yourself a favour and upgrade to the latest version of Java, which would be Java 6 not Java 5. Java 6 has been out for a year and a half or more and is mature. There's no reason to not pick it over Java 5 (imho).
Secondly, like any software project, your goal should be to get something into production as soon as you possibly can. So you need to identify a slice of your system. The smaller the better, the more non-cdritical, the better.
The other thing to do is just try starting up your app under Java 6 and seeing what breaks. It might be worse than you expected. It might be much better.
The other thing you'll probably need to be aware of is that by the sounds of it you will have jars/libraries in your app that have since been deprecated. Some may not even be compatible with Java beyond 1.4.2. You will probably want to upgrade all of these to the latest version as well.
This will probably mean more stuff breaking but using old/deprecated APIs is just kicking the can down the street and causes you other problems.
There are exceptions to this where upgrading can have far-reaching consequences. Axis1 to Axis2 comes to mind. Those situations require more careful thought.
As for what features are used... all of them pretty much. I can't think of any that should be avoided off the top of my head.
Also, I just noticed the size of your project: ~20K LOC. That's actually quite small (eg I've written an app about that size in the last 3 months by myself).
Lastly, this also depends on how easily you will find things that break. If you have good unit test coverage then great. That's pretty rare though. If you can just run through the app and reliably find problems it's not too bad.
The problematic situations are where scenarios are hard to test and it's likely you won't uncover problems straight away. That calls for more caution.
You would want to migrate stuff that doesn't work in the transition from 1.4 to 5 (not sure what that would be), but I'd be wary of migrating stuff for the sake of it.
If you do take this route, some questions:
Do you have comprehensive test coverage ? If not, you should write unit tests for the code you're going to be migrating.
Do you have components that are widely used within your codebase ? If so, they are probably candidates to be migrated in terms of their API (e.g. using generics etc.)
In terms of what's widely used from Java 5. Generics is important and makes your life a lot easier. I don't see autoboxing too much, nor enums (this is all relative). Varargs almost never. Annotations are useful for frameworks, but I consume these. I don't think I've ever implemented one myself.
20 (non-comment) kloc should be small enough to insert generics with a big bang. Obviously make sure your code compiles an runs on Java SE 5 first. The relatively easy thing about generics is that adding them makes very little change to semantics (certain overloadings can change because of implicit cases - Iterator<char[]> iter; ... System.out.println(iter.next()); as a bad example off the top of my head).
Some cases adding generics will highlight conceptual problems with the code. Using one Map as two maps with disjoint key sets, for example. TreeMap is an example in the Java library where a single class has two distinct mode (using Comparator<T> or Comparable<T>).
Things like enhanced-for and auto-boxing are very local and can be added piecemeal. enums are rarer and might take some thinking about how you are actually going to use them.
I think you're going about this the wrong way. Your plan shouldn't be to update all current code to Java 1.5, your plan should be to ensure that all current code runs exactly the same in 1.5 as it did in 1.4.2, and that all future code written will work fine in 1.5.
I've gone through a few transitions like this of varied sized code bases. The goal was always to make sure we had a ton of unit tests so that we could easily plug in 1.5 and run our tests through it. We actually encountered about 10 problems, mostly related to regular expression libraries not supporting something or supporting something differently.
Write all new code in 1.5 then, and if you change an older class for whatever reason, spend a minute and implement generics, but there's no reason to refactor everything. That sounds a bit dangerous to me if you don't have the tests in place.
I'm about to port a smallish library from Java to Python and wanted some advice (smallish ~ a few thousand lines of code). I've studied the Java code a little, and noticed some design patterns that are common in both languages. However, there were definitely some Java-only idioms (singletons, etc) present that are generally not-well-received in Python-world.
I know at least one tool (j2py) exists that will turn a .java file into a .py file by walking the AST. Some initial experimentation yielded less than favorable results.
Should I even be considering using an automated tool to generate some code, or are the languages different enough that any tool would create enough re-work to have justified writing from scratch?
If tools aren't the devil, are there any besides j2py that can at least handle same-project import management? I don't expect any tool to match 3rd party libraries from one language to a substitute in another.
If it were me, I'd consider doing the work by hand. A couple thousand lines of code isn't a lot of code, and by rewriting it yourself (rather than translating it automatically), you'll be in a position to decide how to take advantage of Python idioms appropriately. (FWIW, I worked Java almost exclusively for 9 years, and I'm now working in Python, so I know the kind of translation you'd have to do.)
Code is always better the second time you write it anyway....
Plus a few thousand lines of Java can probably be translated into a few hundred of Python.
Have a look at Jython. It can fairly seamlessly integrate Python on top of Java, and provide access to Java libraries but still let you act on them dynamically.
Automatic translators (f2c, j2py, whatever) normally emit code you wouldn't want to touch by hand. This is fine when all you need to do is use the output (for example, if you have a C compiler and no Fortran compiler, f2c allows you to compile Fortran programs), but terrible when you need to do anything to the code afterwards. If you intend to use this as anything other than a black box, translate it by hand. At that size, it won't be too hard.
I would write it again by hand. I don't know of any automated tools that would generate non-disgusting looking Python, and having ported Java code to Python myself, I found the result was both higher quality than the original and considerably shorter.
You gain quality because Python is more expressive (for example, anonymous inner class MouseAdapters and the like go away in favor of simple first class functions), and you also gain the benefit of writing it a second time.
It also is considerably shorter: for example, 99% of getters/setters can just be left out in favor of directly accessing the fields. For the other 1% which actually do something you can use property().
However as David mentioned, if you don't ever need to read or maintain the code, an automatic translator would be fine.
Jython's not what you're looking for in the final solution, but it will make the porting go much smoother.
My approach would be:
If there are existing tests (unit or otherwise), rewrite them in Jython (using Python's unittest)
Write some characterization tests in Jython (tests that record the current behavior)
Start porting class by class:
For each class, subclass it in Jython and port the methods one by one, making the method in the superclass abstract
After each change, run the tests!
You'll now have working Jython code that hopefully has minimal dependencies on Java.
Run the tests in CPython and fix whatever's left.
Refactor - you'll want to Pythonify the code, probably simplifying it a lot with Python idioms. This is safe and easy because of the tests.
I've this in the past with great success.
I've used Java2Python. It's not too bad, you still need to understand the code as it doesn't do everything correctly, but it does help.