mandrean opened a new issue, #3720:
URL: https://github.com/apache/fory/issues/3720

   ## Search before asking
   
   - [x] I had searched in the [issues](https://github.com/apache/fory/issues) 
and found no similar issues.
   
   ## Version
   
   Apache Fory 1.0.0, Java serializer, `CompatibleMode.COMPATIBLE`.
   
   The warning is seen in a Java application when `scala.Product` is loadable 
from the runtime classpath. The application code and affected serialized 
classes are Java classes, not Scala classes.
   
   It is enough for the application to depend on some ordinary Java-facing 
library that happens to pull in Scala transitively. The application does not 
need to declare `org.scala-lang:scala-library` directly and does not need to 
use any Scala APIs.
   
   ## Component(s)
   
   Java
   
   ## Minimal reproduce step
   
   Create a small Maven project with Fory 1.0.0, Lombok, and any Java-facing 
dependency that brings `scala-library` onto the runtime classpath transitively. 
The Java code does not need to use Scala; `scala-library` only needs to be 
present transitively so `org.apache.fory.type.ScalaTypes.SCALA_AVAILABLE` 
becomes true.
   
   `pom.xml`:
   
   ```xml
   <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 
https://maven.apache.org/xsd/maven-4.0.0.xsd";>
     <modelVersion>4.0.0</modelVersion>
   
     <groupId>repro</groupId>
     <artifactId>fory-lombok-default-repro</artifactId>
     <version>1.0-SNAPSHOT</version>
   
     <properties>
       <maven.compiler.release>17</maven.compiler.release>
     </properties>
   
     <dependencies>
       <dependency>
         <groupId>org.apache.fory</groupId>
         <artifactId>fory-core</artifactId>
         <version>1.0.0</version>
       </dependency>
       <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <version>1.18.36</version>
         <scope>provided</scope>
       </dependency>
       <!-- Used only as an example of a Java application dependency that 
brings scala-library transitively. -->
       <dependency>
         <groupId>org.apache.kafka</groupId>
         <artifactId>kafka_2.13</artifactId>
         <version>3.6.2</version>
       </dependency>
       <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-simple</artifactId>
         <version>2.0.12</version>
       </dependency>
     </dependencies>
   
     <build>
       <plugins>
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>exec-maven-plugin</artifactId>
           <version>3.3.0</version>
         </plugin>
       </plugins>
     </build>
   </project>
   ```
   
   `src/main/java/repro/LombokDefaultRepro.java`:
   
   ```java
   package repro;
   
   import java.util.List;
   import lombok.AllArgsConstructor;
   import lombok.Builder;
   import lombok.Value;
   import org.apache.fory.Fory;
   import org.apache.fory.config.CompatibleMode;
   import org.apache.fory.config.Language;
   import org.apache.fory.logging.LoggerFactory;
   
   public class LombokDefaultRepro {
       @Value
       @Builder
       @AllArgsConstructor
       public static class JavaPojo {
           String id;
   
           @Builder.Default
           List<String> imageRelations = List.of();
       }
   
       public static void main(String[] args) {
           LoggerFactory.useSlf4jLogging(true);
   
           Fory fory = Fory.builder()
                   .withLanguage(Language.JAVA)
                   .requireClassRegistration(false)
                   .withCompatibleMode(CompatibleMode.COMPATIBLE)
                   .build();
   
           byte[] bytes = fory.serialize(JavaPojo.builder().id("1").build());
           fory.deserialize(bytes, JavaPojo.class);
       }
   }
   ```
   
   Run:
   
   ```bash
   mvn -q compile exec:java -Dexec.mainClass=repro.LombokDefaultRepro
   ```
   
   Confirm that Scala is present transitively:
   
   ```bash
   mvn -q dependency:tree -Dincludes=org.scala-lang:scala-library
   ```
   
   Expected dependency path:
   
   ```text
   repro:fory-lombok-default-repro:jar:1.0-SNAPSHOT
   \- org.apache.kafka:kafka_2.13:jar:3.6.2:compile
      \- org.scala-lang:scala-library:jar:2.13.11:compile
   ```
   
   Lombok compiles `@Builder.Default` into a private static method whose name 
has the shape `$default$imageRelations()`:
   
   ```bash
   javap -classpath target/classes -private 'repro.LombokDefaultRepro$JavaPojo'
   ```
   
   Relevant output:
   
   ```text
   private static java.util.List<java.lang.String> $default$imageRelations();
   ```
   
   If the Kafka dependency, or any other dependency that makes `scala.Product` 
loadable, is removed, the warning is not emitted because the Scala 
default-value branch is not enabled.
   
   ## What did you expect to see?
   
   No warning should be emitted for a plain Java class just because Scala is 
present somewhere on the runtime classpath.
   
   Fory's Scala default-value support should either only inspect Scala types, 
or it should only treat method names as Scala default methods when the suffix 
after `$default$` is numeric, such as `apply$default$1`.
   
   ## What did you see instead?
   
   During deserialization, Fory logs a warning from `DefaultValueUtils`:
   
   ```text
   WARN org.apache.fory.util.DefaultValueUtils - Error For input string: 
"imageRelations" finding default value for repro.LombokDefaultRepro$JavaPojo, 
default values support is disabled when deserializing object of type 
repro.LombokDefaultRepro$JavaPojo
   ```
   
   This happens even though `JavaPojo` is a Java class and the repro does not 
call any Kafka or Scala APIs. The only Scala-related condition is that 
`scala.Product` is loadable from the classpath via a transitive dependency.
   
   ## Anything Else?
   
   The suspected path is:
   
   - `CompatibleSerializer` enables Scala default-value support when 
`ScalaTypes.SCALA_AVAILABLE` is true.
   - `ScalaTypes.SCALA_AVAILABLE` is global and becomes true when 
`scala.Product` can be loaded.
   - 
`DefaultValueUtils.ScalaDefaultValueSupport#getDefaultValuesForRegularScalaClass`
 scans all declared methods whose names contain `$default$`.
   - It then parses the substring after `$default$` as an integer.
   - Lombok `@Builder.Default` generates methods like 
`$default$imageRelations`, where the suffix is a Java field name, not a Scala 
argument index.
   
   This makes a transitive Scala dependency enough to produce warning noise for 
Java Lombok model classes. In practice this can happen just by adding a 
Java-facing library whose own dependency graph includes Scala, even if the 
application is otherwise pure Java.
   
   ## Are you willing to submit a PR?
   
   - [ ] I'm willing to submit a PR!
   


-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to