Ask HN: Enterprise Java guy needs advice on what to transition to

40 points by rlawson ↗ HN
I have made my living doing Java enterprise development for big companies for the past 10+ years. I can sense the world is changing (much like when I transitioned from C/C++ to Java) and that I need to make a change. Frankly I am tired of all the complexity and over engineering of enterprise Java. For all the effort, I find most apps are large (1+ MLOC), monolithic, hard to understand and maintained by large groups of onshore/offshore resources who just keep the stuff running by sheer numbers and have no pride in their craft. I want to do something better as I still have about 20 years left in my working life. I have played around with Python and like it but not sure how it will scale up to a large project. Any advice appreciated, especially from those who have already made the transition.

56 comments

[ 2.0 ms ] story [ 107 ms ] thread
Given your Java background, and that you want something more simple you could give a try to the Play! Framework, and you could try to learn Scala.
There is plenty of work doing GWT+(Spring|Guice) apps in areas more interesting than traditional enterprise Java.

Also, there are a lot of interesting infrastructure projects written in Java (Hadoop, Lucene, Cassandra etc). It's pretty easy to get started in any of them.

If you really want to do a new language then I doubt you'll find many people arguing against Python. But the real action is in Javascript (both server & clientside)

Given that you know Java, you could consider transition to Android - it is a lot simpler than enterprise Java (because it has to run on a phone) and most of the APIs have been reworked.

But then that is just me.

Seconded, and extended to languages for other mobile devices. Since most things are (unfortunately) web-centric nowadays, it's a relatively safe bet that knowing how to throw code for smart-phones and tablets will keep you employed (and entertained!) for at least the next decade.
Since most things are (unfortunately) web-centric nowadays

Disagreed. Theres much more that needs to be programmed. Think of devices, health information systems, traffic routing etc.

"Most things are web nowadays" is often said, but just wrong.

Good point, I like the idea that the device limitations enforce a certain simplicity on your design
I work in iphone development as a team lead for software tied to the enterprise stack. The backend/webservice is on the .net platform. We have an android team as well. We cannot for the life of us, find developers with deep backgrounds in software for android. Mainly beginners and entry level types. In the mobile space, I am sure there are companies on the java enterprise stack looking for android developers. The mobile apps space has been lots of fun. Pays well and demand is growing. Look into it:)
Hire them now and in two years you will have somebody with deep understanding of mobile development.
I would suggest experimenting with Groovy/Grails on some weekend projects. Grails is similar to Rails so you could easily leverage this knowledge if you ever wanted to move to RoR.

Beyond that I would agree with earlier commentators that the real action over the next few years will be in JavaScript. Both server and clientside. The former being particularly interesting.

What do you want to do? What do you want to build? What gets you excited?

Try various things, and pick one that actually gets you excited, and makes you think "wow, this is so cool" - not something that makes you think "well, the market seems to be moving in this direction, so there'll probably be decent money there".

I've done a ton of spring / hibernate enterprisey stuff and am now focusing on iOS and Android development.

For one off stuff I usually use ruby nowadays, and if mobile would not be my thing, I'd definitely be delving in to Rails (have some previous experience here) and Node.js.

I've done some projects in Django but didn't really dig that as much. There's a ton of Python frameworks out there though, and Python the language is pretty cool to work with and a breath of fresh air if Java has been your mainstay for the last decade.

Delicious Bookmarking site I believe is Django/Python

As far as scaling to a big enterprise project, not sure yet.

Given your java background have you compared groovy/scala/erlang to python yet?

While I do code android applications I am going through the same evaluation process for my server side development.

Groovy is nice in that I get to re-use Spring/Hibernate EJB, etc while having the features of an object oriented scripting language DSL and Grails has a good set of MVC features.

Python seems a little rough if you are re-using legacy java however jython does function and I guess one could build up jython stuff to handle legacy java enterprise.

Scala and Erlang seem interesting both attempting to solve same and similar problems in different ways implementation language wise.

Zed Shaw has some notes on enterprise coding with python, which are worth a read. I would also not rule out new C++ frameworks as Google still uses a lot of C++ in enterprise with good results.

>I have played around with Python and like it but not sure how it will scale up to a large project.

