Skip to content

Conversation

@Jonathing
Copy link
Member

@Jonathing Jonathing commented Oct 20, 2025

This PR modifies the API design of Java Provisioner to throw exceptions instead of returning null of something goes wrong trying to locate or provision Java installations.

Depends on:


Please don't squash and merge through GitHub.com. I'll merge this myself with the proper tag(s) once approval has been granted.

Copy link
Member

@LexManos LexManos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, the issue is he is wanting to expose more information in the event of failures. Which is fair. But throwing Exception everywhere is not the way to do it.

Better option is to grab the log from LogUtils and print that out when versions can't be provisioned/found.

Aside from that there are some other minor changes like the ordering of distros and nullability. Which we've discussed on discord and should be on the same page about.

try {
return Objects.requireNonNull(readJson(tmp, TypeToken.get(DownloadInfo.class)).info);
} catch (Exception e) {
errors.add(e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder about Objects.requireNonNull

error("Failed to download package info for "+ pkg.id);
return null;
error("Failed to download any packages from " + url);
throw Throwing.withSuppressed(new Exception("Failed to parse package list from " + url), errors);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception and error message are not aligned here.

return null;
try {
DownloadUtils.tryDownloadFile(true, archive, download);
} catch (Exception e) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is broken because the return will be false, not an exception thrown.

// Prefer TCK certified JDKs (and also test Microsoft)
public enum Distro implements Comparable<Distro> {
// These are well know/recommended distros
// These are well-known/recommended distros
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, discussing this on discord, just reiterating it here. I don't particularly care.
But MS > OpenJDK > Temurin > * > JDK > OpenJ9 seems to be the consensus on the order.

log("Gradle home: \"" + gradleHome.getAbsolutePath() + "\" Does not exist");
return;
throw new JavaLocatingFailedException("Gradle home does not exist: " + gradleHome.getAbsolutePath());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gradle home not existing is a valid case that shouldn't throw errors. The 'error' if any should just be because it ant find it during the find(int) function not the findAll functions.

for (File child : root.listFiles()) {
File[] listFiles;
try {
listFiles = Objects.requireNonNull(root.listFiles());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another requiresNotNull and immediately caught exception.

* @return null is no install found, or a File pointing at the JAVA_HOME directory
*/
File find(int version);
File find(int version) throws JavaLocatingFailedException;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throwing an exception here to give more information then a null would is fine.

* @return A list containing all java installs, possibly empty but not null.
*/
List<IJavaInstall> findAll();
FindResult findAll() throws JavaLocatingFailedException;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing an exception here is not find as it is meant to return all available entries. Not caring for things that are broken/whatever. Its just "What are my functional options"

List<IJavaInstall> findAll();
FindResult findAll() throws JavaLocatingFailedException;

interface FindResult {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you must keep this, rename to Results.
Tho I suspect this could be resolved with:

if (ret.isEmpty())
  print(Log.getErrorMessages())

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, the interface was only because I wasn't printing the errors. I'll remove it when I redo this.

}

default IJavaInstall provision(int version, Disco.Distro distro) throws JavaProvisioningFailedException {
throw new JavaProvisioningFailedException("Provisioning is not implemented by this locator");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we throw an exception here, we need to add a 'canProvision' so we don't use exception as codeflow. Tho the only thing that can provision right now is Disco.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to just make a subinterface? IJavaProvisioner extends IJavaLocator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd work for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants