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.

Copy link
Member

Choose a reason for hiding this comment

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

Still relevent

// 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.

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.

@Jonathing Jonathing force-pushed the feat/jonathing/2.0/api-changes branch from 7ec0aa7 to 33339f5 Compare October 27, 2025 21:41
@Jonathing
Copy link
Member Author

All extra exceptions have been removed, and I've done some extra tweaking to the API. Still a breaking change, so it still needs the 2.0, but I think it's in a better spot now with the lack of a logging API. Consumers are now expected to handle logOutput(), and the main classes use System.out and System.err.

@Jonathing Jonathing marked this pull request as ready for review October 27, 2025 21:42
@Jonathing Jonathing requested a review from LexManos October 27, 2025 21:42
Copy link
Contributor

@PaintNinja PaintNinja left a comment

Choose a reason for hiding this comment

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

Looks ok from a quick scan on my phone, left some minor non-blocking questions and leaving the more detailed review to Lex

@Jonathing
Copy link
Member Author

Ready for another pass from @LexManos.

@Jonathing Jonathing requested a review from LexManos October 28, 2025 14:09
@LexManos
Copy link
Member

Looks fine to me

@Jonathing
Copy link
Member Author

I am merging this immediately.

@Jonathing Jonathing force-pushed the feat/jonathing/2.0/api-changes branch from ca52018 to a636717 Compare October 29, 2025 16:51
@Jonathing Jonathing merged commit a636717 into MinecraftForge:master Oct 29, 2025
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.

3 participants