Hate Java? Maybe you should hate the industries stuck in the 50's.
blog.jelastic.com
blog.jelastic.com
- the usage of XML (or now: annotations) to configure all of the tiny parameters that nobody really cares about
- a class hierarchy in which you have to jump to 20 levels of inheritance to get to where you want to go
- that a lot of Java developers aren't able to compile their application outside of Eclipse
- that people build in "flexibility" in form of factory methods but at the same time only have the factory only build the same thing over and over again
- that setting up java projects is usually an unpleasant experience with way to much work if you only want the basic functionality because there are no sane defaults
- that there is no proper package management for libraries (similar to something like 'gems' in Ruby)
- that all of the concepts that the language is missing was 'patched' in using reflection, injection and annotations
- that the language just seems stuck (for how long did the Java community talk about Lambdas by now?)
- that most Java libraries don't seem to be able to provide a simple example (compare to ruby, examples on the front page: nokogiri.org, sinatrarb.com)
It seemed to download the whole internet and POM files are using everybody's favorite configuration language: XML
To make sure I have the right version of my libraries I use bundler
To make sure I have the right version of my code I use git
To make sure I have the right version of other applications I use chef.
Has worked fine for me so far...
I guess it's the usual unix philosophy where each tool does a single job and does it well.
But let me explain how useful this actually is.
When working on a Java project with a team of people, we usually use Maven and some CI tool like Jenkins or Bamboo. People commit code, Jenkins run a Maven build and then either Jenkins or Maven uploads build artifacts to a central repository.
Artifacts usually are: the jar/war/ear file, the -src.jar and the -javadoc.jar.
If code is finished then it will be a x.y release, otherwise it will be uploaded as something like 1.0-SNAPSHOT. Snapshots are usually timestamped.
Now I have a standard place where other projects can find dependencies, where the ops team can grab releases, where developers can find dependencies, code and documentation.
Three extra lines in a pom.xml and you get all that. Your IDE now picks it up and keeps it up to date. You can click/hotkey on anything and it will show source or documentation.
You call it pollution, I call it a great and pretty much completely automatic infrastructure that makes development so much easier.
If you're using Eclipse and Maven plugin, the beauty is that when you hit a shortcut key to navigate to either the Definition or the Implementation of 3rd-party open source library, the Maven plugin will download the source code for you and voila, no configuration or anything like that needs to be done with Eclipse (telling Eclipse where the path, etc).
It's powerful.
I see it this way:
First we had bash and make and ability to do almost everything (run other programs, ...) by using the right thing/language for the job. There was only lack of the functions to deal with Java builds and package management.
Then we had Ant, XML programming language with very limited possibilites (I don't regard targets as a feature). But at least we could express what we wanted.
Then we had Maven. If we needed something special we need to add it to sequence of build plugins (in several hardcoded build phases). Mostly we resort to do things in Ant plugin.
This is why I hate Java. Because of such idiocy.
If there's really some step that needs to be done in your builds that isn't covered by the existing plugins, you can write your own (it's not hard) and then at least that step is happening in a structured, testable way. But if you're doing something unique to a single project, you shouldn't be doing it in the build system.
No, actually, builds can get very unique in multi-language systems or in embedded systems... believe me. =)
Anyway ant is for builds, Maven is for dependencies.
For me the main point of Maven is that you keep things simple and standard. By not deviating from a standard Maven web project structure and avoiding dependencies or build phases that need special care, I have projects that are simple to develop, build and package.
I am trying very hard to just depend on good behaving Maven dependencies and to stick to simple solutions. No more special build phases for code generation, no more crazy stuff. If I need some special build phase then I am probably doing it wrong.
The result of that is also that my projects are super simple. By avoiding special build phases I can pretty much load up a project in any IDE and just hit Run.
To me that is the true power of Maven. For that reason I don't want to look back at Ant or any of the fancy super flexible Groovy/Scala/Ruby build tools.
So contrary what many people think, Maven forces you to keep things simple. And I think that is a good thing in any project :)
Forcing you to something is anything but good.
This is absolutely why I left Java development. Maven in my mind is anything but simple. It was always frustrating to use - this was 2.0 mind you, so maybe things have become easier, but I doubt it.
Even the terminology is totally abstract and complicated. I built a big project for a well known bank around '05-'06 and we had all kinds of problems with maven - we just went back to ant.
I used to love Java in the late 90's/early 00's. I remember the resistance to doing projects with it - it was new, unproven, etc, etc - just like Language X today. I worked with some people who built some cool things with 1.2. The collections framework was great.
But, then all the enterprise stuff started creeping in and everything was configured with gobs of crap xml. Demos would be given where you could edit the configuration via gui tools, but none of the devs I knew did this. Everyone hand edited everything.
Things like maven with their overly abstracted naming and concepts and Spring where everything is 'wired up' by tons of xml are what ultimately drove me away from Java. I just wanted to spend my time working on features instead of configuring things.
My experience is that people try to force Maven to be Ant. In particular, they want a single build to build all of the dependencies in one go. While this can bedone, my experience has been it makes a lot more sense just to keep each of your dependencies a separate project without trying to build everything all at once. It also encourages to build interfaces that change little instead of tying everything together.
A + Config -> B -> C -> D -> E -> Compiled
Maybe you could have decision points in the compilation flow depending on config parameters, system parameters, making it a tree, but I don't see why a build tool couldn't make those decisions based on the configuration provided. Essentially, I envision a build tool that takes in a huge number of arguments (maybe reads them from an XML/JSON/whatever config file) with sane sets of defaults for each.
(Forgive me if all this seems naive, it most likely is. I want to know why.)
That's pretty much how maven works. A typical java project will have an xml file listing its name and version, the names and versions of all its dependencies, a scm URL for tagging releases and that's basically it. The problem is people who have got used to having all the freedom of calling arbitrary shell programs at any point in the build process; it's very easy to accrete a series of small hacks ("oh I'll just sed this file here to fix that") that add up to something incomprehensible.
1) Maven doesn't generate an equivalent of Bundler's lock file. It resolves the versions to be used on each build. If you have dependencies on snapshot versions then there's no way to ensure that all developers are using the same snapshot. OK, you can always specify versions explicitly, but then you lose the benefits of snapshots etc. Bundler's lock file allows you to easily check for newer versions(a gem at a time if you like) without losing reproducible builds.
2) Developers can't upload their jars to the central maven repository. There are gatekeepers. This means that the latest versions of many projects aren't in the central repository. For those projects you have to use their own specific repository. This leads to problem 3. With rubygems developers can upload gems straight into rubygems.org. Also, because most projects are in github and you can specify git dependencies with Bundler you're able to depend on any version of a project(regardless of whether or not it's been released to rubygems.org), all the way down to the commit level.
3) 3rd party repositories change and can be unreliable. This means a jar can become unavailable without any notice. In practice the only way to guard against this is to use a proxy repository like nexus or artifactory, yay, another server to maintain...
2) Gatekeepers have their advantages; how you run a repository is pretty independent of the build tool. It would be possible to start a "anyone can upload anything" maven repository if this was thought useful.
3) Surely the notion of having your build depend on a random third-party git repository is far more worrying than depending on a random third-party maven repository - wouldn't you need to set up a git mirror server, which is more effort than nexus or artifactory?
1) The problem is that until you lock down the dependencies you can never be sure exactly which versions will be used. When you use bundler it generates a file specifying all of the versions that should be used. This gets checked into your repository so everyone is sharing exactly the same versions. This means you don't get situations where you check some code in and you break the build because the build server has downloaded a newer version of a dependency(used to happen a lot for me).
2) It's true it would be possible to start a "anyone can upload anything" repository. Having seen how well rubygems.org works in this scenario I think the java community should really get one organised. Either by enhancing the central maven repository or replacing it entirely(it's always been damn slow to browse anyway).
3) In my experience Github projects tend to be pretty persistent, if you have any concerns though you can always hit the fork button and depend on that. Having said that, using git dependencies is definitely the plan B option.
So how's this different from using non-snapshot dependencies in maven? You mentioned checking for new versions as an advantage for bundler, but you can do that with a single command in maven.
It just grabs your project's dependencies and probably some extra stuff the first time you use maven.
This is not really different from python or ruby build systems.
- Java reperesents a way of thinking where all languages issues are fixed in the IDE. A thinking which enables the language itself to grow in all the wrong directions.
Its not so much that that is always a bad thing. But if the usability of a language is so dependend upon and designed for an IDE, that IDE really should be part of the language design.
When I hanker for dynamicity, I've been reaching for groovy...a language I tried years ago which has come a LONG way and brings a lot of the features (namely, anonymous blocks/closures) I liked about Ruby. I'm nervously courting scala but in the early days.
What I liked about Rails can for the most part be found in Play (http://www.playframework.org), although I must admit I felt better about Play in its 1.x days when it was written in java. The core is now written in scala (though you can develop your app in either java or scala)...perhaps as I learn more of this language I'll feel more comfortable opening Play 2's hood. We're already started converting one of our Rails applications to Play, and it's been a great experience so far. And oh, by the way, we're finding that whole "rails/ruby won't slow you down...your database will slow you down" argument isn't always true.
Anyway, count me among Java's (and the jvm's) fans. It probably doesn't hurt that I have been working with it in one way or another since 2001, but I tried my best to leave it, only to find that sometimes you can indeed go home again.
I don't dislike Java out of popularity, I just don't find it to be a pleasant or expressive language. I like to code in vim without an IDE, so a lot of verbosity and boilerplate is painful. If I want static typing, I prefer a much more expressive and powerful language like Haskell, because frankly I just don't see what the point of static typing is if I'm going to get null pointer exceptions all over the place.
When I look at benchmarks of languages (notably this [1]), and compare Java to say Ruby or Python, it's about 40 times faster, and compare pretty well versus C++. And I'd rather code something in Java than in C++ everyday, all the time.
Now I'm not versed in the benchmarking of languages, and I don't care that much about them as I understand that they are not very reliable. But when I need a lil'more performance than Python or Ruby, but that I don't want to ruin my psychological balance with C++, I'm quite happy to have Java.
Maybe it's just my lack of knowledge that gets me to have this opinion. Maybe once I get a chance to try out Go and Scala, I'll find there is no reason to use Java anymore. But I don't think I'll get to the opinion that is it terrible and that it deserves to be hated and laughed at.
[1] http://shootout.alioth.debian.org/u32/which-programming-lang...
[Edit1] weakly -> dynamically
I think you mean dynamically typed, which is not the same as weakly. But even that is not true: there are plenty of statically typed languages which are nowhere are verbose as Java, due to cultural differences, type inference, first-class functions, pattern matching, etc.
- checked exceptions (usually leads to codebases full of empty try/catch blocks)
- the way generics got implemented
- how the current designers are afraid to change the language and keep adding annotations instead of new keywords (@override, @value, @notnull, ....)
- lack of type alias (typedef in C, type in Pascal/C/Go) to shorten declarations
- it would be nice to have aot compilation available as part of the standard toolchain, instead of forcing us to buy third party compilers
But the language is still quite usable and fulfills its purpose
And even if my last statement is hyperbole, you can still use Java in your scala project for the critical parts where scala doesn't do a good enough job. Sbt, the standard scala build tool typically builds you src/main/scala and src/main/java folders. Write scala in the scala folders, java in the java folders, they can easily refer to each other, it's all seamless.
In my opinion the reason why Scala will never be mainstream. There has to be a balance between features and simplicity.
I remember reading somewhere that although you might decide to limit use of Scala language facilities (as there are too many of them), you'll still have to deal with them when trying to understand how libraries work (for debugging purposes for example).
I've written a bunch of production Scala code, and I'm glad to have gotten away from it. Obviously to each their own.
Agreed on the readability though.
As for a small community, it hasn't bothered me. I get to cheat and use all the java libs.
Regarding compiler speed, I get the impression it's much worse on a mac than on linux (I use the latter, my colleagues use the former). On linux I've had little problem. I also tend to use `~ compile` in SBT. This will re-compile any time a file is modified, and notify you when an error occurs, so typically my code has already compiled by the time I actually want to run it. That's a really nice feature I wish I had in Haskell.
IntelliJ provides an excellent free scala plugin. What have you been using?
It always strikes me that the IDE/tools complaints have a high degree of FUD-spread to them. I've had good luck with both Intellij+Scala plugin and with the Eclipse plugin. And yes, my code is in production and is substantially more complicated than "hello world".
I -love- SBT and I detest the XML-hell at the heart of Maven projects. As you say, to each their own.
Scala is a gateway drug to FP, which, given my newly-acquired prejudices is a good thing. But that said, you still have the vast universe of Java libraries at your disposal, and if you really want to, you can use Scala in an imperative fashion and still get a Java-with-fewer-warts experience. I've not been following the Java 8 roadmap very closely, but with each new release the language seems to get more complicated and uglier, with patch upon patch, a list of which, if stacked end-to-end, would stretch from Chicago to New York and would fill three Library of Congresses and many other Standard Metaphors. It's been a joy to work with a language without all that legacy rolled into it.
You're right about the compiler, though for me it's not a huge issue. My builds take a minute or two, not tens of minutes. You're also right about the docs being weak at this time. There are definitely trade-offs either way in the Java vs Scala decision. For my purposes and my skillset, Scala is a sweet spot with Python a close second.
Doubt it, Go code has much less need for generics than Java code. This is in part because of Go's interfaces which cover some of the same space, because Go has builtin map and slice types, and because the general coding style in Go.
Have you really felt the need for generics when writing Go code? Because that is very, very rarely the case for me, and talking with many other Go programmers, the need for generics seems to very rarely come up when actually writing real world Go code.
One has to realize that features are not interchangeable across languages, just because they are essential to some language doesn't mean that they even make sense in another language.
It would be so much more beneficial to write one stack struct with associated methods rather than having to duplicate functionality for each type.
It's possible to use empty interfaces, but then you have to do runtime type assertions which defeats the point of static typing.
Maybe I've just been spoiled by Haskell/Java in that side of things, but I really feel that compile time static typing solves A LOT of development problems
A huge smell to me is that java frameworks have... frameworks... which have frameworks to finally arrive at a frankenstein's monster that is semi usable until its not and then woe-be-the-engineer saddled with its architecture. JSF is by itself is unproductive to develop with, so frameworks like RichFaces rose on top of it, which were also not enough, so other frameworks like Seam rose on top of them. And one feature of Seam is to make the JSF event-based framework behave more like an action-based framework ala struts or spring MVC. Maybe this should beg the question, "WTF are we doing with this dubiously helpful technology (JSF) at the foundation of our (web) technology stack?"
Its interesting to me that many "new" languages getting implemented are built on the JVM (or are old languages ported to java). I expect the JVM will outlive Java by a long margin.
1) Java is slow (the JIT hides only some of this -- see below)
2) Java makes working in Hashes and arrays very painful
3) Very little functional support (yes, Java8 will help)
4) The java language moves forward very, very, very slowly
5) It scalability is a joke. I've worked as a Java contractor at a number of places and what a PERL/PHP/Python solution can get done in 5 boxes, it takes Java 30-40 boxes. This is NOT an exagerration. I think it's a side effect of some developers stuffing everything into the session and expecting clustering to fix everything.
6) Date and file handling is also really painful. (yes, JODA helps, but we're 15+ years into Java and only finally getting good date support baked into the language)
7) Library management. Maven has largely "fixed" this issue at last, but sorting through library conflicts in order to write in an exception is still not fun. And as already noted, this is one of the reasons you can't just jump in with a text editor and hammer out a simple example.
The library support of Java makes up for a lot, but honestly, Python looks better and better every day.
edit: I will add in support for why many, including myself perceive java to be slow. The startup of the JVM is horrendous. If you're doing even moderate web development, there is a minimum two to three second startup period for a web server. That simply doesn't exist in PERL/PHP/Python. There's no such thing as a permgen error in PERL/PHP/Python. I've never seen PERL/PHP/Python go off and spin the disk as furiously as Java trying to load classes. It's ridiculous.
Java's strength is its maintainability and library support.
Umm...I think you've been working in the wrong Java shops. I've never seen, nor do I believe it's possible, for a well-written python/perl/php app to be faster than a well-written Java app.
The startup of the JVM is horrendous. If you're doing even moderate web development, there is a minimum two to three second startup period for a web server. That simply doesn't exist in PERL/PHP/Python. There's no such thing as a permgen error in PERL/PHP/Python. I've never seen PERL/PHP/Python go off and spin the disk as furiously as Java trying to load classes. It's ridiculous.
Sure, Java's start-up is slow. But it shouldn't be an issue in web apps since your application will likely use threads if it's a Java app. I can see if your app was process-oriented, like many ruby/python web apps are, but with Java's native thread support it makes no sense to start up multiple processes unless you really have a need for the separation.
I've been in the industry over 20 years. I've seen plenty. It is easy to assume that the java and a JIT should be able to take advantage of all the extra information to make fast code. But in practice, when you add in all the frameworks and abstraction overhead, Java on the web is slower. I routinely hit stack traces well over 50 levels of depth. Benchmarks really don't take this into account.
>Sure, Java's start-up is slow. But it shouldn't be an issue in web apps since your application will likely use threads if it's a Java app. I can see if your app was process-oriented, like many ruby/python web apps are, but with Java's native thread support it makes no sense to start up multiple processes unless you really have a need for the separation.
I mostly agree with what you say. It is mostly a development issue. While most software development in Java attempts to be centered around TDD and therefore eliminate the whole start-restart cycle, the ugly truth is that there are reasons that tools like JRebel exist.
But your original post said Java was slow. It's not. Don't conflate the language with bad frameworks written with it.
5) It scalability is a joke. I've worked as a Java contractor at a number of places and what a PERL/PHP/Python solution can get done in 5 boxes, it takes Java 30-40 boxes. This is NOT an exagerration.
I wonder why Twitter is moving their Ruby codebase to Java and Facebook is building a JVM backend of their PHP compiler .For fun, it seems. Facebook also built a PyPy backend[1], and even their own VM[2].
[1] http://morepypy.blogspot.ca/2012/07/hello-everyone.html
[2] https://github.com/facebook/hiphop-php/tree/master/src/runti...
Hard to believe this one is still getting wheeled out in 2012. Java is MASSIVELY faster than Perl/Ruby/Python: http://shootout.alioth.debian.org/u64q/benchmark.php?test=al...
I've seen over and over how Java code is at the very least an order of magnitude faster than a solution in a scripting language.
BTW the correct spelling is "exaggeration"
The DNA complement substitution is close to string processing, but still feels like mostly bit twiddling. Likewise, lot's of numeric fidgeting in those benchmarks.
I want something that does numeric and string conversions; string concatenation; file I/O; network I/O benchmarks. Also, something that could indicate how the strings were encoded, perhaps separate benchmarks for 7 bit ascii vs UTF-8, etc.
http://roboprogs.com/devel/2009.12.html
I suppose I need to update this on newer machines (e.g. - 6 core AMD box I have now, for starters, instead of an old Pentium-D), and it's certainly possible I FUBARed the Java implementation. If anybody thinks they can clean up the Java, so that the single-threaded performance is better, here it is:
https://github.com/roboprog/mp_bench
I got similar results, albeit with much older versions of Perl and Java, about 10 years ago on sample code I made to index a flat-file in Perl and Java. That code belonged to my then employer, so I don't have it.
// deliberately *not* using StringBuffer / StringBuilder,
// as a real app would have many transient string variables StringBuilder buf = new StringBuilder( s1);
buf.append( s2);
String cat = buf.toString();
instead of: String cat = s1 + s1;
in their application code. (although I think that is pretty much what the compiler generates on your behalf, anyway)The loop is in the benchmark so I don't have to write code dealing with many different string values of differing size manually.
Create the task definitions you want; write the best code you can for those tasks with an interpreted language, a JIT'd language and an aot compiled language; set-up the measurements framework and SCM for open contribution of programs; and then put up a website showing all that stuff and maintain it for the next 5 years.
Yeah, Poorly written code in language X can do that.
If developers with poor judgement or knowledge build badly performing Java apps, is that a language problem? I don't think so.
Sounds like they though they got some magical clustering with whatever they used. Instead they should have coded their Java implementation with the same principles that makes PHP rock: don't share state, memcache, scale horizontally. You can then probably replace those those 5 PHP boxes with a single Java server :-)
Our app handles a million concurrent connections per box so I don't know where that is coming from.
The teams I work with that use Java end up being the slowest moving teams because they can't deploy even the simplest code changes without a lot of pomp and circumstance and inability to upgrade their servers without disrupting the whole fragile of chain version dependencies. The java teams are the only teams that have to stop the world for hours when doing server code upgrades. Rails and PHP teams have much simple code deployments.
git tag -a v1.0.1 -m 'Version 1.0.1' ... wait till build is done ... cd $WEB_SERVER_HOME/deploy curl -O http://repo/myapp-1.0.1.war
Done. The last step can also be automated. I've worked with setups where production machines simply follow tagged release builds. Or just use puppet.
Java can rock. Specially with Maven it takes away so much pain of build/package/deploy.
I will say that this has more to do with the project than the language. Having recently inherited an old codebase at a new job, I've found at least 4 frameworks being used for the same app. Why didn't they just continue using one framework or upgrade when they switched? Don't know and the devs are long gone.
But like all languages it's easy to just half-ass something and leave it for the next guy. That's not something just for Java.
These industries and the activities listed have an inherent level of risk associated with them. The existing systems work well enough that we take the safety of these activities for granted. So while as an engineer, I might hate working with old, outdated technology and not want to work in these industries, as a consumer I appreciate that the people governing these industries are perhaps overly cautious.
Is that the most important problem for the tech industry? For the human race? If the proverbial twitter DSL programmer wouldn't proverbially create a DSL, would he use that time to meaningfully solve the systems' antiquity problem in the X sector? Even if so, is that the most important/bang-to-buck problem in known existence?
Java has a history of conservative implementation choices (E.g., see Guy Steele's account of some of those choices at [1]) Having lived through both, the Java world of a dozen years ago reminded me so much of the COBOL world of the 80's, I personally chose to move on to more innovative communities. I still occassionaly write Java, and am always struck by how memory-intensive it is and by how it always seems to abstract by spreading things out rather than by compression.
Regardless of your own preferences and choices, my recommendation to younger programmers would be to work hard to avoid getting stuck in any language rut. If you think of yourself as a "Java programmer," then you might already be a casualty of your circumstances.
[1] http://article.gmane.org/gmane.comp.lang.lightweight/2274
How about we confine language battles to language specific discussions (and I don't see anything wrong with those) and concentrate the overall engineering argument on getting good practice in every language. I can get behind the sentiment of replacing legacy systems but I don't see the point in hating on COBOL.
* The Myth of Uniqueness: Each and every company doing business believes that their business is different and couldn't possibly be the same as another company's. This is not completely untrue, but it's also not completely true. The problem is that this myth is propagated by the enterprise software vendors. The profit margins on services to customize software is far, far greater than the margins on software licenses. It is in vendors best interest to promote software customization.
* 50 Years of Customization is Hard to Throw Away: OK, maybe there's not many 50 year old systems running in production any more, but there are 25 year old systems. The amount of money spent to customize those systems over the years is enormous and big corps are not eager to toss that money spent away to start over.
* Database Conversion is Hard: Not so much difficult, but hard in the sense that it requires many, many hours to first clean up the old database, run the conversion, then validate the new data. One mistake could mean that someone's policy lapses because the conversion broke the automated Pre-Authorized Cheque processing code for that one client.
* Working at Big Corps is Uncool: Let's face it, being a programmer at a big bank or insurance company is perceived as boring. The over 40 set that these jobs appeal to aren't traditionally big adopters of new technology. As these people get promoted into decision making roles, they default to safe, known technologies.
* Corporate Partnerships: Big financial industry companies outsource their IT to corporations like IBM. These services companies have a vested interest in maintaining the status quo. It's much like bee-keeping bears ;)
* The old stuff still works: Even though the legacy code is unreadable and numbers in the millions of lines, it still mostly works. The "if it ain't broke, don't fix it" argument is an easy one to make when your executives (beholden to the shareholders) have to make their quarterly numbers.
Don't get me wrong, I'd love to see start-ups in the financial services software industry pop up with innovative solutions. In fact, I've thought about attempting this myself, given my background. But the elephant herd of legacy vendors to find your way around is extremely intimidating. In fact, I actually saw a few small vendors pop up over the years, get small contracts within the big insurance company to do something innovative with their shiny new technology (but not mission critical to the corporation), and then watch that company take on more and more lucrative services contracts further from their core software product. Eventually, their initial product offering becomes a footnote for them and they turn into something else, legacy related.
* It is near impossible to measure the savings of doing a conversion.
* Anyway, a huge chunk of the subtle behaviors of the current system is unknown, or when known, the business reason is lost in history. That makes it near impossible to properly estimate the cost a conversion would be.
* All the system in legacy tech are core product - they affect literally everyone in the company - thousands of people in the company. Over 40 that still like new tech have rock solid incentive not to push for them.
I've thought long and hard before about how to supplant a current legacy system that's taken root like an old oak tree in a financial services company. I honestly don't know how.
For example, a Life Insurance Administration System in a small insurance company. First, let's make some broad assumptions to make things easier:
1. The system will be "go-forward" only. i.e. we will not convert current policies onto the new system. 2. The system will NOT support any current product lines, but at launch will only support new product X, which is still in the product planning stages.
Given those 2 assumptions, how much customization will the new system require? The answer that everyone hopes for when they buy the software from the vendor (and the story the vendor sells) is, very little. The reality is that the system that goes live is usually very, very customized OR it ends up being very under utilized and simply interfaces WITH THE LEGACY SYSTEMS to meet the requirements of the product team, the regulatory bodies, the actuaries, etc. etc.
So what's a legacy system hating hacker to do?
The only way I could see legacy replacement being feasible is if big corp X decided that they were going to do full in house system development, and then market the core or the resulting system to their competitors. This isn't unheard of, and has been done in the past, but is pretty rare. The trend over the last 20+ years has been to out source virtually all of IT and buy off-the-shelf, vendor supported software to administer daily business. The argument, that big corp X is not in the business of software development is difficult to argue against. Alas, the end result is vendor lock-in, increasingly expensive services contract, and stagnant systems that are impossible to pry your business loose from.
The in-house/out-source cycle is fairly common in big financial services/health care corporations, usually on about a 4-8 year schedule.
I suspect the HN audience is not particularly interested in legacy systems development, or how one's insurance policy is administered. But, the next time you notice how large your insurance premium payment is, or complain about bank fees, or drug dispensary fees, etc. etc., stop and think for a second about what that money is paying for. In the case of insurance (which is the industry I'm familiar with), I'd argue that for a low-risk client, that a large percentage of your premium goes to administration of some sort.
Or do full in house system development and then buy out their competitors. A while back at one of our quarterly IT meetings we had a chart showing this, X number of competitors "recently" bought out, Y number of claims-management systems (and I think other related systems, things like bill review) migrated to our in-house system and shut down, Z number of systems currently being migrated.
[1] http://en.wikipedia.org/wiki/Epic_Systems
[2] http://thedailywtf.com/Articles/A_Case_of_the_MUMPS.aspx
It's indeed a complicated, convoluted, growth.
I've been in situations where critical system changes to support new products were being described in Business Requirement documents, sent to the vendor for translation to Technical Requirement documents, returned to the client for approval, and then scheduled for implementation at some point usually 6 months beyond the original requirements process completion.
Could this be why there are NO widely used open source business systems in the financial services, heath care, and banking industries?
source: http://www.computerworld.com/s/article/57362/Open_source_bre...
Working with legacy systems is a black art that I didn't learn about until I took a job supporting and extending one such system. The book I link to above was critical in helping me to understand the approach taken by the team I was working with. It takes a keen, detail-focused mind to do this kind of work.
The approach we took was to create a legacy interface layer. We did this by first wrapping the legacy code within a FFI. We built a test-suite that exercised the legacy application through this interface. Then we built an API on top of the interface and built integration tests that checked all the code paths into the legacy system. Once we had that we were able to build new features on to the system and replace each code path one by one.
Unsurprisingly we actually discovered bugs in the old system this way and were able to correct them. It didn't take long for the stakeholders to stop worrying and trust the team. However there was a lot of debate and argument along the way.
The problem isn't technical. You can simultaneously maintain and extend legacy applications and avoid all of the risks stakeholders are worried about. One could actually improve these systems by doing so. The real problem is political and convincing these stakeholders that you can minimize the risk is a difficult task. It was the hardest part of working on that team -- even when we were demonstrating our results!
The hardest part about working with legacy systems are the huge bureaucracies that sit on top of them.
The 'real business purpose' argument must also take in to account skills of available workers.
If no one is able to be hired to maintain and extend legacy system X, you're left with
* hiring workers with modern skills and backtraining them on older/legacy/custom stuff that won't do them much good in the future market, so they may balk (the smarter ones would demand a hell of a lot more money).
or
* converting to something more modern and perhaps somewhat future proof. The code itself might not be future proof, but the processes the business puts in place during the conversion should take in to account future conversions and upgrades as part of the requirements.
>Java, with its faults, has completely conquered web >application programming.
Is there any evidence that this is true? It's certainly my experience that the direct opposite is true. Java is traditionally considered successful in everything except web application development.
At this point for me Clojure is simply more fun to write in, although it remains to be seen if it gets ever accepted into the "industry best practices" mainstream that will make your boss sleep well at night, just like Java has for the past decade. Some of the old school LISPers (I'm talking people 70 and older who taught the language before I was even born) I know claim that they haven't gotten bored yet, so there's hope.
> So, why suddenly, in late 2010 and 2011, is Java suddenly the hated demon it is?
Suddenly? In the 2010s? Hah! I hated Java practically since the turn of the century, and only in the last 2 years did I relax and admit that it's become a good language/environment. But with Oracle's acquisition I don't see that staying. It was because of how Sun ran Java that the language flourished—if Oracle so much as sneezes, or even insinuates a change in policy, the language could see a major shift.
On a high level, Java vs Ruby/Python is a question of suitability to purpose.
Java is a great language for large teams of incompetent programmers. You will not be able to find competent programmers to code up the business logic for: Paying with a credit card. Going to the emergency room. Adjusting your 401k. Using your insurance card at the dentist. Filling a prescription.
That code is mindnumbingly boring, and has few technical challenges beyond sheer size and complexity.
With incompetent programmers, you want a B&D language -- Java forces object oriented. It forces a single object oriented paradigm. It forces a set of standard libraries. Etc. It makes it as hard as possible for programmers to shoot themselves in the foot, and it minimizes learning curve to get up to speed, making programmers as interchangeable as possible. If you've got a team of half-wits trying to write an employee management system, that's exactly what you want. The problem falls well within the limitations of the system. If you want to do something more complex -- a startup solving a problem that's never been solved before -- and you have a team of hotshot programmers, you really do want a less constricting and more flexible language.
COBOL is obsolete. Java vs. Python/Ruby vs. LISP/Scheme is a question of suitability to purpose -- primarily problem difficulty and team composition.
That's not censorship. That's the default setting for Wordpress blogs.
It's a flawless test for internet tinfoilery; such people immediately allege scandalous CENSORSHIP when the software mindlessly does what it always does.
Despite this though, I don't see your comment awaiting moderation. Can you resubmit it? Thank you! -Jonathan S. Fisher
The problem with it for me is, it's totally unusable for writing quick command line scripts/applications because you need to either
a) Run java -cp <classpath> <class-with-main>
b) Write a shell/batch script to do the above.
Then there's the lack of good stuff found in modern languages like first class functions.
It's not all bad though, recently I've been learning Go and the lack of generics makes me pine again for Java like a long lost love.
If you are using Rails, the database is the problem 99% of the time, not Ruby. MySQL can easily* be scaled / denormalised / sharded then if you need to you can just horizontally scale your app servers.
(*As easy as MySQL can. It isn't a black magic though, there is plenty of documentation, e.g. http://www.mysqlperformanceblog.com/)
The core Twitter service is still a Rails app though. There is nothing inherit to a language that makes it scale better than another, but different languages are better suited to different problems. As a result, Twitter does make use of Java in some capacity, but they also use a plethora of other languages where they make the most sense.
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
First, you need to wrestle with Eclipse. Then you need to figure out things like class and void and static and public before you can event print something to the screen. Ugh. So...much...syntax.Really?!
Then maybe you should consider other profession, as there are other languages out there much more verbose, like Ada for example.
print('hello world')
Or even HQ9+'s HAnd eclipse is not a pre-requisite to code Java; you get everything you need in the JDK and you best start with that, then it becomes clearer whatever it is your IDE is actually doing for (or against) you...
1) Make them want to write code 2) Show them how to reason about the code (this is where CS classes should come in)
Large companies are risk adverse and generally for a good reason. That mainframe running COBOL has probably been reliably processing orders, crunching financials, and managing inventory for 30 years. No one is going to replace that on a whim because COBOL isn't cool. What are they going to use instead? It's certainly not Mongo DB and Lua scripts on AWS. SAP possibly, but you still end up with an expensive system with even more unpredictable cost and licensing terms.
The problem I see with Java is that we're not sure whether Oracle is taking good care of it.
1. People equate Java IDEs with Eclipse and all it's problems. This one drives me the most nuts. IntelliJ is like night and day compared to Eclipse. I honestly don't understand why anyone uses Eclipse.
For years I've listened to Eclipse apologists for things like:
- Maven integration doesn't work. You need to add custom directives for m2eclipse (in IJ, you just open a pom.xml and you're done);
- Previously, there were two Subversion plugins for Eclipse and neither of them worked entirely right. VCS integration in IJ is excellent;
- Find and Replace across files is awkward and slow in Eclipse. It's fast and efficient in IJ;
- At Google, it's a running joke about Eclipse grey-screening (with our custom build processes and dependencies and so forth) to the point where it's been described as "turn-based programming". We can use IJ too and it has good Google integration but less resources dedicated to it. Still I've found it generally far less problematic;
- Am immense list of subtle improvements over Eclipse. Even something as simple as scope selection. Keep pressing ctrl+W in IJ you select the parameter, then all parameters, then the function call, then the block, etc. There is a similar(ish) command in Eclipse you can bind to a key but it's just not as good. That's just one example;
2. Java means using bloated frameworks like JSF, EJB2, etc. It does not. For example, I'm currently using Spring MVC (I haven't found a good relatively lightweight Guice-based Web framework yet) and Objectify on AppEngine;
3. You can't do closures in Java. You can. It's just incredibly verbose. Guava [1] is pervasive in Google. I highly recommend it. So you can write:
List<String> uppercase = Lists.transform(inputStrings, new Function<String, String>() {
@Override
public String apply(String input) {
return input.toUpperCase();
}
});
Granted it's much terser in, say, Python: uppercase = map(lambda x: x.upper(), input)
or (my personal preference): uppercase = [x.upper() for x in input]
But more on this in (4)...4. There is a lot of boilerplate in Java. There is and there isn't. Empirically there is but it doesn't matter. Take the above function. I type (in IJ):
List<String> uppercase = Lists.tr (autocomplete "ansform(") new (ctrl+space fills in the entire Function<> definition with correct types)
Same for getters and setters. I press alt+insert, getters and setters and select the ones that have them. You can also auto-fill equals, hashCode and toString methods (although the Guava versions of those don't seem to have a generator).5. Java means using checked exceptions. While I also loathe checked exceptions, this simply isn't true. It's one reason I like Spring. It tends to wrap most checked exceptions in unchecked ones (eg DataAccessExceptions instead of SQLExceptions).
6. IMHO Maven is great. Previously there was Ant and of course everyone thought their installation was different or they had their own preferences about where files should be. I like that Maven is "opinionated". It means you can go to any Maven Web project and know where to find things. YMMV.
Anyway, back to the issue at hand...
I've spent years working in such companies. It does tend to be a quagmire of mediocrity and politics but not always. We, as engineers, tend to forget that the easiest way to get anything done in such a company is to make a business case for added productivity, cost savings, risk management or whatever. Once you master this trick you can pretty much do whatever you want. It's simply the language the higher ups tend to speak.
Also, people don't tend to give enough credit to just how hard some of these jobs can be. Business processes and data migrations are incredibly tedious and they need to work.
Also, no matter how bad systems might be engineers tend to underestimate the ability of people to make them work. As engineers we tend to want to automate people out of pretty much everything we can. Often having some person look at something or correct something is far easier, cheaper and less risky than any automated solution or systems change.
I'm experimenting with Guice+Jersey+Angular.JS. It's a nice combination (if you want to do JS applications rather than the traditional MVC thing).
I've tried Sitebrickes[1], but the lack of documentation was a problem.
5. Java means using checked exceptions.
I think most people now accept that Java should have defaulted to using unchecked exceptions, and checked exceptions should only be for very rare cases. It's a mistake, but you are right: things like Spring make it a lot better in that regard.
[1] http://sleeplessinslc.blogspot.com/2012/02/jersey-jax-rs-mvc...
[2] https://github.com/murz/jersey-mustache/blob/master/src/main...
I'm not saying that your Java example is hard to read per say, but those extra lines of code add up, slowing down comprehension speed.
It looks like you're confusing closures with lambda expressions. That's an example of (a more verbose functional equivalent of) a lambda expression, but it isn't a closure.
Java's anonymous inner classes can close over variables in enclosing classes, but they can capture only final variables directly from the enclosing lexical scope. So Java actually does not support true closures.
2. Sure, you don't have to use the frameworks, but they're one of Java's big selling points. If you didn't want them why would you use java?
3. I think you make the point for me. Sure, closures aren't impossible in Java, they're just much harder than they should be.
4. Boilerplate isn't just there when you write it, it's there when you read the code, which is much more important. The one major live bug I introduced was when I accidentally replaced a getter that had some code in with an autogenerated one.
5. It is true in that there are a bunch of standard library methods that throw checked exceptions (e.g. file I/O), so like them or not you have to handle them.
You can do this in a separate process, the IDE only needs to detect that some .class files have changed and refresh the metadata of those files.
Eclipse support for this is sure nice, but then I hate Eclipse for being bloated, with a sluggish interface and shoehorning such features on top is the reason why Eclipse is the way it is.
Java ... It’s one of the fastest languages
Languages aren't inherently fast or slow, that's rather the quality of the underlying virtual machine / hardware architecture the compiled binaries run on. I think everybody can remember the days before Java 1.4 where the official JVM sucked performance wise. Did that mean Java the language is slow?Of course, in designing a programming language, the architect can make some tradeoffs that will make the resulting implementations of certain algorithms run faster or consume less memory. So on one hand the architect can make tradeoffs regarding some features of the language that may help with performance, but on the other hand those tradeoffs can also stay in your way when trying to do higher-level optimizations.
Community governance via that JCP (pre-Oracle).
It was Sun that refused to give a license for the TCK to Apache Harmony. The JCP was never nothing more than a bunch of people and companies bending over to Sun, now Oracle.Of course, because of OpenJDK and because Sun always projected this "open" image of Java to the world, the genie is out of the bottle because OpenJDK can be forked, and because APIs aren't copyrightable (although that's still a gray area), so even third party implementations are possible (as seen in the Google vs Oracle trial). So Oracle has to be a good citizen here, or else they risk losing whatever control they have left.
But the JCP was never and probably will never be a standards body and Java will never be a published standard, in the same sense that C/C++ are.
It’s popular to hate Java
You should definitely have feelings for programming languages, but only immature people think in terms of love/hate based on what other people think (basically you're kind of incompetent or still wet behind the ears if you hate Java based on what other people say about it).Many of us in the trenches avoid using Java because it's lower-level than say, Ruby, or Clojure, or Scala. But Java is still there, still kicking ass, whenever the high-level abstractions are in our way, or whenever we are part of something bigger that imposes Java on us (like company politics). The same can be said about C/C++ - still kicking ass, but you don't really have to go that low level for 99% of the times, unless the project or organization dictates it. So why should you? Best tool for the job, right?
... are the industries that
are still stuck in the 50′s the problem?
Because you know, we should rewrite everything from scratch every 5 years or so.That's not really true. Some language semantics and features are difficult to implement in an efficient manner. Continuations are a good example. Dynamic typing, also can be inefficient because of the need for runtime inspection of object metadata. Clojure has this problem and that's why they added type-hints, purely as a speed hack to avoid this problem. True, most of Java's speed is probably due to the Hotspot VM, but in practice, it's still among the faster languages out there, certainly among the garbage collected languages.
I'm not arguing for or against Java, I'm arguing that both the hypothesis and the conclusion and everything about that article is flawed (it basically screams LINK-BAIT).
Continuations are a good example
First of all, most implementations for continuations that are in common use are on top of virtual machines that are stack-based, so providing first-class continuations is a bitch, because you've got no way out of it other than to save the classical call-stack somewhere and restore it later, should you need to. And because of the way the call-stack is implemented, saving / restoring it is both time and space consuming.This was a pragmatic decision, more often than not, because explicit support is really not that useful, while being error-prone and because the major use-cases, like exceptions handling, coroutines, asynchronous tasks, etc... can receive language support that's also optimal on top of a stack-based VMs. And in most cases you don't need the unlimited extent that continuations on top of Scheme provide (most people just need the "async" support like it was done in C#, which is just compiler-related syntactic sugar). Some people even consider continuations "harmful" as sort of a modern Goto (a topic on which I have no opinion btw).
However, if you get rid of the traditional call-stack and make all methods receive an implicit continuation of the caller, and overload the "return" operator to call that implicit continuation (basically making everything CPS), then you could optimize this more efficiently. By how much, nobody knows yet, because there have been only weak attempts at solving this (I only know of Parrot, the new Perl 6 VM, but it hasn't done anything spectacular yet).
Also remember that our current commodity, general-purpose hardware is optimized primarily for C, which assumes a traditional call-stack. And you can always design hardware that's optimized for different things.
Dynamic typing ... Clojure has this problem and that's
why they added type-hints
You haven't actually mentioned the exact problem Clojure is having. Clojure added type-hints mostly to avoid primitive boxing/unboxing. It doesn't have much to do with "dynamic typing".In case you weren't aware, the JVM bytecode is pretty dynamic. Besides primitive operations on primitives, which have special bytecode instructions, the only place where you really, really need the name of a class or interface is when calling a method. And so the name of the Class.method ends up hardcoded in the bytecode, but that's only because Java itself has clear rules for method-lookup, so providing the means to override that method-lookup was unnecessary.
However in Java 7 they added invoke_dynamic, which does provide the means of overriding the method-lookup being done. JVM engineers, like John Rose, promised the same performance characteristics as invoke_virtual.
But Clojure doesn't even need invokeDynamic most of the time, because in most cases method calls in Clojure are only polymorphic and not dynamic. And because most things in Clojure are immutable. JRuby would have been a better example.
EDIT: formatting (moved ending paragraph to the beginning)
Don't get me wrong, there is a time and place for OOP as well as for GoF design patterns but overdoing it is - I think - really bad design. Java tries to force you to adapt to this, while for certain tasks a different approach is clearly superior. Some programs benefit hugely from being written in a functional style, others benefit from having purely imperative modules that are not part of a class hierarchy. Java doesn't do any of that and makes it look like a good thing.
Again, I don't condemn the idea of OOP, I condemn sticking too closely to one paradigm. C++ is a horrible language in many ways but I still prefer it to Java by miles. Because it's multi-paradigm. Python - multi-paradigm. Heck, even C99 is multi-paradigm in a way (assuming you dive deeply enough into it, one can actually write OOP code as well [1]).
</rant>
[1] www.cs.rit.edu/~ats/books/ooc.pdf
I takes a lot of patience, attention to details, and computer arqueology skills. Still, it can be done, and it is very worth it $$ to the companies (and to me! $ :)
I love the JVM.
90% of the benefits of java are benefits of the JVM.
the Java language itself is garbage though. Too many hacks, too slow release cycle, too slow adoption cycle.
Kotlin is actually a great language built on the JVM that handles the weaknesses of Java and builds on the strengths of the JVM.
So once again, I am sick of articles "Java s0x0rs!" and "Java r0x0rs!" Please be specific as to what is a problem Java or JVM, and address that.
The only issue I have with Java is the JVM's garbage collector. I hate that the JVM's GC can't automatically expand and collapse the total allocated space to make your application run as lean as possible, but also expand to take up as much ram as needed. And by the time OutOfMemory exception is thrown, you are screeeeewed, best u can do is die. Wish there were strategies for out-of-memory handling (like which memory can be scrapped in favor of application stability)... then again you probably have a well designed app at this point.
No language is optimal for every single type of project and workstyle, and knowing only one language you wont get far in most situations, and thats fine. However if I see a choice I can make between java and another language to use at work for what I'm working on, I do end up using java in most cases simply because I enjoy working with it more.
Witness the ridiculous mess the British banking industry has gotten into (with RBS, a massive British consumer bank having a failure that caused them weeks of further problems).
It can often seem to those of us outside that management in those companies has focussed on pure profit, not dealt with technical debt and not even tried to make an effort to adapt their IT strategy to the rest of the world.
If its a given that the industry is "antiquated and ridged" there has to be some room for people to solve existing problems. Even if it's laying new on-top of old (as some have mentioned). The question is: how do you identify the problems without going to work for a legacy infrastructure provider / integrator? Any advice out there?
Seems like Java community did quite a lot to get Java to perform better. How likely is it for a language like Python or Ruby to do something like that? I understand that these are vastly different technologies and we simply can't compare implementing a JVM feature in say a Python interpreter, but any commentary would be appreciated.
The JVM has improved performance by developing more advanced garbage collectors and profiling JIT compilers over the years to the point where it is the JVM is the fastest managed runtime out there. http://shootout.alioth.debian.org/u64q/benchmark.php?test=al...
Short version is that Java tends to take a lot of memory and a fair while to start up, but once it gets going it's very fast. A bit like comparing a Boeing to a small sports car. The sports car will drive you to the shop around the corner very fast. The Boeing will take a long time to prepare for takeoff, but once it gets going will leave the sports car behind in the dust.
IBM also had some very bright minds working on their J9 JVM which was aoriginally targeted at embedded environments but was so good it became their mainstream VM. I'm not sure how much "borrowing" it does from the Oracle VM, but it's definitely a different architecture.
Another language could do this of it had wealthy patrons with a keen interest to make it so. Google with Python might be a possibility, but they are huge Java users already and have some of the old Sun team working for them.
of course there was no documentation whatsoever to figure out what was going on :)
NACA: Automatic migration from COBOL to maintainable Java -- http://code.google.com/p/naca/
"4 millions lines of COBOL were 100% automatically transcoded toward their Java equivalent."
I think this is a really cool technology.