eolivelli opened a new issue #11338: URL: https://github.com/apache/pulsar/issues/11338
**Describe the bug** Pulsar Functions and Pulsar IO connectors that use the Pulsar Client API, in particular the "Schema" API (like `Schema.JSON(Pojo.class)`) do not work anymore if you upgrade your Pulsar cluster to Pulsar 2.8.x. This is because of an `IncompatibleClassChangeError` around the class `SchemaInfo` that was a "class" in Pulsar 2.7 and now it is a pure interface in Pulsar 2.8 (see commit https://github.com/apache/pulsar/commit/89ac98e4af363b09f2fe8e309539b0e35243aaee). The error is: ``` 11:09:19.623 [public/default/fun1-0] WARN org.apache.pulsar.functions.instance.JavaInstanceRunnable - Encountered exception when processing message PulsarRecord(topicName=Optional[persistent://public/default/test], partition=0, message=Optional[org.apache.pulsar.client.impl.MessageImpl@718e1e37], schema=org.apache.pulsar.client.impl.schema.StringSchema@7127ce9a, failFunction=org.apache.pulsar.functions.source.PulsarSource$$Lambda$213/0x000000080056f040@6e18bd1d, ackFunction=org.apache.pulsar.functions.source.PulsarSource$$Lambda$212/0x000000080056fc40@71fc78c9) java.lang.RuntimeException: java.lang.IncompatibleClassChangeError: Method 'org.apache.pulsar.common.schema.SchemaInfo$SchemaInfoBuilder org.apache.pulsar.common.schema.SchemaInfo.builder()' must be InterfaceMethodref constant at org.apache.pulsar.client.internal.ReflectionUtils.catchExceptions(ReflectionUtils.java:42) ~[java-instance.jar:?] at org.apache.pulsar.client.internal.DefaultImplementation.newJSONSchema(DefaultImplementation.java:274) ~[java-instance.jar:?] at org.apache.pulsar.client.api.Schema.JSON(Schema.java:335) ~[java-instance.jar:?] at myfun.Fun1.process(Fun1.java:28) ~[?:?] at myfun.Fun1.process(Fun1.java:14) ~[?:?] at org.apache.pulsar.functions.instance.JavaInstance.handleMessage(JavaInstance.java:95) ~[pulsar-functions-instance.jar:2.8.0] at org.apache.pulsar.functions.instance.JavaInstanceRunnable.run(JavaInstanceRunnable.java:271) [pulsar-functions-instance.jar:2.8.0] at java.lang.Thread.run(Thread.java:829) [?:?] Caused by: java.lang.IncompatibleClassChangeError: Method 'org.apache.pulsar.common.schema.SchemaInfo$SchemaInfoBuilder org.apache.pulsar.common.schema.SchemaInfo.builder()' must be InterfaceMethodref constant at org.apache.pulsar.client.impl.schema.util.SchemaUtil.parseSchemaInfo(SchemaUtil.java:50) ~[pulsar-client-original.jar:2.8.0] at org.apache.pulsar.client.impl.schema.JSONSchema.of(JSONSchema.java:93) ~[pulsar-client-original.jar:2.8.0] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?] at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?] at org.apache.pulsar.client.internal.DefaultImplementation.lambda$newJSONSchema$31(DefaultImplementation.java:277) ~[java-instance.jar:?] at org.apache.pulsar.client.internal.ReflectionUtils.catchExceptions(ReflectionUtils.java:34) ~[java-instance.jar:?] ... 7 more ``` **To Reproduce** In order to reproduce the error follow these steps: - start a simple Pulsar 2.7.1 instance (pulsar standalone is enough) - write a simple Function that contains only "Schema.JSON(MyPojo.class)" (see below) and is it compiled using Pulsar 2.7.1 API - deploy the function with pulsar-admin - produce one message with pulsar-client produce - see the logs of the function (in logs/function/public/default/functionname/*.log) - update the cluster to Pulsar 2.8.0 (stop pulsar standalone, upgrade to 2.8.0 and start it again, just keep the 'data' directory contents) - produce another message - see the error in the logs The workaround is to rebuild the Function against the 2.8.0 API and to redeploy it. Function body (taken from Pulsar Doc, with the addition of Schema.JSON): ``` @Slf4j public class Fun1 implements Function<String, Void> { public Void process(String input, Context context) { Logger LOG = context.getLogger(); String inputTopics = context.getInputTopics().stream().collect(Collectors.joining(", ")); String functionName = context.getFunctionName(); String logMessage = String.format("A message with a value of \"%s\" has arrived on one of the following topics: %s\n", input, inputTopics); LOG.info(logMessage); Schema<MyPojo> json = Schema.JSON(MyPojo.class); LOG.info("schema {}", json); return null; } @Data public static final class MyPojo { String id; BigDecimal data; } } ``` pom.xml relevant deps: ``` <dependencies> <dependency> <groupId>org.apache.pulsar</groupId> <artifactId>pulsar-client</artifactId> <version>2.7.1</version> </dependency> <dependency> <groupId>org.apache.pulsar</groupId> <artifactId>pulsar-functions-api</artifactId> <version>2.7.1</version> <scope>provided</scope> </dependency> ``` Please note that in order to see the Function working you have to add the dependency to "pulsar-client", and "pulsar-client-api" is not enough (otherwise you will see a `ClassNotFoundException: org.apache.pulsar.client.impl.schema.JSONSchema` error. **Expected behaviour** Upgrading Pulsar must be seamless, and the functions must continue working without changes. **Additional considerations** This is a bad problem for people who try to upgrade Pulsar from 2.7 to 2.8 because you may have many functions and you will need to rebuild them from source. Therefore it is not possible to make the upgrade without interrupting the service, because you have to upgrade Pulsar and then upgrade the Function. It is not possible to build the function against 2.8.0 and then see it working on Pulsar 2.7 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@pulsar.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org