[ 
https://issues.apache.org/jira/browse/IGNITE-28863?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dmitry Werner updated IGNITE-28863:
-----------------------------------
    Description: 
*Root Cause*

The pom.xml build script intentionally creates a corrupted JAR for testing bad 
signature verification:

1. Copies `GridUriDeploymentTestTask11.class` under the name 
`GridUriDeploymentTestWithNameTask11.class` (bytecode contains `this_class = 
GridUriDeploymentTestTask11` → mismatch with filename)

2. Packs this corrupted class into JAR, signs it, then updates the JAR with the 
correct class:
{code:java}
 <zip destfile="...${bad-signed.jar}" basedir=".../target/classes/"
     includes=".../GridUriDeploymentTestWithNameTask11.class" update="yes" 
/>{code}
The problem: in Ant 1.10.x, {{zip update="yes"}} sometimes silently skips the 
replacement. The “file is newer than the archive entry” check operates at the 
2‑second granularity boundary of DOS timestamps in ZIP archives, and the 
sequence {{sleep 2 + touch}} sets the file’s mtime exactly on this boundary. 
When the check determines that the file is “not newer,” the archive retains 
only the original, corrupted entry.

This crashes the `grid-uri-scanner` thread, stopping all subsequent deployments.

All `checkTask()` assertions fail with `findResource() == null`.
{code:java}
        
[ERROR][grid-uri-scanner-#35%file.GridFileDeploymentSelfTest%-#269%file.GridFileDeploymentSelfTest%][UriDeploymentScannerManager]
 Runtime error caught during grid runnable execution: 
        IgniteSpiThread 
[name=grid-uri-scanner-#35%file.GridFileDeploymentSelfTest%-#269%file.GridFileDeploymentSelfTest%]
       java.lang.NoClassDefFoundError: 
org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestWithNameTask11 
(wrong name: org/apache/ignite/spi/deployment/uri/tasks/
        GridUriDeploymentTestTask11)
           at java.base/java.lang.ClassLoader.defineClass1(Native Method)
           at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
           at 
java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
           at 
java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
           at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
           at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
           at 
java.base/java.security.AccessController.doPrivileged(JavaAccessController.java:77)
          at 
java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentClassLoader.loadClass(GridUriDeploymentClassLoader.java:56)
          at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentFileResourceLoader.createResource(GridUriDeploymentFileResourceLoader.java:72)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentDiscovery.findResourcesInDirectory(GridUriDeploymentDiscovery.java:109)
          ... (recursive directory traversal) ...
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentDiscovery.getClasses(GridUriDeploymentDiscovery.java:71)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentFileProcessor.processNoDescriptorFile(GridUriDeploymentFileProcessor.java:388)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentFileProcessor.processFile(GridUriDeploymentFileProcessor.java:108)
          at 
org.apache.ignite.spi.deployment.uri.UriDeploymentSpi$2.onNewOrUpdatedFile(UriDeploymentSpi.java:590)
          at 
org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner$URIContext.handleFile(UriDeploymentFileScanner.java:268)
          at 
org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner$URIContext$1.handle(UriDeploymentFileScanner.java:178)
          at 
org.apache.ignite.spi.deployment.uri.scanners.GridDeploymentFolderScannerHelper.scanFolder(GridDeploymentFolderScannerHelper.java:49)
          at 
org.apache.ignite.spi.deployment.uri.scanners.GridDeploymentFolderScannerHelper.scanFolder(GridDeploymentFolderScannerHelper.java:52)
          at 
org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner$URIContext.scan(UriDeploymentFileScanner.java:183)
          at 
org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner.scan(UriDeploymentFileScanner.java:73){code}
The same issue exists for `bad-signed-deployfile.gar` with 
`GridUriDeploymentTestWithNameTask6`.

*Fix*

Replace `ant zip update="yes"` with the standard unzip → copy → zip pattern and 
remove the logic that depends on timestamps:
{code:java}
 <unzip src=".../${bad-signed.jar}" dest="${basedir}/target/file_tmp/zipfix" />
<copy 
file="${basedir}/target/classes/.../GridUriDeploymentTestWithNameTask11.class"
      todir="${basedir}/target/file_tmp/zipfix/..." overwrite="yes" />
<delete file=".../${bad-signed.jar}" />
<zip destfile=".../${bad-signed.jar}" 
basedir="${basedir}/target/file_tmp/zipfix" />{code}
Applied to both `deployfile-bad-signed.jar` and `bad-signed-deployfile.gar`.

  was:
*Root Cause*

All 7 GridFileDeploymentSelfTest failures stem from a duplicate entry in 
deployfile-bad-signed.jar.

The pom.xml build script intentionally creates a corrupted JAR for testing bad 
signature verification:

1. Copies `GridUriDeploymentTestTask11.class` under the name 
`GridUriDeploymentTestWithNameTask11.class` (bytecode contains `this_class = 
GridUriDeploymentTestTask11` → mismatch with filename)

2. Packs this corrupted class into JAR, signs it, then updates the JAR with the 
correct class:
{code:java}
 <zip destfile="...${bad-signed.jar}" basedir=".../target/classes/"
     includes=".../GridUriDeploymentTestWithNameTask11.class" update="yes" 
/>{code}
The problem: `ant zip update="yes"` behavior changed in Ant 1.9+. Instead of 
replacing an existing entry, it appends a duplicate at the end of the archive. 
The JAR now contains two entries with the same name:
 - First entry (corrupted, `this_class = GridUriDeploymentTestTask11`) — loaded 
by `URLClassLoader`
 - Second entry (correct, `this_class = GridUriDeploymentTestWithNameTask11`) — 
never reached

On JDK 17, `URLClassLoader.findClass()` loads the first (corrupted) entry → JVM 
throws `NoClassDefFoundError: wrong name`. This crashes the `grid-uri-scanner` 
thread, stopping all subsequent deployments. All `checkTask()` assertions fail 
with `findResource() == null`.
{code:java}
        
[ERROR][grid-uri-scanner-#35%file.GridFileDeploymentSelfTest%-#269%file.GridFileDeploymentSelfTest%][UriDeploymentScannerManager]
 Runtime error caught during grid runnable execution: 
        IgniteSpiThread 
[name=grid-uri-scanner-#35%file.GridFileDeploymentSelfTest%-#269%file.GridFileDeploymentSelfTest%]
       java.lang.NoClassDefFoundError: 
org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestWithNameTask11 
(wrong name: org/apache/ignite/spi/deployment/uri/tasks/
        GridUriDeploymentTestTask11)
           at java.base/java.lang.ClassLoader.defineClass1(Native Method)
           at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
           at 
java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
           at 
java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
           at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
           at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
           at 
java.base/java.security.AccessController.doPrivileged(JavaAccessController.java:77)
          at 
java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentClassLoader.loadClass(GridUriDeploymentClassLoader.java:56)
          at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentFileResourceLoader.createResource(GridUriDeploymentFileResourceLoader.java:72)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentDiscovery.findResourcesInDirectory(GridUriDeploymentDiscovery.java:109)
          ... (recursive directory traversal) ...
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentDiscovery.getClasses(GridUriDeploymentDiscovery.java:71)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentFileProcessor.processNoDescriptorFile(GridUriDeploymentFileProcessor.java:388)
          at 
org.apache.ignite.spi.deployment.uri.GridUriDeploymentFileProcessor.processFile(GridUriDeploymentFileProcessor.java:108)
          at 
org.apache.ignite.spi.deployment.uri.UriDeploymentSpi$2.onNewOrUpdatedFile(UriDeploymentSpi.java:590)
          at 
org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner$URIContext.handleFile(UriDeploymentFileScanner.java:268)
          at 
org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner$URIContext$1.handle(UriDeploymentFileScanner.java:178)
          at 
org.apache.ignite.spi.deployment.uri.scanners.GridDeploymentFolderScannerHelper.scanFolder(GridDeploymentFolderScannerHelper.java:49)
          at 
org.apache.ignite.spi.deployment.uri.scanners.GridDeploymentFolderScannerHelper.scanFolder(GridDeploymentFolderScannerHelper.java:52)
          at 
org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner$URIContext.scan(UriDeploymentFileScanner.java:183)
          at 
org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner.scan(UriDeploymentFileScanner.java:73){code}
The same issue exists for `bad-signed-deployfile.gar` with 
`GridUriDeploymentTestWithNameTask6`.

*Fix*

Replace `ant zip update="yes"` with the standard unzip → copy → zip pattern 
that works reliably across all Ant versions:
{code:java}
 <unzip src=".../${bad-signed.jar}" dest="${basedir}/target/file_tmp/zipfix" />
<copy 
file="${basedir}/target/classes/.../GridUriDeploymentTestWithNameTask11.class"
      todir="${basedir}/target/file_tmp/zipfix/..." overwrite="yes" />
<delete file=".../${bad-signed.jar}" />
<zip destfile=".../${bad-signed.jar}" 
basedir="${basedir}/target/file_tmp/zipfix" />{code}
Applied to both `deployfile-bad-signed.jar` and `bad-signed-deployfile.gar`.


> Fix flaky GridFileDeploymentSelfTest
> ------------------------------------
>
>                 Key: IGNITE-28863
>                 URL: https://issues.apache.org/jira/browse/IGNITE-28863
>             Project: Ignite
>          Issue Type: Test
>            Reporter: Dmitry Werner
>            Assignee: Dmitry Werner
>            Priority: Minor
>              Labels: MakeTeamcityGreenAgain, ise
>         Attachments: _Apache_Ignite_2.x_Tests_SPI_URI_Deploy_40213.log
>
>          Time Spent: 1h
>  Remaining Estimate: 0h
>
> *Root Cause*
> The pom.xml build script intentionally creates a corrupted JAR for testing 
> bad signature verification:
> 1. Copies `GridUriDeploymentTestTask11.class` under the name 
> `GridUriDeploymentTestWithNameTask11.class` (bytecode contains `this_class = 
> GridUriDeploymentTestTask11` → mismatch with filename)
> 2. Packs this corrupted class into JAR, signs it, then updates the JAR with 
> the correct class:
> {code:java}
>  <zip destfile="...${bad-signed.jar}" basedir=".../target/classes/"
>      includes=".../GridUriDeploymentTestWithNameTask11.class" update="yes" 
> />{code}
> The problem: in Ant 1.10.x, {{zip update="yes"}} sometimes silently skips the 
> replacement. The “file is newer than the archive entry” check operates at the 
> 2‑second granularity boundary of DOS timestamps in ZIP archives, and the 
> sequence {{sleep 2 + touch}} sets the file’s mtime exactly on this boundary. 
> When the check determines that the file is “not newer,” the archive retains 
> only the original, corrupted entry.
> This crashes the `grid-uri-scanner` thread, stopping all subsequent 
> deployments.
> All `checkTask()` assertions fail with `findResource() == null`.
> {code:java}
>         
> [ERROR][grid-uri-scanner-#35%file.GridFileDeploymentSelfTest%-#269%file.GridFileDeploymentSelfTest%][UriDeploymentScannerManager]
>  Runtime error caught during grid runnable execution: 
>         IgniteSpiThread 
> [name=grid-uri-scanner-#35%file.GridFileDeploymentSelfTest%-#269%file.GridFileDeploymentSelfTest%]
>        java.lang.NoClassDefFoundError: 
> org/apache/ignite/spi/deployment/uri/tasks/GridUriDeploymentTestWithNameTask11
>  (wrong name: org/apache/ignite/spi/deployment/uri/tasks/
>         GridUriDeploymentTestTask11)
>            at java.base/java.lang.ClassLoader.defineClass1(Native Method)
>            at 
> java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
>            at 
> java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
>            at 
> java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
>            at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
>            at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
>            at 
> java.base/java.security.AccessController.doPrivileged(JavaAccessController.java:77)
>           at 
> java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420)
>           at 
> org.apache.ignite.spi.deployment.uri.GridUriDeploymentClassLoader.loadClass(GridUriDeploymentClassLoader.java:56)
>           at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
>           at 
> org.apache.ignite.spi.deployment.uri.GridUriDeploymentFileResourceLoader.createResource(GridUriDeploymentFileResourceLoader.java:72)
>           at 
> org.apache.ignite.spi.deployment.uri.GridUriDeploymentDiscovery.findResourcesInDirectory(GridUriDeploymentDiscovery.java:109)
>           ... (recursive directory traversal) ...
>           at 
> org.apache.ignite.spi.deployment.uri.GridUriDeploymentDiscovery.getClasses(GridUriDeploymentDiscovery.java:71)
>           at 
> org.apache.ignite.spi.deployment.uri.GridUriDeploymentFileProcessor.processNoDescriptorFile(GridUriDeploymentFileProcessor.java:388)
>           at 
> org.apache.ignite.spi.deployment.uri.GridUriDeploymentFileProcessor.processFile(GridUriDeploymentFileProcessor.java:108)
>           at 
> org.apache.ignite.spi.deployment.uri.UriDeploymentSpi$2.onNewOrUpdatedFile(UriDeploymentSpi.java:590)
>           at 
> org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner$URIContext.handleFile(UriDeploymentFileScanner.java:268)
>           at 
> org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner$URIContext$1.handle(UriDeploymentFileScanner.java:178)
>           at 
> org.apache.ignite.spi.deployment.uri.scanners.GridDeploymentFolderScannerHelper.scanFolder(GridDeploymentFolderScannerHelper.java:49)
>           at 
> org.apache.ignite.spi.deployment.uri.scanners.GridDeploymentFolderScannerHelper.scanFolder(GridDeploymentFolderScannerHelper.java:52)
>           at 
> org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner$URIContext.scan(UriDeploymentFileScanner.java:183)
>           at 
> org.apache.ignite.spi.deployment.uri.scanners.file.UriDeploymentFileScanner.scan(UriDeploymentFileScanner.java:73){code}
> The same issue exists for `bad-signed-deployfile.gar` with 
> `GridUriDeploymentTestWithNameTask6`.
> *Fix*
> Replace `ant zip update="yes"` with the standard unzip → copy → zip pattern 
> and remove the logic that depends on timestamps:
> {code:java}
>  <unzip src=".../${bad-signed.jar}" dest="${basedir}/target/file_tmp/zipfix" 
> />
> <copy 
> file="${basedir}/target/classes/.../GridUriDeploymentTestWithNameTask11.class"
>       todir="${basedir}/target/file_tmp/zipfix/..." overwrite="yes" />
> <delete file=".../${bad-signed.jar}" />
> <zip destfile=".../${bad-signed.jar}" 
> basedir="${basedir}/target/file_tmp/zipfix" />{code}
> Applied to both `deployfile-bad-signed.jar` and `bad-signed-deployfile.gar`.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to