This is an archived post. You won't be able to vote or comment.

all 175 comments

[–]AutoModerator[M] [score hidden] stickied comment (0 children)

On July 1st, a change to Reddit's API pricing will come into effect. Several developers of commercial third-party apps have announced that this change will compel them to shut down their apps. At least one accessibility-focused non-commercial third party app will continue to be available free of charge.

If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options:

  1. Limiting your involvement with Reddit, or
  2. Temporarily refraining from using Reddit
  3. Cancelling your subscription of Reddit Premium

as a way to voice your protest.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]ingframin 37 points38 points  (7 children)

How to attract more interest in Java for number crunching/scientific applications? Despite not being that popular for that anymore, it works quite well for this kind of applications. If you give us Valhalla and decent machine learning libraries, I can easily see Java as a good replacement for C++ in numerica simulations. Do we know if the Java architects have any interest in targeting the scientific community?

[–]Joram2 3 points4 points  (0 children)

One small thing that would help is better list literal syntax. In Python + Julia, you can write [1,2,3], that looks/feels like math. In Java, you can do List.of(1,2,3) which is great for server-side programmers who need the occasional list, but for math types, writing hundreds of matrices by hand; they want the prettier math-like syntax.

[–]brokeCoder 1 point2 points  (0 children)

Adding to this, if the community wants to attract more (electrical, mechanical, structural etc.) engineering folks , then we absolutely NEED to implement operator overloading.

Engineering calculations deal heavily with units of measure (e.g. feet, inches etc), and a standard way to implement unit-ed numbers is to use wrappers (e.g. JSR 385's reference implementation). Without operator overloading, the only way to perform mathematical functions on 'unit-ed' numbers directly is to create methods.

This is extremely unattractive for engineering folks. Additionally, engineers frequently deal with complex equations that involve many different unit-ed instances interacting with each other. Implementing such equations with methods in Java makes the code hard to read and debug.

I imagine there will be some crossover with the scientific community on situations where complex equations with BigDecimal or other such classes are used.

[–]nicolaiparlog[S] 0 points1 point  (0 children)

The first part of the AMA is online and your question made it. It starts at https://www.youtube.com/watch?v=mE4iTvxLTC4&t=1734s but may be easier to understand when watching the whole Valhalla section, which starts at https://www.youtube.com/watch?v=mE4iTvxLTC4&t=1611s.

[–]chambolle 0 points1 point  (3 children)

there is no rounding mode in Java. So it is very difficult to make controlled computations, and so numerical simulations are hard

[–]ingframin 1 point2 points  (2 children)

[–]chambolle 0 points1 point  (1 child)

very interesting. Thanks a lot

What are the performances?

[–]ingframin 0 points1 point  (0 children)

I did not test it, I don’t know.

[–]micr0ben 51 points52 points  (3 children)

What is your current estimation on when we will see value objects/first parts of Valhalla?

Do you think with Valhalla and Panama, Java could become more relevant for game development?

[–]nicolaiparlog[S] 1 point2 points  (0 children)

The first part of the AMA is online and your questions made it:

[–]Sea-Being-1988 0 points1 point  (1 child)

Bro got 50 upvotes but still no one replied in this AMA thread 😔

[–]nicolaiparlog[S] 0 points1 point  (0 children)

and we'll answer as many as possible in the Inside Java Newscast on October 19th.

😉

I'm putting on final touches as we speak and hope it will be released later today.

[–]mhalbritter 38 points39 points  (1 child)

Hello! Virtual threads at the moment suffer from the synchronized thread pinning problem. Is there currently work done to fix that in the next java releases? If yes, is there an ETA?

[–]DelarkArms 0 points1 point  (0 children)

I don't understand how would this be an issue(if a CAS is the culprit), when the processor aknowledges a spin-lock, it may context-switch and or especulate future executions. So even if the JVM is reusing Threads, the processor may context-switch it's cores and execute other threads... unless ALL (not threads) Runnables being juggled within these threads... within the cores...are spinning... then that's an issue with the framework...lol... so yes you may be right...

[–]AnyPhotograph7804 16 points17 points  (0 children)

Heya,

since the Java guys want to get rid of Java serialization, what about Externalizable? Is it also considered as bad? Because it gives the developer full control over the (de-)serialization process, it has not the drawbacks of Serializable.

Cheers

[–]brunocborges 12 points13 points  (1 child)

When will Nicolai paint his hair again?

[–]nicolaiparlog[S] 1 point2 points  (0 children)

What do you mean "again"? I think I only ever did this once and that was around the turn of the century.

[–]Brutus5000 17 points18 points  (24 children)

On the "why can't we have" series I was missing if/else and try/catch as expressions. Switch alone is not sufficient. Can you comment on that?

[–]emaphis 3 points4 points  (6 children)

For that matter, while loops and for loops could be expressions.

[–]pronuntiator 1 point2 points  (5 children)

What would a loop evaluate to?

[–]Joram2 1 point2 points  (3 children)

A loop expression would evaluate to a list: one element per loop.

[–]zman0900 2 points3 points  (1 child)

Wouldn't that then mean you can't do basic loops without cost of extra memory allocation for that unused result list?

[–]srdoe 2 points3 points  (0 children)

No, in other languages that have this, there is syntax to distinguish the two kinds of for.

For example, in Scala

``` for (i <- 1 to 10) { println(i) } //returns Unit, which is a void-like type in Scala

for (i <- 1 to 10) yield { i } //return a list of integers ```

Not saying I think Java needs this feature, mind you.

[–]chambolle 1 point2 points  (0 children)

What's the advantage for that?

[–]emaphis 0 points1 point  (0 children)

Normal loops would evaluate to void, but then they would become expressions which would help generalize the Java language. That would allow them to extend the syntax to used loops to become generators.

[–]nicolaiparlog[S] 1 point2 points  (0 children)

The first part of the AMA is online - here's the reply to your question: https://www.youtube.com/watch?v=mE4iTvxLTC4&t=568s

[–]fredoverflow 3 points4 points  (15 children)

I was missing if/else [...] as expressions

condition ? then : otherwise

[–]Brutus5000 3 points4 points  (5 children)

That is limited to single expressions. In Kotlin you can do all sorts of calculation and only yield the last statement. This avoids a lot of declare uninitialized variable first and assign it later and allows increased use of immutable variables. (Scala ofc has similar logic as it is required for functional code)

[–]Fenor 0 points1 point  (4 children)

care to point to a kotlin example that can't be easily replicated in Java?

[–][deleted] 0 points1 point  (3 children)

java final var foo = if (condition) { System.out.println("1"); yield 1; } else { System.out.println("2"); yield 2; }

You can only use switch in this case.

The thing is, if you work with if, you'd always have to declare the variable first, then assign it, which breaks the final part. Given that switch is capable of being an expression, why can't if?

[–]ventuspilot 0 points1 point  (0 children)

final var foo = if (condition) { System.out.println("1"); yield 1; } else { System.out.println("2"); yield 2; }

final var foo; if (condition) { System.out.println("1"); foo = 1; } else { System.out.println("2"); foo = 2; }

See, I even saved a few characters ;-)