If by scaling you mean how to organize a large codebase, IMO, it is not hard at all and usually the python codebase is much smaller than a similar java project.

Start with Scala. Then try Play! and such. Also look at GWT. And do iOS. Much better job market than Python etc. http://blog.getgush.com/

I'd stay away from Groovy etc.

Also, please get over that "scaling" stuff. PHP scales just fine. Rails scales just fine. Python scales just fine.

Why stay away from Groovy?
The Java programmers I know consider it bloaty and oldskool.
Well you've probably got Java down pat by now, try something new that will put bread on the table. Learn Ruby and Ruby on Rails.

This should get you away from the overengineering that Java seems to attract and there are plenty of Rails jobs out there (certainly more than there are Grails jobs anyway).

Whilst you are at it pick up some new technologies such as mongodb.

It would be good for your soul (and skill as a programmer) to try something new, completely new. You could of course also learn ObjectiveC++ and become an iPhone developer. Whatever you pick make sure that it puts fear in your heart, something that will challenge you. A mountain to climb rather than molehill.

The future in the next 20 years is mobile development. Currently, for software on the actually device that means Objective-C for iOS(iPhone) development, or Java for Android. Of course, HTML5 and CSS3 are going to important for web pages viewed on the device. Find something you like in this area and stick with it!
I just wanted to reply "20 years?! Realy! Very bold prediction", but then I thught to myself - if someone said in 1991 that the future in the next 20 years would be web... he would have been right... interesting, isn't it.
(comment deleted)
I have a similar background and am also working as enterprise Java Dev. Financially, I don't think that it is a smart idea to transition at the moment (at least in germany, where I live). Java developers still seem to have the highest salaries, the most job offers and the best outlook in general.

There are various interesting technologies that COULD replace Java or at least JEE in the future, and it is certainly a good idea to learn them or do projects in your spare time. But beside Java, I don't think that there is any technology that you can be sure that it will be still around in 5-10 years.

If you are just sick of Java and need some change, then try to find a new job where you can work with whatever you like. Java changes pretty slowly, and you can still change your mind a few years later and find a Java job. But if you need to decide for a language as a career-choice, stick with Java, at least for a few more years.

Here's my take, but keep in mind that I've never worked with programming, I'm just a hobby programmer for now.

I don't really see why you have to bind yourself so hard to a language/platform/whatever. You don't have to be a "Java programmer" or a "Python programmer". Instead aim to become someone who can move around and choose whatever is best for the job, or whatever the job might require. In the end it's just programming, different types of programming sure but never forget that you're basically doing the same thing in a different way. When you see that you realize languages are just tools for you to use, not the other way around.

The first step IMO would be to expand your horizon, see what else is out there. Try out the exotic languages you see everyone rave about, give Python a blast or drive Ruby for a while. Do things in Erlang or Haskell just because it's different from Java and mix web development with low level or simply make a game or a program you've always needed.

When you know what's out there, when you've gotten your feet wet, then you can focus in on something a bit more. The thing that has kept my interest in programming alive is I've always done what's fun, and I can only imagine that's even more important for someone with 10+ in the business actually working with it. So choose something you feel is fun, oddly for me the funniest things are the new and different stuff (Haskell for example).

Long story short: Don't be an "X programmer", be a "programmer" and go where the fun is!

Best of luck to you.

I switched to Groovy/Grails a couple of years ago and haven't looked back. Lots of fun to work with, and allows me to reuse my previous knowledge base.

In addition to reusing my previous expertise, there are four thing I really like about it:

* Convention over Configuration makes things so much simpler * Groovy Language has a lot of great features, allowing for much more concise code (though it does take some time to get used to dynamic typing) * Plugin ecosystem - over 500 plugins on various topics allow you to get things done much quicker. The plugin architecture is wonderful and allows you to compose your from reusable blocks, which could have their own UI. Best actual (as oppoed to theoretical) code reusability I've ever seen * GORM (object relational mapper) is a thing of beauty. It's fairly implementation-agnostic, so you can use it with Relational DBs, switch to Mongo or Reddis as the persistence backend fairly easily.

