Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-73170] Upgrade Commons FileUpload from 1.5 to 2.0.0-M2 #542

Merged
merged 2 commits into from
May 16, 2024

Conversation

basil
Copy link
Member

@basil basil commented May 10, 2024

See jenkinsci/jenkins#9259 for the PR description.

Testing done

See jenkinsci/jenkins#9259.

@basil basil marked this pull request as ready for review May 14, 2024 23:59
@basil basil changed the title Upgrade Commons FileUpload from 1.5 to 2.0.0-M2 [JENKINS-73170] Upgrade Commons FileUpload from 1.5 to 2.0.0-M2 May 15, 2024
*/
void setHeaders(FileItemHeaders headers);

default org.apache.commons.fileupload2.core.FileItem toFileUpload2FileItem() {
Copy link
Member Author

Choose a reason for hiding this comment

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

Bridge from old to new

};
}

static FileItem fromFileUpload2FileItem(org.apache.commons.fileupload2.core.FileItem from) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Bridge from new to old


@Override
public org.apache.commons.fileupload2.core.FileItem toFileUpload2FileItem() {
return from;
Copy link
Member Author

Choose a reason for hiding this comment

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

Prevent infinite recursion

*/
Iterator<String> getHeaderNames();

default org.apache.commons.fileupload2.core.FileItemHeaders toFileUpload2FileItemHeaders() {
Copy link
Member Author

Choose a reason for hiding this comment

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

Bridge from old to new

};
}

static FileItemHeaders fromFileUpload2FileItemHeaders(org.apache.commons.fileupload2.core.FileItemHeaders from) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Bridge from new to old

* C library, it might create a file named "foo.exe", as the NUL
* character is the string terminator in C.
*/
public class InvalidFileNameException extends RuntimeException {
Copy link
Member Author

Choose a reason for hiding this comment

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

Part of the public API and therefore included for compatibility purposes

File tmpDir;
try {
tmpDir = Files.createTempDirectory("jenkins-stapler-uploads").toFile();
} catch (IOException e) {
throw new ServletException("Error creating temporary directory", e);
}
tmpDir.deleteOnExit();
upload = new ServletFileUpload(new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, tmpDir));
upload = new JavaxServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get());
Copy link
Member Author

Choose a reason for hiding this comment

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

The new builder API allows us to omit the default size threshold without any change in behavior. I verified the builder's default is the same number as the old default that we were explicitly passing in.

@@ -1158,6 +1166,7 @@ private boolean isMultipart() {
}

@Override
@WithBridgeMethods(value = org.apache.commons.fileupload.FileItem.class, adapterMethod = "fromFileUpload2FileItem")
Copy link
Member Author

Choose a reason for hiding this comment

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

The Java compiler will generate a getFileItem(String) method that returns the new FileUpload 2.x type. The bridge method injector will call the abovementioned method, then call fromFileUpload2FileItem to generate the old type. Thus compatibility is retained.

Comment on lines 1155 to 1167
CONVERT_UTILS.register(new Converter() {
@Override
public org.apache.commons.fileupload.FileItem convert(Class type, Object value) {
if (value == null) {
return null;
}
try {
return org.apache.commons.fileupload.FileItem.fromFileUpload2FileItem(Stapler.getCurrentRequest().getFileItem(value.toString()));
} catch (ServletException | IOException e) {
throw new ConversionException(e);
}
}
}, org.apache.commons.fileupload.FileItem.class);
Copy link
Member Author

Choose a reason for hiding this comment

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

I honestly can't remember why I had to do this, but some test failed somewhere along the line back in August 2023 and I added this to fix it. If someone really wants to know the justification, I can try removing this and re-running hours worth of test suites to remember the original motivation, but I'm hoping nobody cares enough to ask this question.

Copy link
Member

Choose a reason for hiding this comment

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

If I were to be interested in the answer, what test suites are you referring to? Core and/or BOM PCT?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it was some PCT or ATH test if I remember correctly.

@@ -497,6 +498,7 @@ public interface StaplerRequest extends HttpServletRequest {
* This includes the case where the name corresponds to a simple
* form field (like textbox, checkbox, etc.)
*/
@WithBridgeMethods(org.apache.commons.fileupload.FileItem.class)
Copy link
Member Author

Choose a reason for hiding this comment

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

Bridge methods need to be added to both interface and implementation. See the unit tests for bridge-method-injector.

@basil basil requested review from MarkEWaite and alecharp May 15, 2024 00:08
Copy link
Member

@timja timja left a comment

Choose a reason for hiding this comment

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

thanks for this!

@@ -1158,6 +1166,7 @@ private boolean isMultipart() {
}

@Override
@WithBridgeMethods(value = org.apache.commons.fileupload.FileItem.class, adapterMethod = "fromFileUpload2FileItem")
public FileItem getFileItem(String name) throws ServletException, IOException {

This comment was marked as outdated.

This comment was marked as outdated.

bridge methods work at runtime but there is still a compilation error.
Since I don't want to force plugins to adopt the new API when bumping
their core baseline, simpler to avoid bridge methods here.
@basil basil merged commit d250086 into jenkinsci:master May 16, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants