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.
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).
But I'm not sure one can be a good programmer if Java (or any other mediocre language) is the only thing she knows.
But then that is just me.
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.
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.
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'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.
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.
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".
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.
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.
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.
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/
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.
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.
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).
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?
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.
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.
So... don't blame Java for poor architects or poor engineering/business leadership...
(And, btw, I'd love to talk to you if you are in the Boston area.)
Sorry I'd like to meet up but in sunny South Carolina (go gamecocks !)
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.
Groovy + Grails is a great platform and it feels like a grasp of fresh air, but there is also Clojure (with an emerging ecosystem), JRuby (and you can run Rails on it), Jython and Scala to name a few other options.
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)
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.
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.
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.
everything you've heard about it is true. its great, and the learning curve for someone who isn't a cut-and-paste coder is small. i made the same switch a while ago, java/c to ruby, and it was like a weight lifted off my shoulders.
The thing is, I used to like Java. While I've been mainly interested in Ruby/Rails for personal projects, I've had to keep coding in Java for my work, and I've started to hate it too. But there are a lot of things I still like and miss about it, including moments when I think I'd actually still choose to use Java for a project.
Looking back, I think my enjoyment of Java ended around 2005, which was when Servlets and JSP were replaced with Struts, Spring, and Hibernate. I know a lot of people felt this was a huge improvement over the original EJB, but personally, I was astonished that people thought Spring, Struts, and Hibernate were "lightweight" (I never even bothered with EJB). While these frameworks have improved greatly and aren't nearly as hard to use as they were a while back, but I still don't like coding in them.
I think I miss the "recipe" approach prevalent prior to 2005, where you stuck closer to the "low level" servlet/jdbc approach, and you either brought in a new library for a specific task, or decided to write the code yourself. It was a bit laborious, but there wasn't much you couldn't do if you were willing to do a lot of typing. This approach seems to be an evolutionary dead end now - people generally start their projects in a framework (rails, django, spring), and stay within it for the remainder of the project. So there isn't really any point to a servlet "cookbook" anymore. It's either a Spring cookbook, or a Struts cookbook...
I think some new technologies have made Java more enjoyable - especially Maven, but I felt that Spring made Java far less enjoyable. It's a personal opinion, but to get a sense of it, I recommend you try working through the SpringMVC tutorial on the SpringSource site. Like I said, this is pretty much just a personal preference of mine - if, after doing the tutorial, this seems like a great way to write web apps, then by all means, go for it. But personally, I can't stand it.
I've been wondering if maybe there's a niche out there for people who like to use java at the low level. The funny thing is, I obviously do like frameworks, since I'm pretty enthusiastic about Rails. I think that it's just that if I'm going to use Java instead of Rails, then obviously there's a reason, and it's probably because my tasks are taking me outside the normal operations of a framework.
I think this comes down to wanting to be either at a very effective and efficient high level of abstraction, or wanting to get down into the grit of the problem and be able to do anything. While there was a time that it would have seemed funny to refer to anything Java related as "low level", pure servlets and jdbc seem to be taking that role in the middle tier (not just within SpringMVC or JPA/Hibernate, even non-java languages seem to be compiling to Java to run on the JVM).
Ok, this is a long rant, maybe it should have been a separate post completely. It just seems like we're in the same spot, and I want to ask you - do you think you might enjoy Java more if you dropped back from the enterprise-framework thing and started using it where (in my opinion) it still excels, the "low-ish" level of the middle tier? I wonder if other people are starting to feel the same way I do about this - that Java has its place, but when it does, your probably going to want to be going in as low level as you can with the language - otherwise, you'd be using something else.
What do you think about my other suggestion - dropping back to a lower level of code for java applications? I don't think the servlet/jsp approach is anywhere near as hard to learn, and I think it can be effective. As for not reinventing the wheel... well, I'm all for bringing in components incrementally as you need them - MVC, web service APIs, DI containers.
What do you think - could Java be more popular if the "java community" embraced the lower level approach, starting with Servlets/JDBC, and leaned toward gradual integration of technologies as needed? (I know, it's hard to speak of a "community", it's really just a collection of individuals, but it seems like the overwhelming thrust of the Java world has been starting within frameworks that add tremendous overhead at the start and actually sometimes become a hinderance as the app grows).
Almost everyone using Spring for DI seems to be leaning toward Spring MVC these days, probably because they don't want to do too much pick-and-choosing. And the default choice for a DI framework seems to be Spring as well, which means a Java programmer is now a Spring programmer.
This is probably why the "java cookbook" style books haven't been updated since 2004. They're treated as an evolutionary dead end, though I don't think they should be.
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.
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.