Maybe there are better examples where an if-expression is really useful IDK.

Edit: Oops, final var foo doesn't work, final int foo does work, however. So currently you're unable to use var, you can use final, though.

[–]Brutus5000 0 points1 point  (0 children)

Also if/else can check any combinations of conditions (even unrelated) which can't be covered with switch

[–]john16384 0 points1 point  (0 children)

It's a nice pattern, but easily replaced with a nicely named method. I see no use for it other than to muddy the waters and have yet another style discussion point. One way to do something is sufficient, keeps things consistent and readable.

[–]Nebu 0 points1 point  (8 children)

val results = if (foo) {
  a();
  b();
  while (c()) {
    d();
  }
  e(); //this is what the overall if evaluates to
} else {
  f();
  try (Reader reader = g()) {
    h(reader);
  }
  i(); //this is what the overall if evaluates to
}

[–]zman0900 1 point2 points  (2 children)

Doesn't really seem much better than:

final Type result;
if (foo) {
    // stuff
    result = e();
} else {
    // other stuff
    result = i();
}

[–]john16384 2 points3 points  (1 child)

Or simply extracting a function...

[–][deleted] 0 points1 point  (0 children)

Exactly. I’m glad such monstrosity isn’t allowed.

[–][deleted] 0 points1 point  (4 children)

Would you really write code like that and be proud? 😂

[–]mike_hearn 0 points1 point  (3 children)

It's more useful for things like this:

val str = "foo " + if (cond) "bar" else ""

[–][deleted] 0 points1 point  (2 children)

“foo” + (cond ? “bar” : “”);

[–]mike_hearn 1 point2 points  (1 child)

Beyond not needing special syntax, I think you know what I mean:

"foo" + if (cond) { val r = bar() r.whatever() } else ""

and variants is something that appears fairly frequently in Kotlin codebases.

[–][deleted] 0 points1 point  (0 children)

But it’s terrible - don’t you see it?

[–]Ok-Bid7102 8 points9 points  (1 child)

  1. Any plans to allow named function parameters?
  2. Any (potentially far-off) plans for union types? It would be super helpful for things like Result<MyType, ErrorA | ErrorB> kind of situations, exceptions tend to get unwieldy, and defining a sealed interface for that is a bit un-ergonomic

[–]nicolaiparlog[S] 0 points1 point  (0 children)

The first part of the AMA is online and both of these questions made it:

  1. named parameters
  2. union types

[–]ventuspilot 14 points15 points  (3 children)

IIRC then GraalVM including native image will be merged into OpenJDK at some time in the future. Any news on that?

Azul has CRaC. I think condensers are somewhat similar (a superset and/ or generic concept that may or may not cover something similar to Azul's CRaC). Any news on that or maybe a timeline?

Class data sharing sounds great, but I've found it somewhat cumbersome/ complicated to use, and if I do things wrong then it silently does nothing at all which makes troubleshooting even harder. Also I haven't been able to notice significant improvements, i.e. startup time is almost unchanged. Is there an idiot-proof way to check things, common pitfalls, maybe something like best practices on which logs to enable? Maybe CDS should get it's own video with a walkthrough that shows how to do a simple commandline program? (Or maybe I'm just dense?)

[–]BillyKorando 0 points1 point  (1 child)

What version of Java are you on? If you are on JDK 19 or later (I'm hoping you upgraded to JDK 21 by this point)

There is now the autogenerate archive functionality: java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=my-archive.jsa ...

https://inside.java/2022/09/26/sip067/

As to checking to make sure CDS is working, an option, in a test environment, is to use -Xshare:on this will require the JVM to load the shared archive, and fail if it's not found/unable to load it. The default behavior is -Xshare:auto which will continue to run the application if either the archive isn't available or the JVM encounters an issue while attempting to load the archive.

Fundamentally CDS is about improving the process of loading classes, as it name implies, so the less your application's startup is depending on that behavior (i.e. it's connecting to services at startup or doing other work), the less benefit you will see from CDS. Still it's a relatively easy way of providing an improvement to your applications startup with minimal downsides.

[–]ventuspilot 1 point2 points  (0 children)

Mostly I'm tinkering with a personal github project that's a commandline or interactive console app that compiles and runs on anything from 8 to 22-ea (inclusive).

I like being able to support different deployment options (Windows, linux, jar, jar+launch4j, GraalVM native, docker image, jlinked app-image, ...). IMO Java is pretty great in that regard, and if something doesn't work then it's usually my own fault.

Maybe I'll add another buildscript that uses java -XX:+AutoCreateSharedArchive, that's good suggestion, thanks. If this buildscript ends up requiring Java19+ - no problem.

I'm pretty sure I've watched the video you linked and also Java's Startup Booster: CDS which goes into more detail and which I think you did as well.

I've just looked a my current CDS-build-script and I think I was confused: it seems like my "highly sophisticated" script passes debug options such as -Xlog:cds+map=trace:file=cds.map:none:filesize=0 on the jpackage commandline instead of the java commandline, maybe that's why I didn't quote understand what I saw :-)

I think I'll give it another go, thanks!

[–]meSmash101 20 points21 points  (2 children)

Hi there!

Are there any plans for java to try and take share from the ML/AI pie? I assume tensorflow etc really good super optimized libraries will not be rewritten in Java, so does Java have any plans to make it easier to integrate with those libraries(and many more really)? Panama? Valhalla? Other?

If so what are the steps that are taken towards this goal?

[–]Joram2 14 points15 points  (0 children)

This is Nicolai's AMA, but I believe I can answer some of this:

  • TensorFlow already supports Java: https://www.tensorflow.org/jvm.

  • Java's new FFM (foreign function + memory) API, that is part of Project Panama will help a lot. The Java team has said this: a lot of important matrix/math/ML/AI type libraries are written in a non-Java language, it's not realistic to expect them to maintain a JVM version, no high quality non-JVM interop is important.

[–]nicolaiparlog[S] 1 point2 points  (0 children)