Definitely recommend you check it out. In terms of jobs, it's not as big of a community as Java yet, but I definitely see many jobs advertising those skills.

I couldn't agree more. For most projects today, Java is severe overkill where a more high level language is better suited. While I'm not a fan of the Java language, the Java platform is rock solid and we can all agree it's not going away anytime soon.

I'd recommend taking a look at JRuby. It works nicely with Java libraries and loading Java classes. You don't have to deal with dependency injection. Variables aren't typed, values are. Class and instance methods are managed in the same class declaration. Classes can be easily extended. Classes are loaded into constants at runtime - instance objects are created (and constructor called) by calling the "new" method on a class constant (hence no dependency injection required). Class methods can't be called by an instance objects and vice versa.

While JRuby would be new to you, it's on a familiar platform. http://jruby.org/

I've been thinking about DI in Ruby, and I've been trying to think of how I'd deal with the absence of DI in Rails. Here's a scenario...

Suppose you have two different ways of gaining information about a logged in user. Let's say one goes to LDAP, and the other goes to an RDBMS. You'll be using one or the other depending on where the software is installed.

So in Java, you create an interface that defines the methods you'd need to identify and retrieve a User, and you write an LDAP and an RDBMS implementation. The code deals only with the interface, never the implementation directly. So if you want to switch them, you just create a setter (assuming we're using setter injection) and notify your DI container of which implementation should be injected.

I definitely get it that in a language with duck typing, there's no need for the interface/implementation gymnastics. You can just pass whatever class you want, and as long as it responds to those method calls, you're golden. So in that sense, DI isn't really an issue.

But what about the nice decoupling you get - is there any easy way to swap out a particular implementation in Rails? I'm trying not to think too much in Java here, it's more of a general problem, definitely doesn't mean I'd necessarily want to force DI onto a language that takes a completely different approach to things...

Sorry to get so technical here, just seems like you might have some insights into this.

Your question is more in regards to Ruby itself, and not Rails. You don't have to swap out implementations in Ruby.

Implementations aside, when you do DI in Java, it serves two purposes: 1) instantiates an object and 2) wires it into another object. Remember that in Java, each class is in it's own file. In ruby, you can break classes into several files, but you don't have to. Ruby simply reads class declarations at runtime and instantiates those classes into constants. This means that your classes are always available. If you've defined a class method, you can call SomeClass.some_class_method. If you want to work with an instance of that class, you would call SomeClass.new - to which you can pass args to a constructor.

In your instance, you could have three classes - User, UserLdap, and UserDb. You might call User.find( person ), and in the find method you would test your conditional on whether to use UserLdap or UserDb. If you had common methods you wanted to share between the two, you could place those in User and extend that class for use with an instance object. Another option for sharing methods cold be to place them in a module, which you can then include in your class.

It's hard for me the make a recommendation for your specific problem at hand. My best advice is to read up and Ruby a little and begin to put what you learn into practice. Here's a couple of recommendations:

http://www.humblelittlerubybook.com/

http://mislav.uniqpath.com/poignant-guide/

My light bulb moments were realizing that all class declarations are loaded as constants at runtime and class & instance methods are also managed in the same class declaration. HTH.

Thanks for your reply...

I'm kind of following you - unfortunately, I don't know ruby well enough to understand what you mean when you say class declarations are loaded as constants at run time, but I'll definitely look into it.

I think there's a third purpose to DI that you didn't mention. The container does instantiate an object and inject it ("wire it") into another object, but the real benefit is that you can externally configure which object to swap in. That last part might matter less in a language that doesn't have to be compiled but it can still be valuable if you have a lot of different implementations that need to be swapped in/out in different deployments.

