20 ms·
Lombok makes Java cool again
- LeanderK 8y agoI think java made some wrong decision, with bigggest one being very pragmatics generics-addition, resulting in trouble down the road like List<int> not being possible. But I don't think checked exceptions are one of them ;) I don't like too much flexibility in a language that has strong types. If you undermine the type-system, why not code in python? But some additions of Lombok seem worthwile.
- Retra 8y agoChecked exceptions have often been presented as a mistake on the basis of the ergonomics and workflow problems they cause, not because they are unhelpful when implemented. The problem is that people don't want to break their flow to deal with them, so they don't deal with them by catching/throwing exceptions improperly. EDIT: There's also the fact that Java includes unchecked exceptions, so you can already subvert that part of the type system. I don't really write much Java these days, but I've use at least a few libraries which use checked exceptions in a way that really sapped the fun out of the experience. (And personally I feel it is important for writing code to be fun, because little else of working with computers is.)
- specialist 8y agoI've never understood the arguments against checked exceptions. "Forces API clients to catch exceptions you can't handle." My observation is that obfuscation frameworks throw a bunch of checked exceptions which are unrecoverable. Which says more about the frameworks than the language. Hibernate: RDBMS obfuscation framework Spring: Flow of control obfuscation framework JAXRS: Exception obfuscation framework
- ThorinJacobs 8y agoI've had both good and bad experiences with checked exceptions - it can really depend on the team! One of the parts of Lombok that really works well for me is that its notations are completely optional and fit many different levels of granularity as you see fit. Don't want sneaky exceptions? Don't use them! I mostly end up using it to make my Java code feel like C# though...
- Felz 8y agoThe problem with checked exceptions is that they constrain implementations by what possible failure states they could have. I.E. the implementations of an interface with a method in it that declares no exceptions will either never call anything that could throw a checked exception, it will internally handle its checked exceptions, or it will wrap them in an unchecked exception. In practice, the first is a straitjacket, the second leads to ignoring errors you can't propagate, and the third is boilerplate that makes it harder to actually catch the exceptions when you need them. What would've made them good would be a static analysis of some sort that could divine all possible exceptions thrown by a method call and its dependents based on its code, but in Java a class can always override another class and do something entirely different so that's not possible.
- Terr_ 8y agoTry reading this aloud: "The problem with return-types is that they constrain implementations by what possible success states they could have." Checked exceptions are (for the most part) the mirror image of checked returns! Both describe and circumscribe your expectations for what comes back from the method, the only difference is one is happier than the other. They follow the same kinds of type-rules, and the real problem is entirely on the human end: It's harder to imagine failure scenarios, features are prioritized over error-handling, and people don't like to do it if they can avoid it somehow. > What would've made them good would be a static analysis of some sort that could divine all possible exceptions thrown by a method call and its dependents based on its code Again, ask yourself "why don't we already do this but with return types?" Probably because it's horribly impractical in most cases and and outright impossible in others. For example, when it comes to interfaces, abstract-methods, or overridden methods... All of those involves concrete implementations that haven't been made yet. Heck, they might not get created until months or years after you ship your .class files. Then some random guy you've never met says: "Oh, hey, I can fix my problem by creating my own implementation based on their interface..." So unless your compiler can literally see into the future, you've got to set down your type-expectations first. > but in Java a class can always override another class No, even if all classes were marked "final", you'd have the same problem when it comes to using interfaces.
- kodablah 8y ago> I don't think checked exceptions are one of them While they may not have been the wrong decision, empirical evidence continually shows they add a syntactical burden many devs just work around (e.g. just wrap in a RuntimeException anyways). It's understandable why most modern languages don't consider predictable exceptions as part of the function signatures (though many discourage exceptions altogether in all but the most extreme cases).
- hota_mazi 8y agoThis is similar to saying that since error codes are ignored by most developers, functions shouldn't bother returning them at all. Error conditions captured in the type system are a vital part of making code robust. The fact that some developers don't know how to properly handle these error cases doesn't change anything to the soundness of checked exceptions.
- kodablah 8y ago> This is similar to saying that since error codes are ignored by most developers, functions shouldn't bother returning them at all. It's not like saying they shouldn't return them (unchecked exceptions exist), it's like saying they shouldn't be forced to check the error code or declare that they will return that error code themselves. Checked exceptions aren't sound when in practice the same ones are reused to mean many things. And we shouldn't pretend deciding whether an exception should or shouldn't be checked is an objective choice applied the same way across the ecosystem.
- hota_mazi 8y agoChecked exceptions are the compiler forcing the developer to consider error cases. What's not to like about that? Contrast with all the other approaches (runtime exceptions, return codes, Either/Result, etc...) where the developer can happily ignore errors, the code will compile, and then crash at runtime.
- erik_seaberg 8y ago
- twblalock 8y agoThe problem with checked exceptions is that any method can throw runtime exceptions, whether it declares checked exceptions or not. So the presence or absence of "throws" does not really change your approach to error handling. An exception might happen either way, so you need to exercise the same level of care either way. Furthermore, checked exceptions force you to bubble up implementation details all the way up to the interfaces. For example, if any implementation of an interface might throw IOException, you need to put that in the method signature in the interface. You can be clever and wrap it in a custom exception that exposes the same level of abstraction as the interface, but that's not a whole lot better than just using RuntimeException, and it causes people to try to cast the exception cause.
- Terr_ 8y agoYour second paragraph has a direct-equivalence to complaining about return-types and advocating that everybody should just specify "Object" to make things easier. ( https://imgur.com/iYE5nLA https://imgur.com/iYE5nLA ) In both cases it's about constraining and describing the results from a method. The only difference is that most developers are so much more accustomed to thinking and coding along the happy-path, where they will willingly do all the exact same architectural tasks. Seriously, read these three variations aloud and see how they sound: >> return-types force you to bubble up implementation details all the way up to the interfaces >> if any implementation of an interface might return Foo, you need to put that in the method signature in the interface >> You can be clever and wrap it in a custom return-type that exposes the same level of abstraction as the interface, but that's not a whole lot better than just using Object I'm willing to bet you can think of a slightly-incredulous answer to each of those, right? Perhaps something along the lines of "no they don't", "yes that's normal" and "WTF of course you should."
- twblalock 8y agoDeclaring only some of the things that might go wrong, which is the case with checked exceptions, does not solve the problem you described and only makes it more difficult to write code. If every kind of exception was checked, then every method in Java, including constructors, would need to declare that it throws RuntimeException and IOException and NullPointerException and NoClassDefFoundError and InterruptedException because those things could happen in any method. So we settle for declaring the type a function is expected to return, with the understanding that if something exceptional occurs a magical thing called an Exception will be thrown and it's not handled the same way as a return value. This lets us get our jobs done. It's engineering, not science. When you solve the halting problem we can talk about formalizing every possible failure state as a return value. Until then we will get on with our lives.
- alayne 8y agoChecked exceptions don't work right with streams/functional programming. They prevent abstractions that couldn't possibly be aware of custom checked exceptions. That's why Scala doesn't have them.
- ganonm 8y agoLombok is a useful crutch if you're writing lots of Java code on a day to day basis. However, given how easy it is to use Kotlin alongside Java I would question whether Lombok is the right solution to the problem. Kotlin has data classes which auto generate sensible 'toString' and 'hashCode' methods which is a massive time saver. Really, if you are considering introducing Kotlin to a Java project I'd recommend you just take the plunge. It's pretty much just a minor change to your pom file (if you're using Maven). Kotlin has Java interop as a primary feature and is flawless from my experience.
- kodablah 8y ago> auto generate sensible [...] 'hashCode' methods Unless you're using arrays. They went with "predictable" over "sensible" here. > is flawless from my experience As a heavy Kotlin user, I'd say it's far from flawless (not sure if you mean interop or the entirety of the language, but applies to both). I'm often creating and starring YouTrack issues. But yes, it's still a highly recommended alternative to Java.
- rufugee 8y agoAs someone considering using Kotlin for my next project, your comment is interesting. Care to share what flaws you've uncovered?
- kodablah 8y agoAssuming it's for the JVM, you should definitely choose Kotlin for your next project. Most of the flaws I find are for advanced usage (e.g. interop, coroutines, etc) or tooling (e.g. gradle issues, dokka) or just general advanced language use. I don't keep a running list of issues (I made one back in the day [0] but not all of it is still applicable), but nothing would keep me away from the language. It made a lot of right decisions. 0 - https://gist.github.com/cretz/2a49514b18914ef09b7c518db6db116c https://gist.github.com/cretz/2a49514b18914ef09b7c518db6db11...
- jicea 8y ago
- platelminto 8y agoI'm interested in the downsides of using Lombok, since the article seems to only focus on its positives and makes it seem like I should download it and start using it right now. Is there anyone here with Lombok experience that wants to share any issues they've run into while using it? All I can think of right now is the fact that the source code isn't compatible with Java.
- cs02rm0 8y agoThe downside is that you'll need to install it into your IDE. And again when you upgrade it. I guess the version needs to loosely match the one your projects use too. That might not sound like a lot but some colleagues hate that overhead. I love it though, think I've been using it for at least 8 years now in just about every Java project.
- philsnow 8y ago> The downside is that you'll need to install it into your IDE. And again when you upgrade it. I guess the version needs to loosely match the one your projects use too. If you work on a lot of different projects with different versions of Lombok, do you have to have multiple versions of the IDE plugin installed / is that even possible?
- stickfigure 8y agoLombok doesn't really change that much/often. I've been using it for a decade on projects of varying ages and never noticed a problem.
- cs02rm0 8y agoYep, also never had an issue with it in practice.
- twblalock 8y agoThe @Builder annotation has some odd behavior if you want to add default values (it just hardcodes them and you cannot override them!) or extra builder methods. Actually, anything involving default values seems to be very brittle and difficult to work with -- especially when deserializing objects from JSON. The @Wither annotation results in methods that do not always make a copy, and sometimes use == instead of .equals when comparing class members. If you call one of the Wither methods and assume you have a copy of the original object, and then you modify that "copy", you might have just created a very subtle bug. If you are using IntelliJ you can use the Refactor > Delombok menu option to show you the code that Lombok generates. I've been told that does not actually invoke the same code that the annotation processor invokes at compile time, so the results of Delombok might be misleading.
- benbenolson 8y agoOne of the major features of a language is its syntax-- and here, it seems as if the author, instead of simply using another language, is "fixing" Java's verbosity by installing a compiler pass that converts "shorthand" Java into valid Java code. Why wouldn't the author just use another language?
- javagram 8y agoUsing Lombok is relatively simple compared to switching to Kotlin or Scala, I think. A few annotations don’t seem that much more radical than stuff like AspectJ.
- esrauch 8y agoSometimes just fixing the rough edges with syntactic sugar can provide a lot of value. Like, CoffeeScript got pretty far with that strategy. Honestly, a lot of the best TypeScript features could be described the way you describe it.
- mohaine 8y agoMy main issue with Java is all the annotation based programming. Some of these are nice and can make the easy case super easy but if you need go even slightly off the easy path you seem to quickly loose all the time gained on the easy path. i.e. @GET(url="http://host/users/$userid" http://host/users/$userid") public abstract User getUser(String userid) isn't that much easier than the python requests version but much harder if you need to add a custom dynamic header to the call.
- JohnHaugeland 8y agoFactoryFactoryStrategyFactoryAgreementChainImplementationProxy
- jayd16 8y ago>custom dynamic header Its just: @RequestHeader("Header") added to the param list.
- neuronic 8y agoThe secret is that there is always another annotation...
- joneholland 8y agoHow do you add that dynamically?
- jayd16 8y ago
- chooseaname 8y agoJava the language is cool. What the enterprise has done with it is not cool. Writing apps with layer upon layer upon layer upon layer of abstraction is ... self defeating. Then they'll holler, we need to rewrite it! All in the name of finding that one true architecture that can handle any business CR. Blech.
- dajohnson89 8y agoHow do you feel about Spring? I'm a fan of Java itself as well, but find myself conflicted whenever I use Spring/Boot. It's very nice when it works. But when the magic formula isn't recited correctly....you get frustrated and wind up visiting HN to forget about how unpleasant it is. ahem
- jimbokun 8y agoSpring is obsessed with using anything but actual Java code to express business logic in Java programs. XML bean configuration files. Annotations. Implicit code generation. Property and YAML files. Looking for files and resources in "default" locations. Executing code at runtime as the result of adding a dependency, without it ever being explicitly called anywhere. The result is, you can never really predict what the hell your program is going to do when its running in production. Certainly not by carefully reading and inspecting the Java code you write.
- pjmlp 8y agoI think that it brought a good competition against JEE (back when it was still J2EE), however I would still just use JEE for Java Web projects.
- dajohnson89 8y agoJust curious -- why?
- pjmlp 8y agoShort answer, experience and employers. My experience doing Web development in Java started with joining a team that was ramping up a project on WebSphere 5.1, alongside a migration from BEA WebLogic. I went through a couple of WebSphere, JBoss and TomcatEE versions up to JEE 6, was the technical lead for an in-house JSF framework built on top of RichFaces, and on very last JEE project used PrimeFaces. All the employers that I worked for, mostly used JEE stacks for their Java projects. Spring was the exception, rather than the norm. Additionally, even if a bit slowly, many of the Spring improvements ended up in JEE and Spring also supports the JSR related to JEE anyway. Nowadays I live in the .NET world, and the Java teams next door are happily delivering JEE based solutions. So if I was suddenly asked to architect a Java based solution, naturally it would be JEE based.
- jkmcf 8y agoSomewhat serious: LombokScript please. To quote @Retra in this thread: "I feel it is important for writing code to be fun". IMO, programming is fun when you are solving "business" problems, not writing boilerplate or handling a language's myriad edge cases.
- zmmmmm 8y agoI kind of agree, but I also find it curiously self-indulgent that as a profession software engineers feel entitled to discard technologies and methodologies because they are "not fun". Can you imagine civil engineers or electrical engineers saying that? They might enjoy working with certain technologies but would consider it highly unprofessional to demand that their projects be "fun" over other considerations. NB: Groovy might be the closest thing to "LombokScript"
- deleted 8y ago[deleted]
- JohnHaugeland 8y agolol, no, it doesn't
- JohnHaugeland 8y agoHave you ever noticed how these "cool again" posts always seem to come from companies with billions of dollars that struggle to make their sites work under relatively low load? Five times in six their grocery search - literally the core of their product - 502s on me. In the remaining 1 of 6, if I just keep repeating, I get random subsets of the data I should actually be getting. It's amazing to me that I haven't seen a fail whale yet. I refuse to believe that Instacart has a large practical server load. These are not the people we should be listening to.
- RandallBrown 8y agoThis is from Grubhub, not Instacart.
- saagarjha 8y ago> Although Java is one of the most popular JVM languages Is it not the most popular JVM language?
- berbec 8y agoIs it not the definition of a JVM language?
- chvid 8y agoJava is by far the most popular JVM language - probably by a factor of at least 10.
- isbvhodnvemrwvn 8y ago10 is a low estimate. I'd say it's more like 20, with Scala dominating the rest.
- geodel 8y agoI think Java is just 99% of JVM languages while other ones together take whopping 1% share of JVM languages.
- eweise 8y agoWe initially used lombok to decrease the pain of writing in Java but eventually moved to Kotlin and are sooo much happier.
- BtdTom 8y agoKotlin is great and very easy to use if you already know Java.
- koolba 8y agoWhat's the point of this part of the generated Java code? (I split it out onto multiple lines for legibility) favoriteFoods = new java.util.LinkedHashSet<String>( this.favoriteFoods.size() < 1073741824 ? 1 + this.favoriteFoods.size() + (this.favoriteFoods.size() - 3) / 3 : Integer.MAX_VALUE ); favoriteFoods.addAll(this.favoriteFoods); Why not just? this.favoriteFoods = new java.util.LinkedHashSet<>(this.favoriteFoods);
- notamy 8y ago1073741824 is maximum (signed) integer size divided by 2. This is trying to optimize for the initial size of the set so that it doesn't have to allocate too many elements, since iirc Java's hashsets are backed by a hashmap implementation which has to be sized appropriately.
- koolba 8y agoI understand what it’s doing. I’m curious why it’s necessary to do it explicitly. Wouldn’t the optimal sizing be the default behavior when passing in the collection that will populate the set?
- hota_mazi 8y agoAt this point, it's less disruption to a Java project to start writing it in Kotlin than adding Lombok to it.
- the-alchemist 8y agoi also wanna give a shoutout to https://immutables.github.io/ https://immutables.github.io/ over Lombok. No AST magic, and even optimized Jackson/GSON code.
- JanecekPetr 8y agoThis, a million times. In my professional bubble Lombok is completely gone. I'll go as far and say that modern Java does not use Lombok. Smaller, focused libraries like Immutables or AutoValue, solve the problem of boilerplate for data classes. Lombok tries to do too much across many concerns, in a fairly opaque way, and makes the code and tooling around it more magic than it needs to be. Skip Lombok. Modern Java is better off without it...
- zmmmmm 8y agoEven cooler is using a JVM language that builds many of these features in (my favorite is Groovy). Java will always be weighed down by the (necessary) baggage of backwards compatibility. I think companies still confining themselves to strictly using Java and nothing else are doing themselves a disservice when there are JVM languages that offer almost perfect compatibility at the bytecode level.
- rienbdj 8y agoI spent considerable time playing with Java and various usability extensions, but if I could go back I would have ditched Java much sooner. ML based languages really are an order of magnitude productivity boost.
- jimbokun 8y ago"ML based languages really are an order of magnitude productivity boost." Is this still true when you consider available libraries, performance, concurrency, build and dependency tools, development environments, and deployment options?
- rpeden 8y agoI'd say it depends on which ML derivative you're talking about. I've found F# to be pretty good in all of the areas you mentioned. Although not enough to literally provide an order or magnitude boost like the post you were replying to suggested. I think people use "order of magnitude" a little too freely. Developing with Java (and to a lesser extent, C#) feels slower than with F#, but not 10 times slower.
- rienbdj 8y agoI was not exaggerating, although you would not see the same improvements for all applications. The big win for me is do notation (or computation expressions). I hate to think how I would even write complex async code without it. If I was only writing something linear then Java wouldnt be so bad.
- diegof79 8y agoI use the elements of programming from SICP[1] as a litmus test for this kind of frameworks. The main issue with these annotation hacks is that they fail in the area of “means of combination” and “means of abstraction”. For example if you have: @X @Y class Something{} You cannot tell if X & Y can be combined (or how it’s combined), or you cannot easily create an abstraction Z with X and Y (you may be able to do that but it requires framework support and usually is painfully impractical) It seems to be a small issue compared to the added value, but to me is not. As the code base grows the maintenance and debugging issues grow too... in the end probably is better to use Kotlin or Scala. [1]: https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-10.html#%_sec_1.1 https://mitpress.mit.edu/sites/default/files/sicp/full-text/...
- jimbokun 8y agoThanks for that! Makes clear and explicit the queasy feeling I get from over reliance on Java annotations. Lisp macros, for example, fare much better in the "means of combination" and "means of abstraction" tests, I think.
- ajkjk 8y agoI agree, but it's helpful that the things Lombok abstracts away are very idiomatic and straightforward. I would never want to use it to take on anything more complicated.
- rubyfan 8y agoAnnotations have always come across as a crutch. It’s noisy at best and unsightly in large concentrations.
- malcolmgreaves 8y agoIMO just move to Scala: the change in thinking from mutable, stateful OO to immutable, pure FP (w/ some side effects mindfully mixed-in) is indeed steep. However, accepting this paradigm shift yields unbelievable dividends in terms of quickly writing correct programs that solve complex problems.
- calvinmorrison 8y agoMaybe you just nailed it on the head for me what I've been trying to state for a while in regards to FP. Expressing complex things like algorithms in functional programming can be beautiful and also incredible in how it adjusts your thinking. Fact of the matter is, I don't solve many complex problems like this. It makes doing tutorials and books fun but when i need to get work i stick to my usual guns
- grahamm 8y agoI use Lombok all the time. Yes it has some awful bits but generally it's positives outweigh it's negatives.
- fgbreel 8y agoIs there any other language with such thing like lombok? How would one explain why "lombok" is necessary at all? Specially to a newcomer. With efficient/safer languages like Golang and Rust getting track, I don't see a reason into trying to keep Java around.
- miaklesp 8y agoMaybe just use a better language instead?
- zestyping 8y agoReading this just reminds me of all the terrible things about Java. The lack of reasonable default string representations, comparison and hashing methods, etc. are all glaring mistakes in the language design that have wasted huge amounts of time for millions of programmers. It's as though Java programmers are so deep in the grips of Stockholm Syndrome that ordinary, sensible behaviour seems amazing and "cool". This is similar to the situation with design patterns. When design patterns came along, Java folks talked about them as though they were a wonderful new invention. But they only exist because Java is so clumsy that it needed crutches to do things that had been easy and natural in other languages for years; someone merely came along and gave the crutches names.
- chii 8y ago> all glaring mistakes in the language design that have wasted huge amounts of time for millions of programmers. i would think javascript is the language with which the mistakes wasted the millions in man hours, not java.
- fraggle222 8y agoYou either like strongly typed object oriented langs or you don't. If you do, then a bit of verbosity is really nothing. If there are actual lang improvements beyond saving me a few characters, I'll take them.
- jimmcslim 8y agoSomething like this would be handy for the .NET framework. Off the top of my head; PostSharp (although not free) would get you much of this. Also might be achieveable via Roslyn? And there is another .NET AOP framework whose name eludes me at the moment... EDIT: Fody.
- stevehiehn 8y agoNot sure I agree with the claim considering Lomboks been around for quite a long time.
- dionian 8y agoLombok solves one of the major problems with Java, but doesnt solve a million others. Scala, Kotlin, or Clojure are way better alternatives...
- agumonkey 8y agopythonistic coffeescript for java ?
- spricket 8y agoLombok is awesome. There's still some painful stuff in Java but Lombok gets rid of most of it. I agree with other comments about using Kotlin instead, but I've had a ton of resistance to switching languages since all our devs know java. Since Lombok is "just a library" I've managed to sneak it in almost every project I've worked on. Deftly used, I swear it cuts the LoC in a project by 30%
- afpx 8y agoPlease don't. Why? It adds more time to the build, it requires plugins to work effectively, and it confuses the hell out of people when they expect to see Java. If you really want a better syntax, use Scala or Kotlin (I'm a huge Scala convert).
- ilovecaching 8y agoIt’s ok to let languages die; we’re just barely scraping out of the infancy of programming. Languages like Java and C++ which have carried us a long way need to evolve into new and better languages that incorporate lessons learned and the next wave of research. We also know from Google’s paper on software practices that software naturally gets rewritten over time, at a cadence that makes it acceptable to switch languages. So there is really no reason not to have a plan for your business to migrate languages periodically. Unfortunately the industry seems to be stuck in a rut, and we’re forced to retrofit ancient compilers like horse drawn buggies with plate armor and machine guns on them.
- ehnto 8y agoI see the opposite. I see an industry all too willing to throw away years of hard earned knowledge, experience and purpose built tools in order to chase the shiny tools the popular kids are using. New tooling often follows a commom cycle of being light weight because they ditched the stuff that looked unecessary. Then slowly a whole ecosystem of plugins and libraries springs up to rebuild the missing tools. Like the bottom bracket tool in a bicycle tool box. I have never used one, but when I need one no other tool would work. I do truly believe that there is mastery in advanced, long lived tooling and efficiency may not lie with a new language but in truly understanding a comprehensive set of ordinary tools. Languages also tend to be just the building blocks for the real tools, which are the frameworks and libraries built with them. So I hesitate to throw away my hard earned knowledge only to re-learn another artisan MVC framework written in a prettier language. I concede that the parade must go on though, and ultimately I have to pay the bills. If precompiled serverside React is where the money is then... so be it.
- blr_traffic 8y ago> an industry all too willing to throw away years of hard earned knowledge, experience and purpose built tools in order to chase the shiny tools the popular kids are using. Why do you think people in the industry are doing this? There must be multiple factors behind this.
- 8y ago
- apo 8y agoAnnotation-based programming might seem cool now, but wait a few years. Magic always seems cool when you add it to a project - hey, look - I don't have to do <tedious thing> anymore. Then time goes on, and you (or your successor) opens up the project to track down a bug. Only there's no logical flow - things just seem to happen as if by magic. Lombok strikes me as magic in these ways. I actually had to go to the project home page to figure out what problem it solves: https://projectlombok.org https://projectlombok.org The examples refer to a specific kind of boilerplate, namely the kind that comes from treating classes a dumb bags of properties. Getters directly returning private fields. toString methods, etc. An alternative approach to Lombok would be to think about how the project ended up with so many dumb data classes. How could the project be refactored to eliminate them, for example? Doing so would avoid the need for magic and produce a code base in which effect followed cause.
- arcticbull 8y agoI liked to refer to the genre as MOP -- Magic Oriented Programming. Every ecosystem I've seen go down that route ends up bailing out. A good example of this would be Apple's Cocoa Bindings [1] on macOS that were killed with fire when the iOS APIs were defined, and KVO [2] which is flat out rejected at every company I've ever worked. On the other hand, when built into the language, this kind of explicit but automatic code generation can be awesome (as in Rust's #[derive()] traits [3]) but I think the difference there is the compiler/language vendor agree to support it indefinitely. [1] https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaBindings/CocoaBindings.html https://developer.apple.com/library/archive/documentation/Co... [2] https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html https://developer.apple.com/library/archive/documentation/Co... [3] https://doc.rust-lang.org/rust-by-example/trait/derive.html https://doc.rust-lang.org/rust-by-example/trait/derive.html
- Illniyar 8y agoRails would be the opposite example. Magic all the way down and the ecosystem is not even contemplating the idea of bailing on it.
- pjmlp 8y agoJava is cool, no need for crutches like Lombok.
- mindcrime 8y agoTrue, but Groovy is even cooler!
- pjmlp 8y agoAnd slower, as the tricks employed to make Gradle keep up with Maven show.
- zmmmmm 8y agoI think Gradle is mostly implemented in Java. I wouldn't think its speed is limited by the language of the DSL. Although I would guess startup time is longer as it definitely does have to load up groovy in the classpath and initialize all its classes.
- EmpirePhoenix 8y agoOnly for small stuff, if you have a 100k lines project you are absolutely unable to maintain it while staying sane.
- vorg 8y agoEven a 1k line project is unmaintainable when written in Apache Groovy.
- zmmmmm 8y agoI think you definitely need to approach a 100k line project differently to smaller code (for example declare types more often, static type at least your interfaces and methods, etc) - but it is completely possible to write Groovy in a style that scales to that size and is still maintainable. After all, it can look almost exactly like Java. On the other hand, it's impossible to scale Java down to the point where it would be sensible choice for what would otherwise be a bash script.
- patelh 8y agoWhy not just use Scala, you get all of that out of the box, no need for annotations, and you can still maven ;-)
- foobar_ 8y agoIt is practically impossible to teach good programming to students that have had a prior exposure to JAVA: as potential programmers they are mentally mutilated beyond hope of regeneration.
- jillesvangurp 8y agoI've used lombok in the past but only in projects where somebody insisted on using it before I joined. It can be nice having it around if you are stuck in a project where you have to use Java and it's just not negotiable to use something else and you have to use frameworks that expect a lot of model classes, DTO's and so on that comply with the java beans convention. This is a convention that emerged in the late nineties where people used a naming convention for setters and getters to expose properties. Lots of frameworks (hibernate, jackson, gson, etc.) rely on discovering such properties via reflection. Unfortunately this results in a lot of boiler plate and code that does nothing interesting. Worse, a lot of these frameworks expect mutable classes, which should rightfully make you feel dirty every time you write one. Lombok helps with that and you can sort of fake having quasi immutable classes. There's a price to pay unfortunately: it depends on generating code at compile time. This makes it necessary to use plugins for your favorite IDE to not get confused about all the non existent methods you are calling to access these getters, setters, builders and all the other boiler plate Lombok generates. Unfortunately these plugins make intellij more likely to get confused, which is something that can only be fixed with lengthy rebuilds, cache clearing, and the occasional restart. I've wasted no small amounts of time in trying to convince Intellij to get rid of phantom compile errors. For this reason, I'd never introduce it in any project I'm in charge off. It's just not worth the pain and I'd rather solve the problem of not having to have stupid code like that to begin with by using something that does not require it. IMHO code generation is a bit of an anti pattern. It's kludge for having flawed languages and broken frameworks. There usually is a better solution than generating a lot of source code. These days, Kotlin is a vastly superior way (and I say that with close to 25 years of Java experience) of avoiding that type of code and modern frameworks like spring boot work fine with it. Also worth pointing out that Java is slowly absorbing new features. Type inference is there now and they are working on data classes and a few other features. It might eventually catch up with less than half of what Kotlin does today in a decade or so. But why wait? IMHO Java is no longer a defensible choice on most new projects. Converting Java to Kotlin with the built in conversion tool in intellij is not flawless but it gets you quite far and you can go class by class. I actually have one project where I've been gradually moving to Kotlin for over a year now. Every time I touch some old code, the first thing I do is convert it to Kotlin. Only takes a few minutes once you get the hang of it and it's a great way to explore the language. Mostly you spend this cleaning up the things it got wrong regarding nullability, funky generics, or just using a bit more idiomatic constructs (e.g. using sequences instead of streams), etc .
- vbsteven 8y agoSpring boot with Lombok has been my go to framework for a few years now. Annotation-based programming seems to get a lot of negative attention here on HN, and it definitely is not perfect but there is just no other framework that (in my opinion) comes close in terms of productivity and workflow. Currently I'm building my SaaS + Selfhosted software licensing product with this Spring Boot + Lombok + Postgresql combo and Annotations are helping me out for : * @Bean, @Autowired, @Profile,... for configuring dependency injection with multiple profiles (saas vs selfhosted) * @Entity, @Table, @Repository, @Enumerated, @Embedded for mapping my classes to Database tables * @Api, @ApiOperation, @ApiParam,... for generating Swagger documentation for my endpoints * @GetMapping, @PostMapping, @PreAuthorize for configuring and authorizing my endpoints * Lombok @Data, @Value, @Builder for tedious boilerplate generation * @NotNull, @NotBlank, @Email, @PhoneNumber, @Pattern(regex), @Length(max=12),... for validation of form input, api params and database models. * @JsonProperty, @JsonSerialize, @JsonIgnore for configuring json deserializing for my DTO's * @Value("${my.config.key}") for decoupling configuration from my code and injecting values at runtime I probably forgot a few more use cases. All of these are pretty straightforward, are defined alongside the code they are modifying or interacting with and would lead me to a lot of lost time and a lot more code if I were to implement them myself, or configure them by hand "in real java code".
- raz32dust 8y agoWhile it is great while you are trying to get your product to market quickly, I would highly recommend getting rid of all these annotations as soon as you can. Preferably before your team grows to 5+ people or complexity grows beyond around 100k lines of code. It's hard to explain this to people from non-Java background, but the time writing non-annotation code will save you in debugging and maintainability is well worth it beyond that point.
- vbsteven 8y agoI can see that the dependency injection annotations can be complex for people not experienced with the whole Spring/IoC/DI setup. I have some rules and general guidelines I use for keeping them in check which I can explain in about 10minutes (and have done to team members in a few companies) Honestly, I prefer to debug with annotations and a debugger over a manually coded configuration class with hundreds of lines of wiring components together. And for removing the other annotations: Why should I decouple apidocs from my code? They are litterally annotating the source code so it makes sense to have them close. Stuff like the validators and JSON properties and configuration also makes sense to have them close to the fields that they are about instead of in a separate JsonSerializer class or whatever.
- throwmeback 8y agoJust switch to C# already. /s (just a bit)
- Kiro 8y agoWhy do you need to write all these getters and setters? Why not just a public property?
- salvadormon 8y agoI helped in the development of a microservice as a third party developer for a big lodgings reservation company. The infrastructure team of the main company forced us to include Lombok and use it and the code was a mess. Too much automagically generated code that was hard to debug. My company managed to deliver the microservice with enough quality, but I really hated the experience with Lombok, vanilla Java with the libraries needed for the task is more than enough (more control over your code).
- haglin 8y agoData Classes for Java https://cr.openjdk.java.net/~briangoetz/amber/datum.html https://cr.openjdk.java.net/~briangoetz/amber/datum.html
- ncmncm 8y ago"Again"? That seems to pre-suppose a counterfactual. Counterfactuals can be cool, but you have to explore them, not pre-suppose them. Pre-supposing them is definitely not cool, which calls into question the ability of our interlocutor to recognize what is and (more pointedly) what is not.