News for hackers. Stuff that matters.
Re:Love It or Hate It, Java Continues to Evolve by boyter on Monday June 17, 2019 @04:35AM (#20200995)
In my experience most people don't like Java due to experiences they had before Java 8. This means they were used to the bloat, config as XML style world which made Java a pain to write and slow to run.

Once I show them Java 11 with var keyword, lambda's and streams they start appreciating how modern the language has become. Then you throw in frameworks like javalin or sparkjava and suddenly they are not as hostile as they were before.

Honestly the only things I would really like out of Java these days are data classes and possibly native runtime compilation out of the box. Containers solve the latter issue, but id love to just build a binary and run it.

Do that and its on the same level as Go in many ways which nailed the tooling and deployment model, even if the language has issues. Java already has the tooling.

I suppose a decent syntax highlighter library like pygments or chroma would be nice too.

Re:Love It or Hate It, Java Continues to Evolve by kjeetgill on Monday June 17, 2019 @04:50AM (#20201067)
Agreed on all points.

You mentioned Go, so I'd like to add that Project Loom is the OpenJDK initiative to add green threads/coroutines to the JVM which I'd love. The tricky thing with "data classes" are that everyone wants something similar but different between the various terms: records, data classes, value types.

Personally, what I want from this is essentially Lombock-style all-args constructors, equals, hashcode, and toString. Struct-like like embeddability and flat object-headerless arrays are cool but honestly more niche. I don't mind sucking it up and using unsafe.

Re:Love It or Hate It, Java Continues to Evolve by boyter on Monday June 17, 2019 @04:57AM (#20201091)
Loom is rather nice, but frankly I don't find the lack of co-routines something I miss. You can spawn hundreds of real threads a second so it is possible to write Go style code in Java if you really want. I may change my mind when I actually use it though.

I don't mind what type of data classes they come up with. I just want to not have to write stupidly long constructors, multiple sets or chain-able objects when I want to populate some fields.

Re:Love It or Hate It, Java Continues to Evolve by kjeetgill on Monday June 17, 2019 @05:33AM (#20201250)
I've definitely had to fix servers that have choked themselves with thread abuse, so maybe it's ptsd. The fixes can be as simple as shrinking threadpools to needing substantial rewrites, so I still treat threads as resources requiring management.

Green threads are nice because they let me separate logical execution from operating system resources. Unlike Go, Java will expose the ability to use a custom scheduler, so that should be nice!

My personal pet usecase is actually the opposite. I want to isolate 5-10 "low priority" tasks to a single kernel thread to isolate how much damage misbehaving code can do.

Re:Love It or Hate It, Java Continues to Evolve by pjmlp on Tuesday June 18, 2019 @03:22AM (#20210410)
You can already use custom schedulers with java.util.concurrent though.
Re:Love It or Hate It, Java Continues to Evolve by unscaled on Monday June 17, 2019 @05:42AM (#20201288)
Except that the memory overhead for each thread is MUCH higher: the default would be 1Mb for most JVM implementation.

Yes, you can change the thread stack size, but that's a global fixed size for all threads, so you can't make it to small, or you'll risk stack overflows.

Meanwhile, Go is using dynamically growing stacks, starting at 2k.

Re:Love It or Hate It, Java Continues to Evolve by nvarsj on Monday June 17, 2019 @10:08AM (#20203088)
It doesn’t actually use 1mb. Only if the stack touches the pages will it ever allocate the physical memory. Most threads won’t use more than 16kB (the lower bound when I last tested it on x64). Still, it’s a lot larger than green threads.
Re:Love It or Hate It, Java Continues to Evolve by apta on Monday June 17, 2019 @07:47PM (#20208435)
Java already has both records/data classes[1] (including pattern matching) as well as value classes[2] in the works.

[1] https://cr.openjdk.java.net/~briangoetz/amber/datum.html

[2] https://openjdk.java.net/projects/valhalla/

Re:Love It or Hate It, Java Continues to Evolve by pvg on Monday June 17, 2019 @05:05AM (#20201131)
The additions and improvements are great but I think we're developing a kind of shared 'Modern X' fallacy. Modern Perl, Modern C++, Modern PHP, Modern Java, etc. The 'modern' facilities and the styles and efficiencies they enable are invariably terrific but you can't comfortably and effectively make use of them without having to know the bulk all the non-modern stuff. Which ends up limiting the appeal to the sorts of people who were prepared to put up with pre-modern to begin with.
Re:Love It or Hate It, Java Continues to Evolve by cursork on Monday June 17, 2019 @10:12AM (#20203128)
I agree with this to a large extent. A new codebase in the latest Java/whatever can be OK. But most of the time I feel like it's dealing with the same bad code, with just a smattering of nice syntax on top.

I started learning Perl in 2007; after it was no longer popular, but also around the time that the principles/practices that became 'Modern Perl' were becoming popular in the community.

I think there is a difference between the two though. Java was always a language which required a lot of ceremony and typing to get anything done at all. Perl was always focused on expressivity. Modern Perl was a case of learning from past mistakes and consciously avoiding some of the more egregious code the language easily afforded. Modern Java is more a case of Java playing catch-up to the more expressive languages out there.

One is applying constraints on your coding style, the other is trying to lift constraints. Both are trying to reach some middle point.

But! I agree that no company writes purely 'Modern Perl' - you will have to deal with some terrifying code at some point.

So. I agree with the concept of the 'Modern X' fallacy, but I would say that dealing with non-modern code is pretty normal, and people who are OK putting up with the pre-modern code may be some of your best employees. I suffer from rewrite-it-all syndrome myself sometimes, but it's something I try to avoid. Code that frustrates me, isn't necessarily bad.

(If it helps contextually, I'm - at heart - a Clojure programmer.)

Re:Love It or Hate It, Java Continues to Evolve by agumonkey on Monday June 17, 2019 @05:04AM (#20201124)
I may work with java soon, so I was reading about Spring and it was yet again a dive into insane amount of verbose over engineering that I ran away from years ago.

It's true that post 8 Java becomes palatable. And someone on reddit just showed me this piece of stats:

https://www.jetbrains.com/lp/devecosystem-2019/java/

83% on java 8, java 11 nicely going up

I pity those forced to work with old techniques

Re:Love It or Hate It, Java Continues to Evolve by maltalex on Monday June 17, 2019 @05:17AM (#20201174)
I write quite a lot of Java, and I have to admit I never “got” Spring.

I’d much rather have explicit boilerplate code (preferably in library form as much as possible) than complex, invisible magic.

The latter is “easy”, but the former is “simple”. In most cases, “simple” is more important.

Re:Love It or Hate It, Java Continues to Evolve by nurettin on Monday June 17, 2019 @05:58AM (#20201378)
I'd say there is no upside for the complex invisible magic. Half the time you have to run the application and pray that the configuration beans you've placed are working and if not, you are pretty much in trouble. Perhaps you missed a step in adding a configuration decorator in your application or configuration class, or used some deprecated method or used some incorrect class in the class hierarchy for the bean you want to return.
Re:Love It or Hate It, Java Continues to Evolve by agumonkey on Monday June 17, 2019 @07:12AM (#20201765)
it's not even magic, it's redundant over engineering at its peak

haskell has magic, but at least its concise..

Re:Love It or Hate It, Java Continues to Evolve by rhinoceraptor on Monday June 17, 2019 @05:46PM (#20207696)
It's like playing Where's Waldo, to find the actual code in an enterprise Java/C# application.

I think it's a fundamentally different mentality as far as the code. The codebase is so obfuscated that it might as well be binary data rather than plaintext files. You need an IDE to manipulate it efficiently.

Re:Love It or Hate It, Java Continues to Evolve by agumonkey on Monday June 17, 2019 @09:48PM (#20209145)
I feel like Enterprise is all about looking complex to justify the fees. The simpler it looks the harder it is to bill.

http://jeffacubed.com/the-boilermaker-story-or-knowing-where...

Re:Love It or Hate It, Java Continues to Evolve by unscaled on Monday June 17, 2019 @05:45AM (#20201313)
But Spring gives you the best of both worlds. A lot of verbose code (as annotations and class inflation instead of explicit boilerplate) and inscrutable magic.
Re:Love It or Hate It, Java Continues to Evolve by arethuza on Monday June 17, 2019 @05:50AM (#20201343)
If only we could all agree on what "simple" means - a lot of "enterprise" code I've seen would sweep vast amounts of complexity into hard to spot places to that you could have a small thing that people could point at and say how simple the one visible bit was, ignoring the vast amount of complexity lurking under the surface somewhere and invoked by more or less magical means.
Re:Love It or Hate It, Java Continues to Evolve by oweiler on Monday June 17, 2019 @09:18AM (#20202589)
I disagree. The "boilerplate" is the boring stuff I don't want to waste my time with.
Re:Love It or Hate It, Java Continues to Evolve by maltalex on Monday June 17, 2019 @03:40PM (#20206570)
In my opinion software development is less about what specific developers want to spend their time on, and more about producing solid software.

Does not spending time on boilerplate improve the quality of software you produce? I find that it doesn't.

Re:Love It or Hate It, Java Continues to Evolve by LoSboccacc on Monday June 17, 2019 @05:18AM (#20201182)
> I pity those forced to work with old techniques

java modules broke a lot of software that were using sun classes or did classloading magic.

I was on one of such application, it's not a lot of effort to migrate forward, but many of the issues are runtime only so unless you have a good test suite, a strong incentive and no closed source library that use some such classes you can't really move forward with it.

anyway, in java 7 was already possible to write "unbloated" code, especially with the servlet 3.0+ spec, but spring and osgi have a lot of inertia in the enterprise community, meaning most people were stuck programming in xml, one of the most unpleasant experience ever.

Re:Love It or Hate It, Java Continues to Evolve by agumonkey on Monday June 17, 2019 @07:13AM (#20201776)
I wonder how much salary increase it would take to make working with xml/spring worth someone's while.

ps: also how many shops are doing 'migration off of spring' ?

Re:Love It or Hate It, Java Continues to Evolve by mindcrime on Monday June 17, 2019 @12:58PM (#20204952)
I wonder how much salary increase it would take to make working with xml/spring worth someone's while.

Meh.. in my opinion a lot of this is just tropes. Spring is a fine environment to work in, although you really don't have to use any XML with modern Spring. But you can if you prefer to for some reason.

All the annotation driven "black magic" can be mildly annoying at times, especially before you understand what's going on under the hood... but considering the amount of boiler-plate crap it saves you from dealing with, I'll happily accept that tradeoff.

For my money, if I was starting a new backend service today, I'd absolutely reach for Spring Boot as my starting point. Of course, I may be biased given that I've been writing Java code for 20 years, and I remember what a breath of fresh air Spring was compared to the old EJB 2.x era "J2EE" stuff.

Re:Love It or Hate It, Java Continues to Evolve by LoSboccacc on Monday June 17, 2019 @02:12PM (#20205817)
> old EJB 2.x era "J2EE"

could have had worse you started just around the xdoclet, that was peak madness

Re:Love It or Hate It, Java Continues to Evolve by alasdair_ on Tuesday June 18, 2019 @02:16AM (#20210176)
Some of us worked at a shop that embraced Microsoft’s “embrace and extend” J++ with COM wrappers to go with Java. I still think THAT was peak insanity.
Re:Love It or Hate It, Java Continues to Evolve by mindcrime on Monday June 17, 2019 @02:35PM (#20206023)
I actually was around for the XDoclet era, although I managed to mostly avoid going down that particular rabbit-hole personally. I think I even have the Manning XDoclet in Action book still on a shelf somewhere around here. Never quite got around to reading it...
Re:Love It or Hate It, Java Continues to Evolve by agumonkey on Monday June 17, 2019 @04:52PM (#20207248)
java: provider of fine screen stand since 1995
Re:Love It or Hate It, Java Continues to Evolve by foxyv on Monday June 17, 2019 @05:35PM (#20207612)
I accept your pity. All my code has to be JRE5 compatible...
Re:Love It or Hate It, Java Continues to Evolve by agumonkey on Wednesday June 19, 2019 @01:46AM (#20221098)
Nice constraint..

is it allowed to produce libs in jars from non java languages ? Even though I don't think clojure/kotlin/else support jre5 out of the box anymore.

Re:Love It or Hate It, Java Continues to Evolve by Nursie on Monday June 17, 2019 @05:14AM (#20201161)
Big fan of sparkjava for no-nonsense HTTP services. The days of tomcat-for-everything were not fun as someone who only occasionally dabbled in java back then.

So I have to build this as a special type of jar and then set up this other, rather opaque, set of stuff and deal with all sorts of nonsense ...

Now?

  get("/hello", (a,b) -> "Hello World");
And we're done...
Re:Love It or Hate It, Java Continues to Evolve by butteroverflow on Monday June 17, 2019 @05:21AM (#20201197)
That sure looks nice, but how often do you write services which return a single constant string? I like to judge languages/frameworks based on more representative snippets.
Re:Love It or Hate It, Java Continues to Evolve by unscaled on Monday June 17, 2019 @06:57AM (#20201674)
I think this is not about showing off the easy case, but rather the straightforwardness of the framework. I haven't used spark myself, but I used frameworks quite like it (Jooby, Rapidoid, Ktor) in Java, as well their counterparts in Nodejs (Express, Koa) and Go ("net/http" + some router).

The applications certainly got a lot more complex than that, but we never found ourselves in need of a magic annotation that you can't step through with your debugger.

This is all about simplicity. It's pretty clear how a get() function on the router which takes a route and a callback works, but it requires some work to understand how Spring magically scans all your classes looking for annotations and then builds parser based on that. It's quite unclear where all of the routes are coming from (since they can come from a class just about anywhere). You suddenly need special tools. And the worst thing that suffers is transparency. Ctrl-clicking/Cmd-clicking on an annotation in your favourite IDE never tells you what it does.

In comparison, a second-order function is a vastly simpler and more grkoable beast.

Re:Love It or Hate It, Java Continues to Evolve by Nursie on Monday June 17, 2019 @07:13AM (#20201771)
> That sure looks nice, but how often do you write services which return a single constant string?

The point was just to show that the http server aspect of it is trivial to set up.

You can hook in whatever you want from there.

Re:Love It or Hate It, Java Continues to Evolve by Nursie on Monday June 17, 2019 @01:22PM (#20205229)
FYI, the "(a, b) -> Hello World" piece is a lambda returning a string constant, rather than just a string constant, hence the ability to hook in whatever you want.
Re:Love It or Hate It, Java Continues to Evolve by lihaoyi on Monday June 17, 2019 @09:07AM (#20202502)
In Scala using Cask it's

    object MinimalApplication extends cask.MainRoutes{
      @cask.get("/")
      def hello() = "Hello World!"
    
      initialize()
    }
API design shamelessly stolen from Python's Flask framework
Re:Love It or Hate It, Java Continues to Evolve by nurettin on Monday June 17, 2019 @06:35AM (#20201565)
Since we are hiding the rest of the app, in spring boot + kotlin that would be:

    @GetMapping("/hello") fun hello() = "Hello, World!"
Re:Love It or Hate It, Java Continues to Evolve by unscaled on Monday June 17, 2019 @06:45AM (#20201612)
That's a nice try, but the rest of the app would be[1]:

    import static spark.Spark.get;

    public class HelloWorld {
        public static void main(String[] args) {
            get("/hello", (req, res) -> "Hello World");
        }
    }

[1] http://sparkjava.com/
Re:Love It or Hate It, Java Continues to Evolve by nurettin on Monday June 17, 2019 @06:50AM (#20201634)
It is indeed a nice try, and the rest of the app would be:

    @SpringBootApplication
    @RestController
    class DemoApplication{
     @GetMapping("/hello") fun hello() = "Hello, World!"
    }

    fun main(args: Array<String>) {
     runApplication<DemoApplication>(*args)
    }
And this taught me that the best sinatra clone in java isn't really worth it in terms of lines of code saved (we save what? 3 lines of code? 6 with the imports?) when compared to a full-blown web framework like spring boot.

Would you care to do another one where we return a json response? I'd bet you will need a json mapper class for complex objects whereas I will return a dataclass instance and it will just work.

Re:Love It or Hate It, Java Continues to Evolve by unscaled on Monday June 17, 2019 @07:07AM (#20201735)
In Kotlin, so you don't have to define multiple files, obviously skipping the imports. Let's do the same with Jooby, for instance:

    fun main(args: Array<String>) = run(*args) {
      get { "Hello Kotlin" }
    }
It's always easy to make a framework lightweight. But there is no argument that Spring requires a lot of tedious boilerplate in Java (some of which can be avoided with Kotlin), and annotations which are hard to understand.

Lightweight frameworks don't really tell you "We do everything that Spring does in less lines", since at one point you'll ask them to make avocado toasts or something else that spring-bakery has a plugin for.

The real power of lightweight frameworks is their simplicity. This is not for everyone (that's why we've got Spring and Rails), but if everybody was fine with the tradeoffs that Spring makes, you'll see the same kind of frameworks ruling the Node.js and Go landscape.

Re:Love It or Hate It, Java Continues to Evolve by nurettin on Monday June 17, 2019 @07:29AM (#20201860)
I understand, and I used to be in the sinatra camp a decade ago. What I really disliked with spring/tapestry and rails was the (at the time) huge stack trace and memory usage.

The annotations I used were "this is a spring boot application" on top of a class and another which says "this is a rest controller" to start your hello world application and we only saved a few lines and introduced additional hidden complexity with sparkjava because we still don't have a way to handle json whereas it comes free with spring boot.

You've got another one that says "this is an injectable service" and another which says "this is a db entity" and with the "this is a configuration" you've got 99% of spring boot applications covered. Not sure what is so hard about the annotations. Maybe it has to do with "knowing more than just java/kotlin syntax" that puts people off?

Re:Love It or Hate It, Java Continues to Evolve by Nursie on Monday June 17, 2019 @08:37AM (#20202249)
I don't want to have to learn a brand new syntax to get things done.

Your Spring example immediately turns me off because it uses a bunch of annotations that could do pretty much anything (and I'd have to learn). Further, it uses kotlin which is not java - it's a valid choice but it's a more terse language in general (so not necessarily valid to compare against java examples).

Spark is straightforward and easy to read, it does one thing and it does it well, and it doesn't demand that I spend a lot of time thinking about anything other than what I'm trying to achieve. I have a lot of time for that.

For the record, with kotlin and skipping imports (of which there would only be one anyway) -

  fun main(args: Array<String>) {
      get("/hello") { req, res -> "Hello World" }
  }
I do indeed find this simpler than your proposal upthread.
Re:Love It or Hate It, Java Continues to Evolve by nurettin on Monday June 17, 2019 @09:37AM (#20202763)
Just now I embedded an amqp client into my app. To do that, I had to create a configuration class that instantiates necessary queues, exchanges and binds them to eachother using builder syntax and beans. The spring boot app lazily handles rmq client initialization and I didn't have to think of object lifetimes. That kinda sorta simplified my job. However, your point still stands, I had to learn new syntax (I learned to type @Bean) to do all this.
Re:Love It or Hate It, Java Continues to Evolve by unscaled on Monday June 17, 2019 @12:49PM (#20204843)
Nothing precludes you from using Guice or Koin for dependency injection with any framework. Yes, any DI framework would require you to understand some new syntax, but Spring again comes as more magical and mysterious, and the abstractions are always leaky. For instance, when using its magical scopes, it will create proxy instances without you using its magical request scope, bytecode-gen magic (cglib) or plain reflection (which is bound to be just amazing for performance).

This behavior which looks helpful at first glance, is very confusing. If your not proficient with Spring or spend hours reading the documentation you'll never understand that: 1. Your object lifetime is tied to the request. 2. The instance you see at the debugger is actually a subclass that redirects all call to the actual scoped object instance depending on a thread local variable (I guess?) 3. The proxy instance is either slow (JDK Proxy) or could cause you grief when you upgrade to the next version of Java (CGLIB). It's not clear which is which without some investigating.

I rather prefer to go with a lightweight framework + a sane DI framework and do something more explicit, e.g. create a RequestProvider<T> interface:

    interface RequestProvider<T> { 
      get(request: Request): T
    }

    class MyController() {
      val fooProvider: RequestProvider<Foo> by inject(name = "foo")

      fun myHandler(request: Request) {
          val requestScopedFoo = fooProvider.get(request)
      }
    }
This approach is more explicit, but I prefer it.
Re:Love It or Hate It, Java Continues to Evolve by debug-desperado on Monday June 17, 2019 @03:21PM (#20206408)
I don't get all this about Spring being an "insane" way to do DI. It works well enough, and Pivotal is very thorough with their documentation. I would much rather RTFM than dig randomly through the code and hope I find what I'm looking for.

How exactly does Guice differ in request- or session-scoped injections that makes it that much better?

Re:Love It or Hate It, Java Continues to Evolve by Nursie on Monday June 17, 2019 @11:24AM (#20203868)
> Just now I embedded an amqp client into my app.

I have no need for one of those, I'm good building some fairly simple microservices against spark without 'lazy client initialization' or any framework features.

That's kinda the point, it's a simpler toolset for a single purpose. You may have requirements that are made simpler for you by knowing the arcane ins and outs of a feature-rich framework.

Not everyone does, and bringing in said framework to achieve something simple in the name of "Maybe, in future, I may need this" is a prime route to an overcomplex, heavyweight mess. IMHO.

Maybe you've avoided Spring-related hell, but all the java devs I know who survived that era tend to groan whenever it's mentioned.

Re:Love It or Hate It, Java Continues to Evolve by ngrilly on Monday June 17, 2019 @04:50AM (#20201066)
> Once I show them Java 11 with var keyword, lambda's and streams they start appreciating how modern the language has become.

I wrote a lot of Java, but it was a long time ago. Could you share a bit of code representative of the modern Java 11 style you mentioned (var keyword, lambdas, streams, etc.)?

Re:Love It or Hate It, Java Continues to Evolve by somerandomqaguy on Monday June 17, 2019 @05:25AM (#20201217)
Not the guy that you were asking but Trivial example:

  public static void assertIsSuperset(Collection<Object> superSet, Collection<Object> actualSet) {
    final List<Object> missing;
    missing = actualSet.stream().filter(x -> !superSet.contains(x)).collect(Collectors.toList());
    if (missing.size() != 0) {
     /* Imagine some more verbose exception creation here, which is why we caught it in a list*/
    }
  }
The lambda is in the creation of 'missing':

  filter(x -> !superSet.contains(x))
A lot collections in Java 8 brought in a stream method which has some functional esqe methods. Filter is one of them, and if you look at filter's method signature:

  public interface Stream<T> extends BaseStream<T, Stream<T>> {

    /**
     * Returns a stream consisting of the elements of this stream that match
     * the given predicate.
     *
     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
     * operation</a>.
     *
     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
     *                  <a href="package-summary.html#Statelessness">stateless</a>
     *                  predicate to apply to each element to determine if it
     *                  should be included
     * @return the new stream
     */
    Stream<T> filter(Predicate<? super T> predicate);
  [SNIP!]
  }
Predicate is an interface that has one method: 'public boolean test(T t);'. The lambda that I created conforms to that single method; accepting the generic object (x) and returning the boolean tested by '!superSet.contain(x)' The other way I've seen them used is to implement an anonymous version of an interface.
Re:Love It or Hate It, Java Continues to Evolve by ngrilly on Monday June 17, 2019 @05:55AM (#20201367)
Thanks! I guess your example could be simplified further with the var keyword:

  public static void assertIsSuperset(Collection<Object> superSet, Collection<Object> actualSet) {
    var missing = actualSet.stream().filter(x -> !superSet.contains(x)).collect(Collectors.toList());
    if (missing.size() != 0) {
     /* Imagine some more verbose exception creation here, which is why we caught it in a list*/
    }
  }
Re:Love It or Hate It, Java Continues to Evolve by WAHa_06x36 on Monday June 17, 2019 @05:45AM (#20201311)
That still seems very clunky and also very inefficient compared to what I'd do in Swift:

    func isSuperset<Type: Equatable>(superSet: Set<Type>, actualSet: Set<Type>) -> Bool {
        return actualSet.contains(where: { !superSet.contains($0) })
    }
What is all the noise about "collect"? Why allocate a while new list? What's with the "final"? And why do I have to type out obvious types in 2019?
Re:Love It or Hate It, Java Continues to Evolve by somerandomqaguy on Monday June 17, 2019 @02:11PM (#20205814)
Because you're doing something entirely different, I'm asserting, you're testing. The equivalent java code would be:

  return superSet.containsAll(actualSet);
But a straight up boolean doesn't tell me what is missing, only that something is missing. I snipped out the bit about creating a more verbose exception creation because it wasn't really needed for the example:

if (missing.size() != 0) { final StringBuilder builder; builder = new StringBuilder(); builder.append("Missing item found: [ "); builder.append(String.join(",", missing.stream().map(x -> x.toString())).collect(Collectors.toList()))); builder.append(" ]"); throw new IllegalStateException(builder.toString()); }

Keep in mind that the objects that this method was written for actually implement human readable toString methods.

> What's with the "final"?

Habit that I forced on myself. But it's not a bad habit to get into. In theory methods are supposed to be short and readable but reality often ends up being that in the fury of writing under looming deadlines you can have horrifically long methods that do many things. And I've seen more then a few times someone reusing variable names badly. Using final when possible is just a way for someone to be able to look at the code, see the variable name and be able to know that what it says is what it is.

>And why do I have to type out obvious types in 2019

Because types aren't always obvious. That's a list, meaning that you can have duplicated items and that order matters. What if my 'list' was actually a set, in which order was not guaranteed? What about if you're trying to integrate this with multiples teams scattered across the world that don't speak English on a code base that's about 500,000 lines of code? Or when you walk away for 2 or 3 years and then have to come back to a method that's not as small and trivial as the given example? What about the next poor sap that has it dumped in his lap?

I know it seems stupid in the short run, and if you've got something small or something that probably wont' be relevant in a year or two, and I'd agree with you if that's the case. But but if you've got a code base that needs to be communicated to other people, then typing is a good way of handling that communication without having to write extra documentation.

Re:Love It or Hate It, Java Continues to Evolve by pjmlp on Tuesday June 18, 2019 @03:25AM (#20210422)
Except that is a Pyrrhic victory, as Swift is quite useless outside Apple platforms.

Linux support is still WIP, Windows nowhere to be seen, and everything else is not supported at all.

Re:Love It or Hate It, Java Continues to Evolve by sbov on Monday June 17, 2019 @11:49AM (#20204167)
The equivalent expression in Java would actually be this:

actualSet.stream().anyMatch(x -> !superSet.contains(x));

Re:Love It or Hate It, Java Continues to Evolve by aardvark179 on Monday June 17, 2019 @06:23AM (#20201516)
Yeah, the collect isn't really needed, you could easily use a reduce to calculate the value.
Re:Love It or Hate It, Java Continues to Evolve by Nursie on Monday June 17, 2019 @05:28AM (#20201235)
I've not yet worked on anything more recent than 8 but ...

I have a Map of Lists of Foo items (foos), and I want to transform each item in the sublists to a Bar, filter out bad Bars, transform to Baz and keep the results as a new list of Bazs

  List<Baz> barList = foos.values()
                          .stream()
                          .flatMap(List::stream)
                          .map(Foo::transformToBar)
                          .filter(Bar::isBad)
                          .map(Baz::transformToBaz)
                          .collect(Collectors.toList());

The syntax is a little clunky at times... but once you get used to it it's quite expressive.
Re:Love It or Hate It, Java Continues to Evolve by unscaled on Monday June 17, 2019 @06:42AM (#20201597)
Java 11 is obviously much better than Java 8, which is still leaps and bounds ahed of Java 6, itself an improvement over Java 4. You'd see the same in every language.

Java's problem is that for many years it used to be the slowest car around. Maybe this was one of the things that helped Java become the undisputed ruler Enterprise Inc. but now it's got a lot to catch up with, and even though the pace has picked up since Java 9, it's far behind its competitors.

Everything you mention (var, lambdas, streams) and everything you might mention when Java 13 comes out (switch expressions, text blocks) is just too little, too late.

Yeah, var is a lifesaver if you have to use Java, but compare the limited type inference it brings to the table with almost any other competing language (Kotlin, C#, Scala or Swift) which at the very least can do a return value inference.

Likewise, streams are long due, but the syntax is horrible and the repertoire of built-in operations is meager, and since Java does not support extension functions like the rest of the languages mentioned here you can't extend them gracefully.

If you take one of the examples given here:

  var grades = school.students()
                 .stream()
                 .flatMap(student -> student.grades()
                    .stream()
                    .map(grade -> new NamedGrade(student.name(), student.grades())
                 .filter(x -> x.grade() > 60)
                 .collect(Collectors.toList());
Kotlin goes the same route, but makes it little more natural to use:

  val grades = school.students
                 .flatMap { (name, grades) -> grades.map {
                              NamedGrade(name, it) 
                  }}
                 .filter { it.grade() > 60 }
                 .toList()
Besides simply more natural syntax, get the special 'it' variable, destructuring, more operations and

Now take C#, a language had something "Streams" since version 3.0 (released 7 years before Java 8):

  var result = students
                  .SelectMany(student => student.Grades.Select(grade => new { Name = student.Name, Grade = grade }))
                  .Where(record => record.Grade > 60);
Where you get anonymous records - you don't need to define a new type anymore.

Or with LINQ:

  var result = from student in students select
      from grade in student.Grades 
      where grade > 60
      select new { Name = student.Name, Grade = grade };
You get a highly readable built-in query language as well.
Re:Love It or Hate It, Java Continues to Evolve by rjbwork on Monday June 17, 2019 @07:08AM (#20201744)
Quick nitpick. Both of the C# examples are called LINQ. The first is called the "method syntax", the latter is called the "query syntax". The query syntax is transpiled into the method syntax before compilation.
Re:Love It or Hate It, Java Continues to Evolve by pjmlp on Tuesday June 18, 2019 @04:09AM (#20210608)
The slowest car still gets you down to the city center.

And neither Java nor C# have anything to brag about Streams or LINQ.

I could already writen those code examples in Lisp, Scheme, Caml Light or Smalltalk.

What we have is mainstream computing catching up, or as Erik Meyer has stated, selling Haskell to VB programmers.

Re:Love It or Hate It, Java Continues to Evolve by floriol on Monday June 17, 2019 @05:18PM (#20207491)
You have Clazz::someMethod in java so no need to write out the whole lambda expression
Re:Love It or Hate It, Java Continues to Evolve by anextomp on Monday June 17, 2019 @03:51PM (#20206654)
With kotlin, the final .toList() call can be removed
Re:Love It or Hate It, Java Continues to Evolve by vimslayer on Monday June 17, 2019 @05:49AM (#20201336)
That sounds a lot like what people are saying about PHP and its newer versions. But the thing is, now that we have great alternatives (Kotlin, C#, Scala, Go, Dart...), what does Java have that those don't?
Re:Love It or Hate It, Java Continues to Evolve by oblio on Monday June 17, 2019 @07:13AM (#20201770)
Millions and millions of people using them. High quality (and in many cases user friendly and familiar, too) tools built around them, several options, even.
Re:Love It or Hate It, Java Continues to Evolve by locopati on Monday June 17, 2019 @10:02AM (#20203023)
A virtual machine backed by decades of development and millions of person-hours
Re:Love It or Hate It, Java Continues to Evolve by twsted on Monday June 17, 2019 @05:17AM (#20201180)
This is not the only reason.

Who started using Java way before Java 8, used to experience serious issues about memory usage and performances in the JVM.

These memories struggle to leave.

Re:Love It or Hate It, Java Continues to Evolve by sebcat on Monday June 17, 2019 @05:31AM (#20201242)
Especially on 32-bit JVMs. Still have nightmares.
Re:Love It or Hate It, Java Continues to Evolve by stevoski on Monday June 17, 2019 @05:58AM (#20201380)
I can’t recommend sparkjava enough. It is the only Java web framework I’ve encountered whose “quick start guide” is actually that: a guide that gets you started in minutes, not days. The fully working “Hello world” app is 5 lines of code.

I built my profitable, bootstrapped B2B SaaS using sparkjava.

You can find sparkjava here: http://sparkjava.com/

Re:Love It or Hate It, Java Continues to Evolve by xrisk on Monday June 17, 2019 @05:25AM (#20201215)
I was checking out Spring recently. The hello-world sample turned me off at once [1]. It's so much more clunky than something equivalent in Python/Go/what have you.

[1]: https://spring.io/guides/gs/rest-service/

Re:Love It or Hate It, Java Continues to Evolve by Litmus2336 on Monday June 17, 2019 @04:47PM (#20207205)
While I agree with you that Spring is clunky, if you're making a simple application I don't think anyone will recommend Spring.

Where Spring shines is enterprise. When you have 600k concurrent users it's just something I can trust. Other solutions can work too, but we value the stability.

Re:Love It or Hate It, Java Continues to Evolve by fniephaus on Monday June 17, 2019 @06:10AM (#20201451)
RE native runtime compilation: have you had a look at GraalVM's native image: https://www.graalvm.org/docs/reference-manual/aot-compilatio...
Re:Love It or Hate It, Java Continues to Evolve by IloveHN84 on Tuesday June 18, 2019 @01:30AM (#20210028)
GraalVM works with Java 8, Java 11 isn't fully implemented
Re:Love It or Hate It, Java Continues to Evolve by StreamBright on Monday June 17, 2019 @06:40AM (#20201591)
I think it is certainly part of it. I also don't like Java because best practices include hiding everything inside objects and developers are generally against using simple functions. I also dislike how leaky abstractions are common in average Java code and the unnecessary verbosity. Java 8 helped with many of these yet, it is uncommon to see Java 8 syntax in most sources I work with. Many large companies just migrated or in the middle of migration to Java 8.
Re:Love It or Hate It, Java Continues to Evolve by ar_lan on Monday June 17, 2019 @04:48PM (#20207215)
Javalin is a bit of a cop out because it's not strictly Java.

I agree with modern Java improvements for the most part, especially if you are including Kotlin in that ecosystem - I really enjoy writing Kotlin.

However, I've professionally switched to Go and really wouldn't want to go back to Java much. I already think Go is a bit bloated, and I still feel like Java (even w/ the latest modern features) still gets incredibly bloated.

Re:Love It or Hate It, Java Continues to Evolve by vmurthy on Monday June 17, 2019 @04:42AM (#20201028)
> I suppose a decent syntax highlighter library like pygments or chroma would be nice too.

Could you clarify this? I last worked on Java in 2016 but even at the time, we had eclipse settings that had Syntax highlighters. Am I missing something?

Re:Love It or Hate It, Java Continues to Evolve by boyter on Monday June 17, 2019 @04:48AM (#20201058)
Have a look at http://pygments.org/ or https://github.com/alecthomas/chroma where you can pass code into a library and it returns highlighted HTML.

You can use Pygments in Java using Jython but its performance is questionable and can be incredibly slow when highlighting lisp code for example.

Its a very edge case for most people, but seeing as I am working on a searchcode.com upgrade I need a fast highlighter. Currently I am spawning a background Go process using Chroma to take care of this for me, but if there was a decent Java library I would use it. None exist I am aware of that are even slightly up-to date.

Re:Love It or Hate It, Java Continues to Evolve by Macha on Monday June 17, 2019 @09:27AM (#20202666)
Like with C++ though, chances are you will not be working on a "modern" project and will have to deal with patterns like random nulls, APIs based on extending framework classes etc
Re:Love It or Hate It, Java Continues to Evolve by ryuukk_ on Saturday June 22, 2019 @09:54AM (#20249552)
problem isn't that stuff, it is how java is engineered, it was made for the 80's

gaming industry is huge, but you can't with java because autoboxing everywhere, no value type, and no specialized generics

same for serverless, you can't because you have to ship heavy runtime

same for machinelearning, you can't do math because lack of value type

etc etc etc

Java tried to fix all problems, but they forgot the essential stuff, performance and efficiency

Re:Love It or Hate It, Java Continues to Evolve by pragmaticlurker on Monday June 17, 2019 @06:18AM (#20201486)
check out what 'auto' does from C++11 onwards then, oh and smart pointers too: memory management is no hell anymore
Re:Love It or Hate It, Java Continues to Evolve by sandGorgon on Monday June 17, 2019 @05:01AM (#20201113)
did you ever try Kotlin ? whats your opinion there ?
Re:Love It or Hate It, Java Continues to Evolve by boyter on Monday June 17, 2019 @06:20PM (#20207922)
I have not. The only major thing I see in Kotlin over Java right now (I don't do Android development) is data classes. Everything else is either in the language or should be soon which makes me hesitant to invest the time learning it.
Re:Love It or Hate It, Java Continues to Evolve by pjmlp on Tuesday June 18, 2019 @04:12AM (#20210619)
I agree with you here, I think that Kotlin is settled for life in what concerns Android, given the sore state of Android J++ and #KotlinFirst announced at IO.

Outside Android, we can enjoy modern Java, which makes Kotlin just yet another language capable of targeting the JVM.

Re:Love It or Hate It, Java Continues to Evolve by sonnyblarney on Monday June 17, 2019 @05:23AM (#20201207)
I find the Java love/hate intriguing, I personally like the ideal of 'getting the job done'.

Pre Java 8 is just fine, I don't think it's materially changed, I think what has changed is perception i.e. the realization that all that Enterprisy cruft 'does not equal' Java - nor do wee need FactoryFactor patterns.

My wishlist: - Stream syntax was nice, but a little clumsy - In addition to data objects, some kind of 'un-typed' object (better than a Map) for dealing with json-ish type data, right in the syntax. - First class functions instead of lambdas - Async notation as a better way to express threads, or even combining within the same thread - Union types

For compilation, you should check out Graalvm, which has some neat new features there.

Re:Love It or Hate It, Java Continues to Evolve by Nursie on Monday June 17, 2019 @08:41AM (#20202284)
> Async notation as a better way to express threads

CompletableFutures?

You don't deal directly with threads in java (unless you want to) these days.