[MOTIVATION]
I have a maven project that uses commons-fileupload 1.5. When I want to update the dependency to 1.6.0, it does not compile. here
[LIMITATION]
I cannot use jakarta libraries on code, because of later dependency (org.gwtproject).
[MIGRATION IN CONFIGURATION FILES]
@pom.xml:
<dependency>
<groupId>commons-fileupload</groupId><!-- poi excel does not like u! -->
<artifactId>commons-fileupload</artifactId>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
<version>1.6.0</version><!-- 1.5 was working -->
</dependency>
@module-info.java:
requires org.apache.commons.fileupload;//commons.fileupload;
[COMPILE ERRORS]
cd C:\git\blg\com.tugalsan.blg.org_apache_commons_fileupload_1_6_0; JAVA_HOME=C:\\bin\\java\\home cmd /c "\"C:\\bin\\netbeans\\home\\java\\maven\\bin\\mvn.cmd\" -Dmaven.ext.class.path=C:\\bin\\netbeans\\home\\java\\maven-nblib\\netbeans-eventspy.jar --no-transfer-progress clean install"
Required filename-based automodules detected: [javax.servlet-api-4.0.1.jar]. Please don't publish this project to a public artifact repository!
COMPILATION ERROR :
-------------------------------------------------------------
com/tugalsan/blg/org_apache_commons_fileupload_1_6_0/server/TS_SUploadWebServlet.java:[113,51] cannot access javax.servlet.ServletContextListener
class file for javax.servlet.ServletContextListener not found
com/tugalsan/blg/org_apache_commons_fileupload_1_6_0/server/TS_SUploadWebServlet.java:[48,35] cannot access javax.servlet.http.HttpServletRequest
class file for javax.servlet.http.HttpServletRequest not found
com/tugalsan/blg/org_apache_commons_fileupload_1_6_0/server/TS_SUploadWebServlet.java:[55,73] no suitable method found for parseRequest(javax.servlet.http.HttpServletRequest)
method org.apache.commons.fileupload.FileUploadBase.parseRequest(org.apache.commons.fileupload.RequestContext) is not applicable
(argument mismatch; javax.servlet.http.HttpServletRequest cannot be converted to org.apache.commons.fileupload.RequestContext)
method org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(javax.servlet.http.HttpServletRequest) is not applicable
(argument mismatch; javax.servlet.http.HttpServletRequest cannot be converted to javax.servlet.http.HttpServletRequest)
3 errors
[QUESTION]
What code changes should I apply to migrate fully.
[ADDITIONAL NOTES]
on netbeans on projects on dependencies, javax.servlet-api-4.0.1.jar & commons-fileupload-1.6.0.jar & commons-io-2.19.0.jar exists.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tugalsan</groupId>
<artifactId>com.tugalsan.blg.org_apache_commons_fileupload_1_6_0</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId><!-- poi excel does not like u! -->
<artifactId>commons-fileupload</artifactId>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
<version>1.6.0</version><!-- 1.5 was working -->
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.19.0</version> <!-- poi version 5 needs it, becuase servlet-upload and gwt messes up -->
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
<include>**/*.gwt.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>24</release><!--prop.jdk-->
<enablePreview>true</enablePreview>
<!--<compilerArgs>
<arg>- -add-modules</arg>
<arg>jdk.incubator.vector</arg>
</compilerArgs> -->
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
module-info.java
module com.tugalsan.blg.org_apache_commons_fileupload_1_6_0 {
requires javax.servlet.api;
// requires commons.fileupload;
requires org.apache.commons.fileupload;//;
}
TS_SUploadWebServlet.java
package com.tugalsan.blg.org_apache_commons_fileupload_1_6_0.server;
import javax.servlet.http.*;
import java.io.File;
import static java.lang.System.out;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebListener;
import javax.servlet.annotation.WebServlet;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.FileCleanerCleanup;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@WebServlet("/u")
@MultipartConfig(
fileSizeThreshold = 1024 * 1024 * TS_SUploadWebServlet.UPLOAD_MB_LIMIT_MEMORY,
maxFileSize = 1024 * 1024 * TS_SUploadWebServlet.UPLOAD_MB_LIMIT_FILE,
maxRequestSize = 1024 * 1024 * TS_SUploadWebServlet.UPLOAD_MB_LIMIT_REQUESTBALL,
location = "/" + TS_SUploadWebServlet.UPLOAD_DIR_NAME//means C:/bin/tomcat/home/work/Catalina/localhost/spi-xxx/upload (do create it)
)
public class TS_SUploadWebServlet extends HttpServlet {
final public static String UPLOAD_DIR_NAME = "p";
final public static int UPLOAD_MB_LIMIT_MEMORY = 10;
final public static int UPLOAD_MB_LIMIT_FILE = 25;
final public static int UPLOAD_MB_LIMIT_REQUESTBALL = 50;
@Override
public void doGet(HttpServletRequest rq, HttpServletResponse rs) {
call(this, rq, rs);
}
@Override
protected void doPost(HttpServletRequest rq, HttpServletResponse rs) {
call(this, rq, rs);
}
public static void call(HttpServlet servlet, HttpServletRequest rq, HttpServletResponse rs) {
try {
var appPath = rq.getServletContext().getRealPath("");// constructs path of the directory to save uploaded file
var savePath = appPath + File.separator + TS_SUploadWebServlet.UPLOAD_DIR_NAME;// creates the save directory if it does not exists
var fileSaveDir = new File(savePath);
if (!fileSaveDir.exists()) {
fileSaveDir.mkdir();
}
if (!ServletFileUpload.isMultipartContent(rq)) {
println(rs, "USER_NOT_MULTIPART");
return;
}
//GETING ITEMS
//WARNING: Dont touch request before this, like execution getParameter or such!
var items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(rq);
//GETTING PROFILE
var profile = items.stream().filter(item -> item.isFormField()).findFirst().orElse(null);
if (profile == null) {
println(rs, "RESULT_UPLOAD_USER_PROFILE_NULL");
return;
}
println(rs, "profile_selected");
var profileValue = profile.getString();
if (profileValue == null) {
println(rs, "RESULT_UPLOAD_USER_PROFILEVALUE_NULL");
return;
}
println(rs, "profileValue: " + profileValue);
//GETING SOURCEFILE
var sourceFile = items.stream().filter(item -> !item.isFormField()).findFirst().orElse(null);
if (sourceFile == null) {
println(rs, "RESULT_UPLOAD_USER_SOURCEFILE_NULL");
return;
}
println(rs, "sourceFile_selected");
var sourceFileName = sourceFile.getName();
if (sourceFileName == null) {
println(rs, "RESULT_UPLOAD_USER_SOURCEFILENAME_NULL");
return;
}
println(rs, "sourceFileName: " + sourceFileName);
//COMPILING TARGET FILE
var targetFile = fileSaveDir.toPath().resolve(profileValue).resolve(sourceFileName);
//CREATE DIRECTORIES
targetFile.getParent().toFile().mkdirs();
//STORE FILE
Files.createFile(targetFile);
sourceFile.write(targetFile.toFile());
//RETURN SUCCESS FLAG
rs.setStatus(HttpServletResponse.SC_CREATED);
println(rs, "RESULT_UPLOAD_USER_SUCCESS");
} catch (Exception e) {
throwIfInterruptedException(e);
e.printStackTrace();
}
}
private static void println(HttpServletResponse rs, String msg) {
try {
out.println("println: " + msg);
rs.getWriter().println(msg);
} catch (Exception e) {
throwIfInterruptedException(e);
}
}
//---------------------------- LISTENER ----------------
@WebListener
public class ApacheFileCleanerCleanup extends FileCleanerCleanup {
}
//----------------------------- UTILS -----------------------
@SuppressWarnings("unchecked")
private static <T extends Throwable> void _throwAsUncheckedException(Throwable exception) throws T {
throw (T) exception;
}
@Deprecated //only internalUse
private static void throwAsUncheckedException(Throwable exception) {
TS_SUploadWebServlet.<RuntimeException>_throwAsUncheckedException(exception);
}
public static <R> R throwIfInterruptedException(Throwable t) {
if (isInterruptedException(t)) {
Thread.currentThread().interrupt();
throwAsUncheckedException(t);
}
return null;
}
public static boolean isInterruptedException(Throwable t) {
if (t instanceof InterruptedException) {
return true;
}
if (t.getCause() != null) {
return isInterruptedException(t.getCause());
}
return false;
}
}
The main problem is:
I found that 1.6.1 uses javax.servlet:servlet-api rather than javax.servlet:javax.servler-api. So I try to upgrade the version from the pom.xml, It did not compile.
Additionally,
I found that here 2.0.0-M5 version is compatible with javax.servlet if I fork it from javax.servlet:servlet-api to javax.servlet:javax.servler-api on the pom as here here
<!-- <depe`ndency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${commons.servlet-api.version}</version>
<scope>provided</scope>
</dependency>-->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>`
Now the project compiles.