Win a copy of Murach's MySQL this week in the JDBC and Relational Databases forum!

Rob Spoor

+ Follow
since Oct 27, 2005
Rob likes ...
Eclipse IDE Spring VI Editor Chrome Java Windows
Merit badge: grant badges
For More
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads

Recent posts by Rob Spoor

Stephan is right.

A better version would be int mthd(Class<? extends Enum<?>> enum), unless the first version should be <T extends Enum<T>> int mthd(T enum).

Which one to use depends on what you prefer to read, and whether or not you need that T inside your method.
2 weeks ago

Stephan van Hulst wrote:That would be a really bad idea.

In essence, that means that I can no longer control whether and how a caller makes an instance of my class, and it also means that I can create instances of classes without providing the bare minimum of information they need for initialization.

Consider the following example:

First of all, you're not supposed to instantiate an Integer directly. You're supposed to use a literal or one of the valueOf() factory methods. Secondly, if you DID instantiate an Integer directly, then what would it even mean to instantiate one without a value?

Remember, according to your proposal, Integer should inherit the parameterless constructor from the Number class.

This could be circumvented by only automatically creating constructors if no explicit constructors exists. If you create just one constructor manually, no more automatically created constructors. That's already done right now with the no-argument constructor, but this would actually change what the compiler does - a single no-argument constructor might not be added anymore, but several others.

I don't think Oracle will implement this, and I won't miss it. Within seconds my IDE can create these constructors just as easily (and those seconds are me find the right context menu item).
2 weeks ago

Tim Holloway wrote:Java supports a "universal" file path notation which is essentially that of Unix. There are conversion rules that can map DOS paths to this notation and they necessarily include the drive ID. So "C:\Program Files\java" maps as "/C:/Program Files/java". Resolving in the other direction is ambgious, so expect that "/" will map to the root directory of the currently-logged drive.

I don't think this is correct. In Windows, it's not allowed to have "/" in file names. Java uses that to translate every "/" into "\", both in the old File class and in NIO/2.
The file path "/C:/Program Files/java" cannot be used in Windows applications. I've seen it though, but I think that's mostly in URIs. You can use it with File but not with Path.of. You can use "C:/Program Files/java" with both though; that gets translated to "C:\Program Files\java".

Windows does have a "\" though (which means you can use "/" in Java). It's the root of the current drive, e.g. "C:\" or "D:\".

Assuming you're not doing something stupid like uploading/creating/altering files within the WAR directory structure. Which will fail horribly on an unexploded WAR.

Not to mention that with exploded WARs, you'll lose those changes after each deployment.

One final note. Java is a very bad language to use a "current directory" in. There's only one current directory for a given JVM instance, and since many processes may be running under that JVM, you can not be 100% sure that one of them might change the current directory programmatically at any given time. So as a rule, absolute paths are preferable, the Universal path notation is likewise preferable and ideally that path should include the currently-logged disk when running Windows.

As far as I know, it's not possible to change the current directory at run time. You can set it when the JVM is started using system property "user.dir", but once the JVM has started, new File(".") and Path.of(".") will always refer to the same file. Unless maybe, very maybe, it's possible with some nasty native code or reflection to change it.
3 weeks ago
The problem is you're mixing Windows and Linux (through wsl).