The method you described for person - testing a conditional - do you mean you'd create a method with a conditional, and choose which implementation to use based on that conditional? I've done this, and it certainly works, but it isn't really a placement for DI (this sounds more like a factory method, though again I don't think that those really exist to the same extent in ruby since duck typing is much more flexible than static typing). My problem with this approach (if I understand it right, which I'm not sure I do) is that this would lead to a very long series of conditionals to load the right class. In rails, I'd probably be looking to pull them out into a yaml file (something like the applicationContext file in Spring).

"class declarations are loaded as constants at run time"

Let's say I create a class called User. When ruby sees that declaration, it creates a constant called User to contain that object. When I create a new instance:

user = User.new

"User" is a constant whose value is the object/class. "new" is a method that calls the constructor (if one exists) and creates a new instance. The same applies when you call something like:

User.find

You're not calling find() on an instance, you're calling it on the object that's loaded into the constant "User". The class declaration "class User" is saying User is the name of the class; User is also the constant in which it's stored. It's also what allows you to reopen a class on the fly to extend it with more methods.

"I think there's a third purpose to DI that you didn't mention. The container does instantiate an object and inject it ("wire it") into another object, but the real benefit is that you can externally configure which object to swap in."

True, but I've never found myself switching objects out on a regular basis.

As you mentioned, the conditional approach probably isn't the best. What I'm assuming now is that you're based on your deployment, you might use a different bean factory configuration file? And this works as long as UserLdap and UserDb implement the same interface?

That being said, instead of sprinkling conditionals throughout user, you can dynamically assign User initially.

User = UserDb

OR

User = UserLdap

and as long as UserDb or UserLdap had a find() method, you could then call

User.find

Remember, User is now a constant that references the same value as UserDb or UserLdap

Does that help clarify?

Responding very late, sorry...

It does help clarify this, thanks. It does still leave the problem that you have to specify the "type" in the code and can't swap it out. That said, I think this could probably be handled easily with a yaml file (just specify the class you want to instantiate every time a user is created)? I may try that some time.

Look into JRuby and Ruby on Rails.

You'll get a fun development environment, a less formal language. The big plus for you is that JRuby has wonderful Java integration, so you'll be able to use all the Java libraries and infrastructure you've learnt over the years where they make sense for your project.

As a recovering java enterprise developer I'd say pick a small project you are interested in and another language you are not familiar with and try it out. I found ruby an easier transition from java than python, Go might be interesting for you if you are coming from c++. Just make a small app in your free time and realize that a ridiculous number of startups these days have code bases measured in thousands of lines of code rather than millions. It is wonderful to live in a world where you can hope to understand the whole system.
> Go might be interesting for you if you are coming from c++

Go might be more interesting if you are coming from C. Go and C++ are pretty much antithetical.

For some reason Go also seems to interest people coming from Ruby.

It all comes down to what kind of software you intend to make (and frankly, who you intend to make it for). If you want to write a 3D video game, Python and Ruby aren't exactly your best bet for example. Likewise, if you're inside some company with a JVM mandate, your options can be limited as well. I can only comment on web app development since that's what I do most. My advice would be to pick up Ruby (and Rails) or Python (and Django). You might also try out Scala. Lift appears to be a pretty nice alternative to the morass of heavy Java web frameworks, though it's much less mature than something like Django or Rails. Coming from Ruby and Python though, when I work in Scala, it still feels a tiny bit heavy to me. I think for you, a clean break from the Java world sounds like it's what you need.

Managing a substantial Python (or Ruby) project is easier than you'd imagine because there is so much less code and configuration. There is also less "architecture astronautism" with all the layers of abstraction hiding what's really going on. You can still have some of that, but in my experience, it's pretty rare.

The biggest issue when stepping outside the JVM (in my opinion anyway), is dependency management. The libraries you want may often not be pure Python or Ruby, but have C/C++ stuff in there too. This can make setting up an environment on multiple OS platforms tricky, since you need to install (and maybe even compile) all that stuff. There's something to be said for throwing a jar on a classpath and being done. However, I suspect you'll find these languages cut development time so much that you're still ahead of the game after burning a little extra time installing some dependencies.

Performance-wise, both Python and Ruby are probably "fast enough", certainly when developing apps that are not used by large numbers (i.e. web-scale numbers) of people. Internal apps in particular run perfectly fine with no exotic caching, partitioning, parallelization, etc... There are also plenty of companies out there that operate very busy, successful public websites with both Ruby and Python, so in general, the performance should be the least of your worries. Obviously, if you're looking to do scientific simulation or some other compute-heavy work, your mileage may vary.

Editors are another thing that trip people up going to Ruby and Python from Java. Take my advice: ditch your IDE and use a regular text editor with syntax highlighting. There's no way I write Java code without an IDE, but for languages like Ruby and Python, it's not necessary and the IDE just gets in the way. Keeping an interpreter window open when dealing with a library you haven't used before is far more productive. You can create some fake classes, try out some methods, and once you have a feel for the thing, move over to your editor and code up what you want. That beats the pants off autocomplete any day (and the inevitable compile, run, test cycle that goes with it).

EDIT: Oh, and learn JavaScript if you don't already know it. It's only going to get more important.

I'm surprised that more people haven't mentioned javascript as a new language to get into. Becoming an expert at it looks like it could become extremely valuable very quickly, simply because it's everywhere on the web now. It doesn't matter what backend a site has, 'every' client is using javascript.
Frankly I am tired of all the complexity and over engineering of enterprise Java. For all the effort, I find most apps are large (1+ MLOC), monolithic, hard to understand and maintained by large groups of onshore/offshore resources who just keep the stuff running by sheer numbers and have no pride in their craft.

If this is the type of thing you want to move away from, then I don't think that the problem is teams that use Java - the problem seems to be working for large enterprises.

I suggest that as a first step, ignore any questions of language/platforms/tools and instead think about what type of company you would like to be working for: a small start-up, a more-established medium size business, etc. Do you want to work in a place where the primary business product is software (i.e. a software development company), a place where software is something that is done in support of the primary product being sold, or are you interested in consulting for others?

Once you decide what type of environment you'd like to work in, then the rest of the decisions follow naturally from that.

As a single anecdote, I work for a medium-to-large software-as-a-service company business where most of our work is in Java, but we are very far from the notion of monolithic apps with 1M LOC and offshore teams.

The language/tools are not the problem, it's the people/organization.

this is a good insight, thank you
> The language/tools are not the problem, it's the people/organization.

The language is a problem, because Java was specially created for this type of organizations. And it is not surprising that Java attracts this type of people (fungible crowds having no pride in their craft).

I disagree that it's possible to paint all developers using this language with such a broad brush. By this notion everyone that uses Rails loves being a "ninja" and monkey patching.
My comment was about the language, not the people. I have no doubt that there are many good programmers who use Java.

But I'm not sure one can be a good programmer if Java (or any other mediocre language) is the only thing she knows.

As others have mentioned, migrating to something else on the JVM first will allow you to reuse some of the skills/knowledge you have while you gradually focus on the 'new' aspects of something else.

JRuby and Jython are both good stepping stones to ruby and python, which would give you an idea of if you want to head in those directions full time.

I'm partial to Groovy myself, and I'd consider it more a superset of Java (though technically its not). You can reuse as much or as little of Java as you want - even in the same file - while picking up the new idioms.

Groovy, JRuby and Jython will all help you dispense with much of the boilerplate cruft you see in traditional Java, without giving up the power/libraries you're used to. And they all have good webstacks (Grails, Rails, Django, for example).

Moving off the JVM, if you're looking in to web work, PHP - as much as it has a bad rep in certain quarters - is where a lot of work is. The code quality of projects you may find tends to be hit or miss, but it's certainly possible to write clean, elegant and scalable code in PHP (and I've seen some pretty piss-poor rails in my day as well - nothing's perfect). Have you considered looking at .NET as well?

As someone else said, the 'scalable' thing - don't fret about it. Anything is scalable, and each platform will have different techniques - they all have pros and cons, which may not always be apparent until you dig more deeply in to the constraints of a particular language or platform.

Find a couple platforms that are of some interest, and focus on finding some communities for those platforms (Django, Rails, Zend Framework, Grails, ASP.NET, whatever). Getting a feel for how the community thinks about problems, what they focus on (features, security, etc) will give you a sense of what you're comfortable with.

>"I have played around with Python and like it but not sure how it will scale up to a large project."

Which is more important - a new language or a new career path? In other words, would "Enterprise Python" or "YC Java" provide more of the change you are seeking? From your post, I get the sense it is the latter. Good luck.

Mobile markets are going to explode over the next few years. There's a lot of potential growth there and mobile developers are in high demand. But the best would probably be to try making your own app and become an entrepreneur. You should start with Android since you already know Java.