This is an automated email from the ASF dual-hosted git repository. technoboy pushed a commit to branch branch-4.0 in repository https://gitbox.apache.org/repos/asf/pulsar.git
commit 796603ea1b00e36d5833d0eef1e2f3bce301b7d3 Author: Phineas <62228193+falser...@users.noreply.github.com> 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 <lhot...@apache.org> --- .../PulsarFunctionTestTemporaryDirectory.java | 4 ++++ .../apache/pulsar/io/AbstractPulsarE2ETest.java | 3 ++- .../apache/pulsar/io/PulsarFunctionE2ETest.java | 23 ++++++++++++++++++++++ .../functions/utils/FunctionFilePackage.java | 3 ++- 4 files changed, 31 insertions(+), 2 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 336aca37439..cd8a64e662b 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 74f76e7eb59..5b1a66fafb4 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 @@ -313,7 +313,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 e3114b2dd4b..bb3c969b5d4 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; @@ -32,6 +33,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; @@ -68,6 +70,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. @@ -203,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); } } }