In Windows, /Try is equivalent to C:\Try. (It can be on a different drive, that all depends from where Java was started, but you've already shown that the current drive is C:.)
In Linux, / is just that: /. The matching directory for Windows' C:\ is not / but /mnt/c; you can see that in the console snippets you've shown:

Anil Philip wrote:

PS C:\> wsl
ANIL-PHILIP-LAPTOP:/mnt/c$ sudo mkdir /Try/tea/
ANIL-PHILIP-LAPTOP:/mnt/c$ sudo mkdir /Try/tea/earlgrey
ANIL-PHILIP-LAPTOP:/mnt/c$ sudo mkdir /Try/tea/hot.txt

I can see it did create the files

ANIL-PHILIP-LAPTOP:/mnt/c$ cd /Try/tea/earlgrey/.././hot.txt
ANIL-PHILIP-LAPTOP:/Try/tea/hot.txt$ cd ..
earlgrey  hot.txt

You see from the prompt that you start in folder /mnt/c, but you create /Try/tea. The second console snippet shows that if you cd into /Try/tea/earlgrey/.././hot.txt the current folder is /Try/tea/hot.txt. That does not match Windows' C:\Try\tea\hot.txt because in wsl that's /mnt/c/Try/tea/hot.txt.
3 weeks ago
That would probably be caused by JEP 396: Strongly Encapsulate JDK Internals by Default and JEP 403: Strongly Encapsulate JDK Internals. Before Java 16, there would be a warning. The first of these JEPS changed the default from warn to fail, but it was still possible to switch back to fail with a JVM flag. The second JEP caused this flag to be ignored; it will be completely removed in some later release.
3 weeks ago
I've become a bit of a fan of @snippet. Before I used a combination of pre and code HTML tags. While that worked, it allowed any code to be included in documentation - even code that didn't even compile. With @snippet I've been able to link to (parts of) actual classes, that I've added to the test source path using Maven. The end result are code snippets that actually compile.
1 month ago

Kieu Thoai wrote:So what if I want it to print the word blocked first and then get the result?

By creating a new CompletableFuture using one of its methods. In this case, since you want the original value, thenApply fits best:
1 month ago
PipedReader doesn't override it, and therefore inherits the default behaviour (return false).

A bit more surprising, the same goes for InputStreamReader. I expected it to delegate to its backing InputStream, but I guess that the "1 byte isn't necessarily 1 char" would have made that tricky.
1 month ago
Campbell already moved it for you.

I noticed that the path that failed had {modulename} in it. I couldn't find any references to it, but I'm guessing that was the issue. Given that the file was called .netbeans_automatic_build makes me think this may have been a glitch in Netbeans.
1 month ago
That feature was heavily abused for email viruses. One of the best examples: Anna Kournikova (computer virus). The actual file name was AnnaKournikova.jpg.vbs but Outlook didn't display the actual extension, so it looked like an image file.
2 months ago
Be warned that this trySplit is only guaranteed to work if the spliterator is ordered: wrote:
If this spliterator can be partitioned, returns a Spliterator covering elements, that will, upon return from this method, not be covered by this Spliterator.

If this Spliterator is ORDERED, the returned Spliterator must cover a strict prefix of the elements.

(On the other hand, if the spliterator isn't ordered, then the stream probably wasn't either, and there's no real definition of "last").

It also won't work on infinite streams, but then again, no solution would work on infinite streams as these don't have a last element.

Unless this Spliterator covers an infinite number of elements, repeated calls to trySplit() must eventually return null.

2 months ago
On Windows you can still use /. Those get turned into \ for you. Paths.get("/zebra/food.txt") will refer to file <drive>:\zebra\food.txt, where <drive> is the drive of the current directory. Paths.get(".././food.txt") will refer to file <current directory>\..\.\food.txt.

Esteban, you can check the result of Paths.get("/zebra/food.txt").toAbsolutePath().normalize() and Paths.get(".././food.txt").toAbsolutePath().normalize() to see what files they actually refer to. You can see what the current directory is using Paths.get(".").toAbsolutePath().normalize().
2 months ago

Steve Dyke wrote:

indentedBillRequestParmsObj will not be a JavaScript object with properties itnbr and itdsc, it's a JavaScript string with as value the result of calling toString() on the IndentedBillRequestParms instance.

To let indentedBillRequestParmsObj be a JavaScript representation of the IndentedBillRequestParms instance you need some processing:
  • First convert the object to a JSON string, using a library like Jackson, Gson or if available JSON B (there are even more)
  • Properly escape the JSON, to prevent injection attacks. This can be easily done using StringEscapeUtils.ESCAPE_JSON from Apache Commons Text

  • The result would then be this (replace escape and toJson to your actual methods):

    The JavaScript will now contain something like this:
    2 months ago
    javax.persistence versus jakarta.persistence has nothing to do with the JDK itself, it's indeed the dependencies that determine which of the two you need. Spring Boot 2.x used javax.persistence, but in Spring Boot 3 they moved to jakarta.persistence. This is basically just a newer version of the same thing, but due to licensing (or something like that) the javax. package prefix could no longer be used. The javax. package prefix is owned by Oracle, and Java EE is now no longer owned by Oracle but renamed to Jakarta EE.
    Java 22 (and 21 with preview features enabled) allows you to do this:

    By assigning it to a variable it becomes an expression. But _ (disallowed since Java 9, reallowed since Java 22) is an unnamed variable - it cannot be used anywhere, but serves as recipient of a value you discard. You won't get a warning that the variable is never used.
    2 months ago