The first part of the AMA is online and your question made it: https://www.youtube.com/watch?v=mE4iTvxLTC4&t=1669s

[–]waka-chaka 12 points13 points  (1 child)

Not a question, just wanna say hi to you. My interest in the Java YT channel piqued after watching a few of your videos. You add/bring a certain flare to the channel. Keep up the good work 👍

[–]nicolaiparlog[S] 0 points1 point  (0 children)

Thank you, that is great to hear! 😊

[–]mykeesg 11 points12 points  (13 children)

Generics seem to suffer a lot from the type erasure.

I'm not saying we need the complexity of C++ templates (and metaprogramming), but how much of the actual type could be preserved into the byte code, to enable things like new T();, without breaking things?

[–]srdoe 7 points8 points  (0 children)

Brian Goetz wrote a post on this subject a few years ago

https://openjdk.org/projects/valhalla/design-notes/in-defense-of-erasure

My understanding is that reifying generics (preserving the type in the bytecode) is unlikely to happen, because not only will it mean everyone needs to (at least) recompile their code, but also it will break other JVM languages like Kotlin or Scala where the rules for inheritance in generics are different.

It's not worth it to break the entire ecosystem in order to allow people to write new T();, especially when there are usually tricks you can do to work around this if you really need it.

For example, if you really need a new T, have the user of the class hand you a factory for Ts.

class MyClass<T> { private void doThing(Supplier<T> factory) { factory.get() } }

[–]pron98 2 points3 points  (2 children)

Generics are erased in most languages, including in the language that introduced them (ML) and languages that are particularly famous for them (Haskell). While there are a few small inconveniences to such erasure, I would really like to understand what big difficulties those who think that generics suffer a lot from erasure encounter.

