This is an automated email from the ASF dual-hosted git repository. lhotari pushed a commit to branch branch-3.3 in repository https://gitbox.apache.org/repos/asf/pulsar.git
commit b671819ac0df32b0accb0d29c13c3e6d2c83d9a3 Author: Phineas <[email protected]> AuthorDate: Fri Aug 8 00:32:54 2025 +0800 [improve][io] Add dependency file name information to error message when .nar file validation fails with ZipException (#24604) Co-authored-by: Lari Hotari <[email protected]> (cherry picked from commit 2d5b0d6810af7c348f8e5b7f063dcb6c650023eb) --- .../PulsarFunctionTestTemporaryDirectory.java | 4 ++++ .../apache/pulsar/io/AbstractPulsarE2ETest.java | 3 ++- .../apache/pulsar/io/PulsarFunctionE2ETest.java | 24 +++++++++++++++++++++- .../functions/utils/FunctionFilePackage.java | 3 ++- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/functions/worker/PulsarFunctionTestTemporaryDirectory.java b/pulsar-broker/src/test/java/org/apache/pulsar/functions/worker/PulsarFunctionTestTemporaryDirectory.java index 67426980332..0b6215b42c7 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/functions/worker/PulsarFunctionTestTemporaryDirectory.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/functions/worker/PulsarFunctionTestTemporaryDirectory.java @@ -80,4 +80,8 @@ public class PulsarFunctionTestTemporaryDirectory { Assert.assertEquals(foundFiles.length, 0, "Temporary files left over: " + Arrays.asList(foundFiles)); } + + public File getTempDirectory() { + return tempDirectory; + } } diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/io/AbstractPulsarE2ETest.java b/pulsar-broker/src/test/java/org/apache/pulsar/io/AbstractPulsarE2ETest.java index d27e2763904..62c21ef1b91 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/io/AbstractPulsarE2ETest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/io/AbstractPulsarE2ETest.java @@ -314,7 +314,8 @@ public abstract class AbstractPulsarE2ETest { workerConfig.setAuthorizationEnabled(true); List<String> urlPatterns = - List.of(getPulsarApiExamplesJar().getParentFile().toURI() + ".*", "http://127\\.0\\.0\\.1:.*"); + List.of(getPulsarApiExamplesJar().getParentFile().toURI() + ".*", "http://127\\.0\\.0\\.1:.*", + tempDirectory.getTempDirectory().toURI() + ".*"); workerConfig.setAdditionalEnabledConnectorUrlPatterns(urlPatterns); workerConfig.setAdditionalEnabledFunctionsUrlPatterns(urlPatterns); diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/io/PulsarFunctionE2ETest.java b/pulsar-broker/src/test/java/org/apache/pulsar/io/PulsarFunctionE2ETest.java index ab4925bfeb8..a74da92005d 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/io/PulsarFunctionE2ETest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/io/PulsarFunctionE2ETest.java @@ -21,6 +21,7 @@ package org.apache.pulsar.io; import static org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest.retryStrategically; import static org.apache.pulsar.functions.worker.PulsarFunctionLocalRunTest.getPulsarApiExamplesJar; import static org.apache.pulsar.functions.worker.PulsarFunctionLocalRunTest.getPulsarApiExamplesNar; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.spy; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; @@ -33,7 +34,7 @@ import static org.testng.Assert.fail; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.util.concurrent.ThreadFactoryBuilder; - +import java.io.File; import java.nio.ByteBuffer; import java.util.Collections; import java.util.HashMap; @@ -71,6 +72,7 @@ import org.apache.pulsar.functions.worker.TestPulsarFunctionUtils; import org.awaitility.Awaitility; import org.testng.Assert; import org.testng.annotations.Test; +import org.zeroturnaround.zip.ZipUtil; /** * Test Pulsar sink on function @@ -204,6 +206,26 @@ public class PulsarFunctionE2ETest extends AbstractPulsarE2ETest { testE2EPulsarFunction(jarFilePathUrl); } + @Test(timeOut = 20000) + public void testE2EPulsarFunctionWithInvalidJarDependencyInNarFile() throws Exception { + File narFile = getPulsarApiExamplesNar(); + File invalidNarFile = File.createTempFile("invalidJarDependency", ".nar", tempDirectory.getTempDirectory()); + try { + // Add an invalid dependency to the nar file + ZipUtil.addEntry(narFile, "META-INF/bundled-dependencies/invalid-dependency.jar", + "Invalid jar content".getBytes(), invalidNarFile); + String jarFilePathUrl = invalidNarFile.toURI().toString(); + testE2EPulsarFunction(jarFilePathUrl); + fail("Expected PulsarAdminException to be thrown due to invalid jar dependency in nar file"); + } catch (PulsarAdminException e) { + assertThat(e.getMessage()) + .contains("META-INF/bundled-dependencies/invalid-dependency.jar' failed due to zip END header not " + + "found"); + } finally { + invalidNarFile.delete(); + } + } + @Test(timeOut = 40000) public void testE2EPulsarFunctionWithUrl() throws Exception { testE2EPulsarFunction(fileServer.getUrl("/pulsar-functions-api-examples.jar")); diff --git a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionFilePackage.java b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionFilePackage.java index 8224de32521..44e33410bd6 100644 --- a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionFilePackage.java +++ b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionFilePackage.java @@ -79,7 +79,8 @@ public class FunctionFilePackage implements AutoCloseable, ValidatableFunctionPa } classFileLocators.add(locator); } catch (IOException e) { - throw new UncheckedIOException(e); + throw new UncheckedIOException("Loading '" + classpath + "' failed due to " + e.getMessage(), + e); } } }
