tags:

views:

311

answers:

7

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.

+8  A: 

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.)

Brian Clapper
+5  A: 

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.

Soviut
From what I understand about Jython, I don't know that it would help. I'm trying to go in the opposite direction (taking a Java library and making it available to Python code). Can Jython actually do that? Or is it just used for running Py code on top of Java?
Mike Griffith
You can import Java libraries and use them from within a Python script, so yes, Jython might be useful.
Kiv
I know that IronPython allows you to use Python modules in C#.
Soviut
+6  A: 

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.

rhettg
+1: This will be "aggressive" refactoring, the best kind.
S.Lott
It depends on how heavily-used the library is, how well it's documented, how easy it will be to test the replacement. (Like, what if heavy library users have written code that relies on a defect that your refactoring fixes?) Rewriting is my first instinct too, but I'm often wrong.
Robert Rossney
+3  A: 

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.

David Thornley
+2  A: 

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.

Kiv
+2  A: 

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:

  1. If there are existing tests (unit or otherwise), rewrite them in Jython (using Python's unittest)
  2. Write some characterization tests in Jython (tests that record the current behavior)
  3. 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!
  4. You'll now have working Jython code that hopefully has minimal dependencies on Java.
  5. Run the tests in CPython and fix whatever's left.
  6. 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.

orip
A: 

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.

Stuart Axon