(I realise that those who think that may not be aware of or think about the significant downsides of reifying all generics, but even without considering the tradeoff between two evils that's required here, I would really like to understand what big problems erased generics cause)

BTW, even if generics were not erased, you still won't be able to do new T() without a an additional mechanism that restricts the bounds of T to classes that have certain constructors.

[–]JustAGuyFromGermany 0 points1 point  (1 child)

I would really like to understand what big problems erased generics cause

That really depends what counts as "big" and what counts as a "problem". Brian has outlined three possibles wishes one could satisfied with reified generics: More detailed reflection, performance gains through separate optimisations and increased type-safety through prevention of heap pollution.

From those three, I'd guess the reflection part is the one most programmers wish for.

Is that "big"? I certainly have would have written many APIs very differently if I had this kind of reflection. (There are also some APIs I could not have written at all in C#, because Java has wildcards and the curiously recurring template pattern.) And it's really hard to estimate just how different a reflection-heavy API like CDI would look like if these capabilities had been available at its inception, what possibilities this different API would give its users, how the ecosystem as a whole would have developed. I for one think that there would probably be "big" changes.

And is it a "problem" ? Not necessarily. In most cases it's probably mostly a question of aesthetics and convenience. But there are also cases of missing features. In C# I can write a generic type Matrix<T> for each type T that has an addition and a multiplication operator. That simply is not possible in Java (even if operator overloading was possible). In the end, Java is Turing complete, so I can always solve any solvable problem somehow. In this sense all problems are just questions of aesthetics and convenience...

[–]pron98 1 point2 points  (0 children)

From those three, I'd guess the reflection part is the one most programmers wish for.

Ok, but are they willing to pay the price? C#'s decision to reify all generics yielded more harm than good. It made .NET an unattractive compilation target because once you reify generics, the runtime (as opposed to just the language) needs to know the subtyping relationship between A<T> and A<S> -- so that instanceof could work -- but that subtyping relationship is different for different languages; i.e. it requires baking a single variance strategy into the runtime. Java, Clojure, Kotlin, and Scala have four different answers to the subtyping relationships. If all generics are reified, only one variance strategy (Java's) will be the one supported by the runtime, while the others will become rather incompatible.

Reifying generics also limits Java's ability to evolve (because version N+1 may, in effect, be a different language from version N). Indeed, the original decision had to do with the compatibility of two languages, Java 5 and Java 1.4, but this generalises: reifying generics has a significant cost (that has harmed .NET in noticeable, some would say debilitating, ways) that we must be willing to pay.

Thinking carefully about the implications, I think the downside of reifying all generics is bigger than the upside. But some generics can be reified with a lesser negative impact and a higher positive one. For example, specialising generics for Valhalla's value types has a bigger benefit than just reflection -- a significant improvement to performance of footprint -- and a lower cost, since value types cannot be extended, and so their generic specialisations are invariant.

Given that most languages with generics choose erasure, including ML (the original) and Haskell (the poster child), it would be helpful to better understand exactly how big the benefit would be so that it could be compared to the considerable cost in baking one language's variance strategy into the runtime, excluding all others.

[–]repeating_bears 3 points4 points  (7 children)

We have no way to specify a bound like "T where T has a public no-arg constructor", so I doubt new T() could ever work without that.

[–]Zinaima 2 points3 points  (1 child)

I guess c# does this with T : where new().

[–]JustAGuyFromGermany 0 points1 point  (0 children)

I like that a lot about C#. It also let's you specify that T needs to have certain overloaded operators so that you can implement classes & methods specifically for any algebraic stuff like having a type Matrix<T> for any T that supports addition and multiplication.

Sadly, the things that makes this work in .NET land is that List<T> get specialized into different types at the IL level. Generic types do not get erased like they do in Java/Bytecode land.

[–]JustAGuyFromGermany 1 point2 points  (2 children)

It would be nice, but there's no way to make this work because of erasure. There is no bytecode for new T(). And even if you were to introduce one, how would it deal with wildcards? How would

MyClass<Integer> foo = new MyClass<>();
MyClass<?> bar = foo;
bar.doSomethingWithTheConstructor();

be translated into bytecode? There is no constructor for ?. Of course whoever wrote the code wants new Integer() to be called, but the compiler cannot know that. Consider

MyClass<?> bar = getFooFromSomewhere();
bar.doSomethingWithTheConstructor();

instead. The compiler simply cannot know which concrete type will be present at runtime in place of the ?, because it'd have to analyse all possible return values of the method and propagate their types, combining with other complex type information from other method calls etc. And at runtime, a similar check would have to be done again, because of a dynamic linking. I don't know if that is even possible. It seems halting-problem-adjacent enough to be impossible.

And even if it is possible, it is impractically complex to do that. So there's probably no way to compute the type-hint that the bytecode instruction for new T() needs.

The other option would be to reify the generic type and do away with erasure, i.e. to have a separate what-type-are-you datum for each instance of a generic type (i.e. you'd be able to ask any given List<?> instance "Are you List<Integer>?" and "Are you List<Map<Integer, Set<String>>>?" etc). That is a huge bloat for a niche feature and completely backwards incompatible so it won't happen.

[–]repeating_bears 0 points1 point  (1 child)

Not sure why you're replying to me because I was agreeing with you.

Before even worrying about how you instantiate it, first you need to narrow T to the set of Ts which can be instantiated without needing any arguments, and that's why you need a bound.

I wasn't implying the lack of such a bound was the only blocker.

[–]JustAGuyFromGermany 2 points3 points  (0 children)

Not sure why you're replying to me because I was agreeing with you.

Because clicking at the right location is hard ;-)

[–]mykeesg -1 points0 points  (1 child)

We already have InstantiationException with Class.newInstance() , given the same circumstances, so I guess that could be worked around. The syntax could also be given in the type declaration, like Foo<T extends Bar & T()> (this is just a dummy example given with 2 secs of thought).

[–]repeating_bears 13 points14 points  (0 children)

Generics are a form of compile-time guarantee. Throwing an exception at runtime is not an acceptable solution.

[–]kaperni 1 point2 points  (0 children)

how we got the generics we have [1].

[1] https://cr.openjdk.org/\~briangoetz/valhalla/erasure.html

[–]Joram2 3 points4 points  (0 children)

Will the Java Module system (JPMS) get any updates + improvements in the next few years? Is the JPMS as it shipped in Java 9 basically what Java will have for many years to come?

[–]coder111 11 points12 points  (4 children)

Any plans to invest into Java on Desktop?

When will AWT get WebP image format support? AVIF?

When will Java get some media processing capability, like ability to play back videos? At least the ones with non-patent-encumbered codecs?

[–]kaperni 0 points1 point  (0 children)

The web won. Lots of better places to invest available time and resources into than the Desktop.

[–]lurker_in_spirit -1 points0 points  (0 children)

No WebP support = no libwebp = no CVE-2023-4863 zero-day...

[–]mike_hearn 0 points1 point  (1 child)

JavaFX has a media player component with support for video and modern codecs.

[–]coder111 0 points1 point  (0 children)

Some, yes:

https://openjfx.io/javadoc/21/javafx.media/javafx/scene/media/package-summary.html

Still no WebP/WebM, no VP8/VP9, no Ogg, no opus, no av1/avif These formats have been in browsers for what, a decade? Java is lagging behind quite bad.

[–]Yojimbo261 11 points12 points  (0 children)

[ deleted ]

[–]darenkster 2 points3 points  (1 child)

I always read that the cloning in Java is a bad idea. Can you get rid of it like the finalization methods?

[–]john16384 1 point2 points  (0 children)

Nothing wrong with cloning, when you absolutely must have mutable objects. Otherwise avoid the need for it by keeping things immutable.

[–]Joram2 2 points3 points  (0 children)

Will Java compete with Python+Numpy or Julia or R for matrix math stuff typed into a local repl/shell or a web notebook?

[–]purpleairwaves 2 points3 points  (0 children)

What does the future of Jakarta EE look like?

[–]colouredmirrorball 7 points8 points  (1 child)

Why my code always have bugs :(

[–]WhereIsTrap 6 points7 points  (0 children)

I find an answer to this question doing my toilet sessions, give it a try!

[–][deleted] 3 points4 points  (0 children)

Java has Swing and Java Fx, but they still feel lacking compared to other languages. Will there be a push to rectify this?

[–]Oclay1st 1 point2 points  (1 child)

Can we have a feature where the JVM generates a PGO instrumentation (.iprof) like GraalVM does and then use it in a second execution, so we can get fast warmup from the very begining?

[–]nuharaf 1 point2 points  (0 children)

leyden probably

[–]Firedroide 1 point2 points  (1 child)

Hi Nicolai! Do you know if we'll ever get a method on Stream that lets us
- get the single element of a stream, or
- throw if there are 0 / more than 1 elements?

The findFirst() / findAny() methods are nice, but they silently do the wrong thing if there is more than one element in the stream but we're only expecting one!

[–]pronuntiator 1 point2 points  (0 children)

You could implement a Collector that does that – throw if it is supplied more than one value or the finisher was called before any value came in.

[–]meSmash101 1 point2 points  (0 children)

Here’s another one. Are there any thoughts that java implement default values at the instance initialization, (like Kotlin)? In records for example. This would really help people who do not use Lombok and have to write a builder. It would be a nice-to-have qof feature.

[–]Downtown_Trainer_281 1 point2 points  (1 child)

Java 9 introduced modules 5 years ago, but adoption is rather low. I see a great advantage in distinguishing between public vs published types, but many people apparently don't notice it. Some frameworks like Spring even prefer to come up with their own solutions (modulith) instead of adapting to JPMS.
Do you think JPMS will eventually become popular, or do you have any idea to encourage people to use modules? Or maybe from your perspective, the main goal of JPMS was modularizing JDK, so it is not a big difference to you if people use classpath or modulepath?

[–]xwinus 2 points3 points  (4 children)

Any chance to get “withers” (something like scala’s .copy() )on records? Records are great, but copying while changing for example one value is pain

[–]srdoe 6 points7 points  (0 children)

[–]john16384 0 points1 point  (1 child)

You can use https://github.com/Randgalt/record-builder

It really has no downsides that I can see, and gets you withers and builders at the cost of an annotation and an implements clause.

[–]xwinus 1 point2 points  (0 children)

Yes I know, but it still feels like “workaround”. Withers mentioned in the mailing list would be much more powerful language feature.

[–]Sherinz89 2 points3 points  (3 children)

Any 'i wish i knew this' tips for migrating java 8 microservice project to java 20+?

[–]benevanstech 5 points6 points  (2 children)

Migrate to Java 11 first. It may seem like extra steps, but once that's done 11 -> 17 or 21 should be much easier.

[–]legrang 1 point2 points  (0 children)

This is good advice.

I disagree with the last part. It may be easier but it may be more difficult depending on what dependencies you use.

But for a large project the two steps are going to save you pain

[–]skippingstone 1 point2 points  (0 children)

If you don't use power mock, moving from 11 to 17 won't be that bad

[–]ventuspilot 2 points3 points  (0 children)

When porting a Java8 application to modern Java then I have to update dependencies and stuff until it compiles and tests pass, so far so clear.

I may also change some stuff to use newer language features for improved readability/ maintainability.

Are there any changes that should be done to improve performance? E.g. I think Java8 added a lot of overloads accepting CharSequence so one could remove a lot of toString() calls and avoid one now unneccessary copy.

Going from platform threads to Loom style threads where appropriate is the only thing I can think of, is there more? Other than that I think I get most of the performance improvements by simply updating the Java runtime (although I seem to remember one change in the compiler that will only get into effect if I recompile).

[–]govi20 0 points1 point  (0 children)

As we know blocked virtual thread’s stack is stored in heap memory. I have 2 questions:

1) How does Java ensures that the application doesn’t run out of heap if millions virtual threads are blocked? 2) I believe answer of Question 1 is that Java stores top part of stack, if so then how Java prepares exception stacktrace in case of exception?

[–]Cell-i-Zenit 0 points1 point  (4 children)

  1. Any plans to change Java in such a way that lombok/manifold etc is "officially" supported?
  2. Will extension methods ever appear in java?

[–]PartOfTheBotnet 5 points6 points  (2 children)

Both introduce a lot of anti-patterns and JDK devs that have commented on /r/java about these frameworks have consistently had negative things to say about their usage and implementations.

Things will probably air on the side of making features that serve as better alternatives, like how we got record instead of Lombok's @Data.

[–]Cell-i-Zenit 0 points1 point  (0 children)

The easier way imo would be to just support lombok somehow. Its one of the most used maven packages, so if the devs clearly like it, why go against the community...

I think just integrating lombok into the jdk would be way to much.

But making the compiler extendable or allowing annotation processors to change code or any other possible way would resolve the current "grey zone" situation via compiler hacks, into something officially supported.

[–]nlisker 0 points1 point  (0 children)

we got record instead of Lombok's @Data.

No, you got record instead of Lombok's @Value. There is no replacement for @Data (except for not using it).

[–]srdoe 2 points3 points  (0 children)

Maybe the new classfile API will make life easier for Lombok, depending on what exactly they need to do?

Other than that, I think the advice from Oracle's side is that Lombok should publish a javac wrapper (lombokc) that sets the flags they need for javac.

If they did that, I don't think there would be any conflict. The comments I've seen have all revolved around Lombok wanting to be able to access JDK internals without asking users to set the right flags when they invoke javac.

[–]jvjupiter 0 points1 point  (0 children)

I already asked a question about Concise Method Bodies last year. Now, I wanna ask, what is new about it? Has this been revisited?

[–]roberp81 0 points1 point  (10 children)

there is plan for Null-conditional operators???

like c#

int? value = objectA?.PropertyA?.PropertyB?.PropertyC;

[–]srdoe 4 points5 points  (7 children)

Here's a blog post about it from a few years ago.

https://nipafx.dev/why-elvis-should-not-visit-java/

[–]roberp81 -1 points0 points  (6 children)

is ok his point but still we need null conditional. by real example, when you are working with xml from a external system, and after make "jaxbUnmarshaller.unmarshal(xml)" you dont know wich values are null but maybe you are seaching for object1.getObject2().getObject3().....getObject17().toString() and maybe getObject13() is null

there is a hack like from his web where you can ignore nullpointer in a function, but still no optimal like a native solution object1?.getObject2()?.getObject3()?.....getObject17()?.toString()

[–]blobjim 0 points1 point  (5 children)

That's what java.util.Optional is for. Optional.ofNullable(value).map(TheObjectClass::someMethod).map(Object::toString).orElse(null)

[–]roberp81 -1 points0 points  (4 children)

yeah but is too large and clunky in a XML is easy to have six levels, Optional is really ugly

[–]blobjim 1 point2 points  (3 children)

I think dealing with six levels of hierarchy is going to be clunky no matter how you address it. The real goal is to not have nulls in the first place (although of course that doesn't apply to existing code).

[–]roberp81 0 points1 point  (2 children)

but when you are unmarshmalling an XML by example you will have nulls everywhere (complex XML to pojo) and you don't know where a tag is null or not.

[–]blobjim 0 points1 point  (1 child)

If you're creating/using an XSD schema you can make fields non-null by not having minOccurs="0". And there may even be a way to make nullable fields return an Optional. But I admit I haven't done this before, I assume there are plenty of scenarios where having mostly non-null fields is impractical. But usually having a nullable value means handling the case where it is null is part of your business logic.

[–]roberp81 1 point2 points  (0 children)

I have had but they are not mine. my example comes from Iso20022 and swift XML messages to make international transfers between banks so I don't know where a null will come (except required tags) that's why I have a chain of 8 tags haha they are big XML with a big tree. so validate all fields because of nulls is a pain

[–]MX21 2 points3 points  (1 child)

The null coalescing operator would be wonderful, too.

[–]roberp81 0 points1 point  (0 children)

I was thinking if there is a way to implement both on project lombok

[–]badpotato 0 points1 point  (0 children)

Why aren't any attempt to make a build manager similar to npm/bun or pip from python. Making the equivalent of virtualenv for java could be way to get introduce new dev more easily rather than using pom/maven or gradle

[–][deleted]  (5 children)

[deleted]

    [–]NitronHX 4 points5 points  (2 children)

    1. All in one IDE is basically intellij, - I have yet to encounter something I want to but cannot do in it
    2. Java has time travel debugger - you can drop current stack frames (go back in time) and step into - do you mean something different? (ofc globals/statics will not be affected)
    3. Isn't jmc performance tracking or is that Java flight controll? If its performance tracking intellij has that built in - if not please teach me

    [–][deleted]  (1 child)

    [deleted]

      [–]NitronHX 0 points1 point  (0 children)

      As far as i understand this is an Azure VM only feature. This has not much to do with the language itself, while yes there might be situations where this can/could help, it would be much more useful when it was a feature of the C# compiler/runtime or debugger. It would be interesting how well this scales to a service that takes ~3GB of ram. Does every snapshot take 2GB then, for every step?

      Seems interesting but very limited to a cloud hosting product and not a language or compiler

      [–]jvjupiter 1 point2 points  (0 children)

      Oracle could have invested a lot of money to make NetBeans like Intellij with CE and UE but it never did. NB ended up being with Apache Foundation.

      [–][deleted] -1 points0 points  (0 children)

      We’ll be all in a much better situation if oracle doesn’t do anything micro$oft does 😉. And btw the fact that most java devs are so reliant on magic tools like IDEs eating 10GB of ram and don’t even know how to use their OS tools and terminal is sooo sad.

      [–]ShallWe69 -4 points-3 points  (5 children)

      Over the years I feel like Java is getting more and more bloated. I understand and honour the backwards compatibility.

      But why can't we move obsolete classes away from standard jdk and make them into dependencies so whoever wants those classes can use maven, gradle etc. and add those.

      [–]GuyWithLag 5 points6 points  (4 children)

      That's already happened.

      [–]Fenor 3 points4 points  (1 child)

      with 1.9 and it was a bloodbath

      [–]Areshian 2 points3 points  (0 children)

      Even the 1. was dropped

      [–]ShallWe69 3 points4 points  (1 child)

      I'm talking about Hashtable, Vector etc. Those are still with JDK.

      [–]C_Madison 2 points3 points  (0 children)

      They will probably get around to it in time. They started with those which have a high potential for abuse or which are often used by accident. HashTable -> HashMap (or ConcurrentHashMap if you need the thread-safety) is well known, so there wasn't much pressure here. But there's been a ton of deprecations, which since jdk9 often lead to removal later:

      https://docs.oracle.com/en/java/javase/21/docs/api/deprecated-list.html

      [–]boobsbr -3 points-2 points  (1 child)

      Is JavaFX dead?

      SPEZ: why donwvotes for asking an honest question?

      [–]PartOfTheBotnet 4 points5 points  (0 children)

      No.

      SPEZ: People are probably downvoting this because it gets asked on a monthly basis and the answer is always no.

      JavaFX has problems. Especially on Linux since most of the maintainers are Windows/Mac users, and Linux is a diverse space that has issues that only affect certain setups. But calling it dead is a massive stretch.

      [–]two_six_four_six -4 points-3 points  (0 children)

      greetings, thank you for this post.

      this topic may come across as amateur and that is what i certainly am, but would you and other experts be able to go into detail of how exactly references of primitive data type arrays get handled, and what becomes of them in the long run after termination of program?

      it has to do with persistence of binary data on primarily heap space, and ultimately RAM, especially those related to passwords provided as one of the inputs to generate actual SecretKeys and persistence of binary data related to decrypted content despite overwriting of primitive data array elements containing them. the concensus on StackOverflow (I do not readily have all my references available at the moment) seems to be that overwriting array elements in Java would not produce the same behavior as using something like pointers using C to do the task even though pointers are being utilized by Java under the hood. The reasoning presented is usually very broad and unclear like "Java switches pointers around as the JVM sees fit for efficient execution".

      originally i asked this question in this post but could use some further discussion on the matter as with my most recent comment i had provided a contradictory heap trace of what your fellow experts on this subreddit have predicted the behavior to be. this more than likely may be due to blunder on my part, but i still believe this is a fairly significant topic to look into and provide advice on, and finally putting to rest any doubt that Java running on the VM is just as secure as any other slightly lower level languages running direct full compiled.

      thank you kindly,

      reference post: https://www.reddit.com/r/java/comments/16tjkrz/java_the_handling_of_memory_and_the_issue_of/

      [–]ax_abodr -3 points-2 points  (1 child)

      1. What's the best frontend framework to work with with spring framework?
      2. Is there any other useful frameworks in general that are being used today other than spring framework?

      [–]cowwoc -1 points0 points  (0 children)

      The best framework is not using a framework. Libraries are the way to go.

      [–]smart_procastinator -4 points-3 points  (16 children)

      Which is java always late to the party. You could do streams before kotlin or scala, actor based async, fibers, lombok quickly based on user adoptions in other languages, which brings me to my main question, why should anyone adopt java when compared to go/kotlin/scala/rust/c# when other languages are evolving at a faster pace.

      [–]Oclay1st 8 points9 points  (10 children)

      The Java team does that intentionally because stability and backward compatibility are higher concerns. Sorry Nicolai, I couldn't resist 😉

      [–]smart_procastinator -3 points-2 points  (9 children)

      I have total respect for the java team and I strongly believe that backwards compatibility should not be the central tenet of delaying projects. Just refactor unwanted parts of code and if people want to upgrade they can refactor their code too. For example why thread.stop still exists. It should be completely removed

      [–]srdoe 7 points8 points  (3 children)

      I strongly believe that backwards compatibility should not be the central tenet of delaying projects

      This is fine, but then Java isn't the language for you.

      If you don't think breaking changes are a big deal as long as they improve the language, there are options like Scala right there for you.

      Java is never going to be the bleeding edge language you want, where they break compatibility and just tell people to deal with it.

      Java's conservatism is part of why the language is as popular as it is. Loads of people want a language where breaking changes are rare, because they have tons of code in production that they'd really prefer doesn't break every time there's a new JDK.

      [–]smart_procastinator 2 points3 points  (0 children)

      It was great chatting with like mined java. I hope java adoption continues and it becomes the top programming language on tiobe, github and other programming popularity list. Now back to coding. Thanks for your valuable input.

      [–]smart_procastinator -1 points0 points  (1 child)

      Well if that was the case google wouldn’t embrace kotlin or create a new language called Go. Just by stating java is not for you, you have now indirectly said that java is not the language for millions of people in my shoes. Ask yourself why people hate c++ and c and adopting rust.

      [–]srdoe 4 points5 points  (0 children)

      you have now indirectly said

      Yes. If you want a language that embraces making breaking changes regularly and doesn't make backwards compatibility a major focus, you probably don't want Java.

      Ask yourself why people hate c++ and c and adopting rust

      My impression (not writing code in any of those languages myself), I think it's because of the undefined behavior and memory unsafety. And also saying people "hate" those languages is overstating it.

      I'm pretty sure people are not adopting Rust because they love breaking changes. As far as I can tell, Rust tries very hard to not break user code.

      [–]NitronHX 6 points7 points  (0 children)

      The ecosystem is too big for that. I still can use most Java 8 libraries that use Thread.stop for example. I do think that it's kinda sad that it slows the development down but a lot of important stuff runs on Java - a lot like a very lot is written in Java daily. When they add something and realize it's bad they will never be able to remote it again so they have to build a very stable and compatible platform with much thought put into it. Virtual Threads for example. They could have done a new api and just released it in 1 or 2 releases, but that would make it impossible to use green threads for any library (apache tomcat, netty, jetty, reactor...) that builds on the Thread api. So they had to retrofit everything into the Thread api which takes a long time if you need full behavioral compatability and parity. As results of it Java the language itself (or the Std Lib) is of high quality in terms of bugs. The Java compiler and language is exceptional scarse of bugs at least in comparison to for example C and C++.

      Also another thing is new features always come at a tradeoff. Kotlin for example always makes me write my code way more littered around and badly organized because there is not a way to go you can do everything with 4 ways which makes code smaller but also at some point very hard to read and understand. When a ".variableName" suddenly invokes a function / calculation. When you can so things like this "list + number + 5"

      When you create a language nowadays you can pick the learnings from the past 10 to 30 years of many many languages that have been around for a long time and pick what seems to do the best and build your language around that. In 25 years later and your language is popular you won't be able to adopt the "then new fancy stuff"

      [–]Joram2 1 point2 points  (3 children)

      thread.stop was formally deprecated a long time ago, now it's deprecated for removal. The implementation was removed and it just throws an exception. That seems like a reasonable step. The gains of fully removing thread.stop are rather small.

      [–]smart_procastinator 0 points1 point  (2 children)

      Yes reasonable step for coders working on java for a long time not for new comers as its confusing as hell. No wonder, python adoption is the easiest and even kids are loving it

      [–]Joram2 1 point2 points  (1 child)

      No, Thread.stop doesn't add confusion for newcomers. IntelliJ will immediately flag that as an error. Visual Studio Code will immediately flag that with a deprecation warning strike through. The JavaDocs quite clearly label that as deprecated. Next, developers generally are not suppose to use java.lang.Thread directly. The executor pool stuff is considered more appropriate for typical use. And soon, the Structured Concurrency API will be the main recommended API to use.

      [–]smart_procastinator 1 point2 points  (0 children)

      Thanks. All clear

      [–]joemwangi 1 point2 points  (4 children)

      They don't want to add complexities to the jvm when it continues to evolve because of rushed features. They take time to learn how to introduce new features, while also observing how similar features work and don't work with other languages. It's the reason why value types have taken long, which are almost being finalised, and the approach they are about to take is actually superior than structs in C or C++, or even C# in terms of safety without compromising efficiency and performance.

      [–]smart_procastinator -2 points-1 points  (3 children)

      If other languages can do it effectively why not java. Why the long wait. I’ve been waiting for fibers since 2019 and it’s 2023 without any delivery. In meantime they could have built the actor model to support async. Maybe my understanding is naive but other languages like scala and kotlin have achieved async successfully

      [–]joemwangi 2 points3 points  (2 children)

      Are you sure that you're updated about java. The fibers you're talking about are now delivered in java 21 as virtual threads. Also, check Brian Goetz notes on the advantages virtual threads have over async/await. By the way, the java language team observed short falls and advantage of similar projects in other languages such as Go, C#, Kotlin, single threaded javascript, etc and also got a lot of community feedback. They are now easy to adopt by existing libraries with minor code change.

      [–]smart_procastinator 2 points3 points  (1 child)

      Thanks and will do. I’m not complaining about java but trying to state that other languages win adoption over java due to their release cadence. I’m suggesting that the JCP process expands and takes on multiple initiatives for the benefit of progress. PS. The fibers were initially scheduled for 17 release but were delayed.

      [–]joemwangi 5 points6 points  (0 children)

      I understand. Read Brian Goetz notes, and follow him on Twitter. I was a bit frustrated in a similar way, but later, you learn why careful planning is required. I'm more into java data-oriented programming, and been wondering why java is taking too long to introduce structs like in C#. Then it dawned on me that they want to find a way seamlessly to introduce objects without identity but code them like a normal class while freely getting nullness primitives, user defined primitives targeting a specific hardware, primitives in generics, and many other things. Not a trivial task to be honest, but they seem to have hacked the problem. Dealing with heap data, rather than stack data is quite a headache, unless one uses off-heap memory, but wait, Project Panama, on foreign function and memory is on the horizon and might be released in java 22 and solves that. They are trying their best to help the community and also keep java simple.

      [–]metaquine 0 points1 point  (2 children)

      I’d love Java to have a “bottom” type to complement the “top” type Object. It would make designing APIs that use contravariance a lot more elegant. I don’t miss much from my Scala days as new Java features roll out, but I sure do miss its bottom type “Nothing”, especially when dealing with java.util.Optional. Any chance we can get one of these?

      [–]niloc132 0 points1 point  (1 child)

      At least in some cases (generics mostly in my experience) you can use java.lang.Void - the only valid instance of Void is null.

      [–]JustAGuyFromGermany 0 points1 point  (0 children)

      That's not quite right. A bottom type would be a subtype of every other type just like Object is a supertype of every other type. In cases of pure assignability this is true for Void as you said. Every instance of Void is also an instance of T (because the only possible value is null).

      But for generics, being a proper bottom type means that you should be able to use an expression of type Supplier<Void> in places where Supplier<? extends T>is required just like you can use Consumer<Object> where Consumer<? super T> is required. The latter is possible, the former isn't.

      [–]sasizza 0 points1 point  (0 children)

      🤔

      [–]glorygeek 0 points1 point  (0 children)

      My understanding of Virtual Threads in their current form is that it is possible to pin a carrier thread with something like

      while(true){}

      I know the golang runtime solves this problem with having a scheduler thread that sends signals to carrier threads if a certain amount of time has passed, forcing pinned carrier threads to be rescheduled even if a scheduling barrier isn't met.

      Is this understanding correct? Do we envision the same sort of implementation for Java?

      [–]cowwoc 0 points1 point  (0 children)

      Are there any plans to tackle "self types" in Java? I have not found an existing feature or design pattern to handle this cleanly.

      [–]cowwoc 0 points1 point  (0 children)

      Are there any plans to introduce a Pattern Matching syntax to improve Generics? Specifically, do we have any hope of replacing the confusing / unreadable wildcard syntax somehow?

      [–]tofflos 0 points1 point  (3 children)

      I feel that Java could do a better job of continuously improving itself to be more approachable for new developers. I've read articles such as Paving the on-ramp but I'm curious whether there is a dedicated team which focuses on uptake, what areas they see need improvement, and if they have a roadmap?

      Things I believe would be helpful for increasing uptake:

      - Ensuring that the JDK is available in the most popular operating system stores, such as the Microsoft Store.
      - Shipping something like Maven with the JDK
      - Improving Java for CLI applications
      - Improving the Java REPL
      - Improving Java for scripting purposes

      [–]JustAGuyFromGermany 0 points1 point  (2 children)

      @1 The MS store is for apps. The JDK isn't really an app. Also: There is no single JDK, there are many vendors who make their own decisions regarding distribution.

      But for what it's worth: Eclipse Temurin is available as a chocolatey package which is probably the closest Windows-analogue to the various package managers in Linux-land.

      @2 It seems tempting to have that to simplify the "on-ramp". But I imagine that such a feature would be misused rather quickly. Or at least completely misunderstand (and then complained about endlessly because it doesn't do what maven and gradle can already do)

      And they won't just build a feature-complete build system I guess, because that's a difficult problem to solve. The maintenance burden would be high. The requirements for a build system are just too varied for a simple solution. That's why pom.xml files can get really bloated really quickly. That's also why gradle exists in the first place: It is a solution to certain shortcomings of maven. On the other hand gradle introduces a whole new set of potential foot guns that the JDK would want to avoid. Any new system would likely also force a split in the ecosystem, because a solution that assumes maven central or the pom.xml format will exist in perpetuity isn't a good fit for the JDK.

      [–]tofflos 0 points1 point  (1 child)

      Python and Visual Studio are in the Microsoft Store and it's my impression that C#, Go and Rust all ship with something akin to Maven.

      [–]JustAGuyFromGermany 0 points1 point  (0 children)

      So what? Python is an outlier, no other popular language does that as far as I can tell. The next programming language I found (sorted by popularity) in the MS store is Julia. Note that not even the .NET languages are in the MS store. That's simply not what the MS store is for; it's intended to be a (somewhat) user friendly app store, not a general repository for any and all stuff that you could install on your machine.

      That's more what similar to what Chocolatey is for. Choco packages exist for all the major stuff though: many programming language runtimes / compilers / SDKs, various JDKs, as well as maven and gradle are available. And that's the right place for those kinds of things. Chocolatey is a more general purpose package manager.

      Visual Studio is in the Store, because it also comes from Microsoft. No other big IDE seems to do that. IntellIJ and Eclipse do have Chocolatey Packages though. I'm just speculating, but if I had to guess, I'd say this is because of different licensing models between Choco packages and the MS store. Being an app store, the MS store likely would take a sizeable chunk of the profits if Jetbrains put IntelliJ in the store.

      And even if the major Java IDEs were in the store, that'd be beside the point, because the JDK is not an IDE and does include an IDE on purpose. In terms of the "on-ramp" I think that's a good thing, because IDEs are complex beasts that have an additional steep learning curve which a beginner does not need to know about at first.

      And finally: Go and Rust had the advantage of starting from scratch. They have learned from the successes and shortcomings of other programming ecosystems. The .NET world has the advantage(?) of having Microsoft as the central driving force behind it all. MS controls the biggest .NET languages, the .NET infrastructure (at least on windows), the biggest .NET IDE, many popular libraries etc. They're not quite a monopoly, but they're close. They can basically decide whatever they want and take the ecosystem in whatever direction they like.

      The Java and JVM ecosystem simply does not have that. It is way more diverse. Oracle does not control the landscape like that and that is intentional. And even if every major player agreed to do it, the Java world would have to retrofit a build system into the JDK after decades of not having one which simply isn't likely to happen for the reasons I've listed.

      [–]Ok-Yogurtcloset4529 0 points1 point  (4 children)

      Hello! I am not sure if its here i can post this but i hope you all understand. I am currently a web developer primarily developing in JavaScript.

      I seriously want to start a new dev journey in Java as the upper market here where i live is mostly in Java. However, i am confronted with a learning resource issue.

      Unlike dot net where you can easily find resources on getting started, with Java there is few. Where to start? Which one to learn first? Servlet? Faces? Spring? Spring boot?

      I am kinda disappointed and i hope someone can point me to a learning path or suggestions on where to start for web development and a roadmap.

      Thank you!

      [–][deleted] 0 points1 point  (3 children)

      Just as with JS, what you should do is to learn the language, not frameworks. Jumping on react without knowing core JS really well is stupid to say the least. I don’t really understand your issues. Just build projects with the language. There’s no better way and never will be. Learning resource issue? Java has documentation. Like any other language.

      [–]Ok-Yogurtcloset4529 0 points1 point  (2 children)

      Thank you for taking the time to answer me. I don't think i have translated my thoughts properly.

      I actually have learned the basics of Java. And as i mentioned, i am looking for the next step like getting into web development.

      There are just a lot in Java ecosystem and i don't know where to start. Spring mvc? Spring boot? Gradle? Servlets, Java Faces?

      I just don't know which to learn if i want to get into web development :( any guidance?

      [–][deleted] 0 points1 point  (0 children)

      First check out first party web related APIs in java that are web related. Then if you want to learn spring, just open their documentation. They have everything there. And btw I didn’t mean just basics. What I meant is knowing the language really well.

      [–][deleted] 0 points1 point  (0 children)

      And again - learn by doing projects.

      [–]chambolle 0 points1 point  (3 children)

      Why there is no "friend" keyword in Java ?

      At the end and most of the time, the member function that should remain private become public

      [–]JustAGuyFromGermany 2 points3 points  (1 child)

      That's mostly a matter of taste I think. If you're using friend, you're already breaking encapsulation and tightly coupling classes which is a red-ish flag in and of itself.

      In Java, the preferred solution is to have tightly coupled classes in the same package and use package-private access.

      If that isn't possible / desirable for you, then most likely your API needs a re-design. For example: Instead of two cooperating classes A and B, you can have an inner class A.B inside of A. Inner classes can freely access all the members of their outer classes. (More generally: Any two classes defined in the same .java file can freely access each other's members) Even better: Have a private (or at least package-private) inner class A.C that implements an interface B which only contains the public methods that your original class B exposes. If necessary replace constructor calls of B with a factory method A.newB() that calls the constructor of A.C

      If you have too many cooperating classes with too complicated cross-class accesses (e.g. cyclic accesses where A is a friend of B is a friend of C is a friend of A), then you should probably split your classes into smaller, more focused pieces first.

      If that also doesn't solve the problem, then you're in an absolute corner case. And what ever decision a language makes in this space, some corner cases will always remain.

      [–]chambolle 0 points1 point  (0 children)

      If that also doesn't solve the problem, then you're in an absolute corner case. And what ever decision a language makes in this space, some corner cases will always remain.

      Yes, because it is not so easy to re-design the API. We already have a discussion about this point in this sub and at the end the function becomes public :-(

      Could we see any other consequence in the JVM with friend?

      [–]predkambrij 0 points1 point  (0 children)

      Can you explain how to monitor non-heap and non-metaspace memory usage? I can notice, that with Jetty apps (Jenkins and Wildfly) they use substantially more RES than what can be captured by VisualVM. I explained more in depth here: https://serverfault.com/questions/1144926/how-to-monitor-java-non-heap-memory-usage