Antoine Caradec created DAFFODIL-2973:
-----------------------------------------

             Summary: Daffodil is unable to open its own XSD files inside a 
linux native image produced with Quarkus
                 Key: DAFFODIL-2973
                 URL: https://issues.apache.org/jira/browse/DAFFODIL-2973
             Project: Daffodil
          Issue Type: Bug
          Components: General
    Affects Versions: 3.10.0
         Environment: Quarkus 3.17.8 with GraalVM 21 Community Edition.
Linux executable run inside a virtual machine with AlmaLinux 8.10
            Reporter: Antoine Caradec


I tried to integrate Daffodil inside a linux native image via Quarkus and 
GraalVM, and got an error when trying to compile a DFDL schema with : 

 

 
{code:java}
Compiler c = Daffodil.compiler();
ProcessorFactory pf = c.compileSource(...); //error here{code}
 

 

Here is the error :

 

 
{code:java}
Schema Definition Error: Error loading schema due to Invalid or unsupported 
schemaLocation URI: Unrecognized URI type: 
resource:/org/apache/daffodil/xsd/XMLSchema_for_DFDL.xsd
Schema context: Location in 
/root/Documents/quarkus/getting-started-dfdl/files/helloWorld.dfdl.xsd
        at 
org.apache.daffodil.core.dsom.DFDLSchemaFileLoadErrorHandler.$anonfun$loaderSDEs$1(DFDLSchemaFile.scala:60)
        at scala.collection.immutable.List.map(List.scala:293)
        at 
org.apache.daffodil.core.dsom.DFDLSchemaFileLoadErrorHandler.loaderSDEs(DFDLSchemaFile.scala:51)
        at 
org.apache.daffodil.core.dsom.DFDLSchemaFileLoadErrorHandler.handleLoadErrors(DFDLSchemaFile.scala:99)
        at 
org.apache.daffodil.core.dsom.DFDLSchemaFile.$anonfun$iiXMLSchemaDocument$1(DFDLSchemaFile.scala:236)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body$lzycompute(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.liftedTree1$1(OOLAG.scala:707)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny$lzycompute(OOLAG.scala:705)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny(OOLAG.scala:699)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value$lzycompute(OOLAG.scala:754)
        at org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value(OOLAG.scala:754)
        at 
org.apache.daffodil.core.dsom.DFDLSchemaFile.iiXMLSchemaDocument$lzycompute(DFDLSchemaFile.scala:220)
        at 
org.apache.daffodil.core.dsom.DFDLSchemaFile.iiXMLSchemaDocument(DFDLSchemaFile.scala:220)
        at 
org.apache.daffodil.core.dsom.Import.$anonfun$mapPair$3(Import.scala:68)
        at scala.Option.getOrElse(Option.scala:189)
        at 
org.apache.daffodil.core.dsom.Import.$anonfun$mapPair$1(Import.scala:47)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body$lzycompute(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.liftedTree1$1(OOLAG.scala:707)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny$lzycompute(OOLAG.scala:705)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny(OOLAG.scala:699)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value$lzycompute(OOLAG.scala:754)
        at org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value(OOLAG.scala:754)
        at 
org.apache.daffodil.core.dsom.Import.mapPair$lzycompute(Import.scala:45)
        at org.apache.daffodil.core.dsom.Import.mapPair(Import.scala:45)
        at 
org.apache.daffodil.core.dsom.IIBase.$anonfun$notSeenThisBefore$1(IIBase.scala:149)
        at 
scala.runtime.java8.JFunction0$mcZ$sp.apply(JFunction0$mcZ$sp.java:23)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body$lzycompute(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.liftedTree1$1(OOLAG.scala:707)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny$lzycompute(OOLAG.scala:705)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny(OOLAG.scala:699)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value$lzycompute(OOLAG.scala:754)
        at org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value(OOLAG.scala:754)
        at 
org.apache.daffodil.core.dsom.IIBase.notSeenThisBefore$lzycompute(IIBase.scala:148)
        at 
org.apache.daffodil.core.dsom.IIBase.notSeenThisBefore(IIBase.scala:148)
        at 
org.apache.daffodil.core.dsom.IIBase.$anonfun$iiSchemaFileMaybe$1(IIBase.scala:255)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body$lzycompute(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.liftedTree1$1(OOLAG.scala:707)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny$lzycompute(OOLAG.scala:705)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny(OOLAG.scala:699)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value$lzycompute(OOLAG.scala:754)
        at org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value(OOLAG.scala:754)
        at 
org.apache.daffodil.core.dsom.IIBase.iiSchemaFileMaybe$lzycompute(IIBase.scala:254)
        at 
org.apache.daffodil.core.dsom.IIBase.iiSchemaFileMaybe(IIBase.scala:254)
        at 
org.apache.daffodil.core.dsom.IIBase.$anonfun$seenAfter$1(IIBase.scala:178)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body$lzycompute(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.liftedTree1$1(OOLAG.scala:707)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny$lzycompute(OOLAG.scala:705)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny(OOLAG.scala:699)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value$lzycompute(OOLAG.scala:754)
        at org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value(OOLAG.scala:754)
        at 
org.apache.daffodil.core.dsom.IIBase.seenAfter$lzycompute(IIBase.scala:177)
        at org.apache.daffodil.core.dsom.IIBase.seenAfter(IIBase.scala:177)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.$anonfun$getImportsOrIncludes$1(SchemaDocIncludesAndImportsMixin.scala:214)
        at 
scala.collection.TraversableOnce$folder$1.apply(TraversableOnce.scala:196)
        at 
scala.collection.TraversableOnce$folder$1.apply(TraversableOnce.scala:194)
        at scala.collection.Iterator.foreach(Iterator.scala:943)
        at scala.collection.Iterator.foreach$(Iterator.scala:943)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1431)
        at scala.collection.IterableLike.foreach(IterableLike.scala:74)
        at scala.collection.IterableLike.foreach$(IterableLike.scala:73)
        at scala.collection.AbstractIterable.foreach(Iterable.scala:56)
        at scala.collection.TraversableOnce.foldLeft(TraversableOnce.scala:199)
        at scala.collection.TraversableOnce.foldLeft$(TraversableOnce.scala:192)
        at scala.collection.AbstractTraversable.foldLeft(Traversable.scala:108)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.getImportsOrIncludes(SchemaDocIncludesAndImportsMixin.scala:211)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.getImportsOrIncludes$(SchemaDocIncludesAndImportsMixin.scala:206)
        at 
org.apache.daffodil.core.dsom.XMLSchemaDocument.getImportsOrIncludes(SchemaDocument.scala:68)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.$anonfun$ismli_$1(SchemaDocIncludesAndImportsMixin.scala:225)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body$lzycompute(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.liftedTree1$1(OOLAG.scala:707)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny$lzycompute(OOLAG.scala:705)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny(OOLAG.scala:699)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value$lzycompute(OOLAG.scala:754)
        at org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value(OOLAG.scala:754)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.org$apache$daffodil$core$dsom$SchemaDocIncludesAndImportsMixin$$ismli_(SchemaDocIncludesAndImportsMixin.scala:224)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.org$apache$daffodil$core$dsom$SchemaDocIncludesAndImportsMixin$$ismli_$(SchemaDocIncludesAndImportsMixin.scala:224)
        at 
org.apache.daffodil.core.dsom.XMLSchemaDocument.org$apache$daffodil$core$dsom$SchemaDocIncludesAndImportsMixin$$ismli_$lzycompute(SchemaDocument.scala:68)
        at 
org.apache.daffodil.core.dsom.XMLSchemaDocument.org$apache$daffodil$core$dsom$SchemaDocIncludesAndImportsMixin$$ismli_(SchemaDocument.scala:68)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.importStatementsMap(SchemaDocIncludesAndImportsMixin.scala:222)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.importStatementsMap$(SchemaDocIncludesAndImportsMixin.scala:222)
        at 
org.apache.daffodil.core.dsom.XMLSchemaDocument.importStatementsMap(SchemaDocument.scala:68)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.$anonfun$sali_$1(SchemaDocIncludesAndImportsMixin.scala:232)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body$lzycompute(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.liftedTree1$1(OOLAG.scala:707)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny$lzycompute(OOLAG.scala:705)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny(OOLAG.scala:699)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value$lzycompute(OOLAG.scala:754)
        at org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value(OOLAG.scala:754)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.org$apache$daffodil$core$dsom$SchemaDocIncludesAndImportsMixin$$sali_(SchemaDocIncludesAndImportsMixin.scala:231)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.org$apache$daffodil$core$dsom$SchemaDocIncludesAndImportsMixin$$sali_$(SchemaDocIncludesAndImportsMixin.scala:231)
        at 
org.apache.daffodil.core.dsom.XMLSchemaDocument.org$apache$daffodil$core$dsom$SchemaDocIncludesAndImportsMixin$$sali_$lzycompute(SchemaDocument.scala:68)
        at 
org.apache.daffodil.core.dsom.XMLSchemaDocument.org$apache$daffodil$core$dsom$SchemaDocIncludesAndImportsMixin$$sali_(SchemaDocument.scala:68)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.seenAfter(SchemaDocIncludesAndImportsMixin.scala:229)
        at 
org.apache.daffodil.core.dsom.SchemaDocIncludesAndImportsMixin.seenAfter$(SchemaDocIncludesAndImportsMixin.scala:229)
        at 
org.apache.daffodil.core.dsom.XMLSchemaDocument.seenAfter(SchemaDocument.scala:68)
        at 
org.apache.daffodil.core.dsom.SchemaSetIncludesAndImportsMixin.$anonfun$allSchemaFiles$1(SchemaSetIncludesAndImportsMixins.scala:66)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body$lzycompute(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.body(OOLAG.scala:520)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.liftedTree1$1(OOLAG.scala:707)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny$lzycompute(OOLAG.scala:705)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValueBase.valueAsAny(OOLAG.scala:699)
        at 
org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value$lzycompute(OOLAG.scala:754)
        at org.apache.daffodil.lib.oolag.OOLAG$OOLAGValue.value(OOLAG.scala:754)
        at 
org.apache.daffodil.core.dsom.SchemaSetIncludesAndImportsMixin.allSchemaFiles(SchemaSetIncludesAndImportsMixins.scala:64)
        at 
org.apache.daffodil.core.dsom.SchemaSetIncludesAndImportsMixin.allSchemaFiles$(SchemaSetIncludesAndImportsMixins.scala:64)
        at 
org.apache.daffodil.core.dsom.SchemaSet.allSchemaFiles$lzycompute(SchemaSet.scala:92)
        at 
org.apache.daffodil.core.dsom.SchemaSet.allSchemaFiles(SchemaSet.scala:92)
        at 
org.apache.daffodil.core.dsom.SchemaSet.$anonfun$isValid$2(SchemaSet.scala:181)
        at 
scala.runtime.java8.JFunction0$mcZ$sp.apply(JFunction0$mcZ$sp.java:23)
        at org.apache.daffodil.lib.oolag.OOLAG$.keepGoing(OOLAG.scala:65)
        at 
org.apache.daffodil.core.dsom.SchemaSet.isValid$lzycompute(SchemaSet.scala:180)
        at org.apache.daffodil.core.dsom.SchemaSet.isValid(SchemaSet.scala:172)
        at 
org.apache.daffodil.core.dsom.SchemaSet.isError$lzycompute(SchemaSet.scala:567)
        at org.apache.daffodil.core.dsom.SchemaSet.isError(SchemaSet.scala:566)
        at 
org.apache.daffodil.core.compiler.ProcessorFactory.isError$lzycompute(Compiler.scala:147)
        at 
org.apache.daffodil.core.compiler.ProcessorFactory.isError(Compiler.scala:147)
        at 
org.apache.daffodil.core.compiler.Compiler$.org$apache$daffodil$core$compiler$Compiler$$compileSourceSynchronizer(Compiler.scala:426)
        at 
org.apache.daffodil.core.compiler.Compiler.compileSource(Compiler.scala:359)
        at org.apache.daffodil.japi.Compiler.compileSource(Daffodil.scala:170)
        at org.apache.daffodil.japi.Compiler.compileSource(Daffodil.scala:156)
        at org.acme.HelloWorld.start(HelloWorld.java:72) {code}
 

 

We can see that daffodil-lib does not open the file 
resource:/org/apache/daffodil/xsd/XMLSchema_for_DFDL.xsd 

It is infact unable to access any URI with a "resource" scheme (see 
"Unrecognized URI type: resource:/..." above).

 

What happens here is that resources included inside a native linux executable 
are not part of any jar nor file system, and are supposed to be retrieved using 
a "resource" URI scheme which isn't handled equally in every method dealing 
with resource loading.

After invegating, I found a workaround in the class 
daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala.

 

Code in version 3.10.0 :

 
{code:java}
def getResourceRelativeOnlyOption(relPath: String, contextURI: URI): 
Option[URI] = {
  Assert.usage(relPath ne null)
  Assert.usage(contextURI ne null)
  if (contextURI.isOpaque) {
    //
    // We used to call new URL(jarURI, relativePathString)
    // but that is deprecated now (as of Java 20)
    //
    optRelativeJarFileURI(contextURI, relPath)
  } else {
    // context URI is not opaque. It's probably a file URIsrc
    if (contextURI.getScheme == "file") {
      val relURI = contextURI.resolve(relPath)
      if (Paths.get(relURI).toFile.exists())
        Some(relURI)
      else None
    } else {
      // not a file nor an opaque resource URI. What is it?
      throw new IllegalArgumentException(s"Unrecognized URI type: $contextURI")
    }
  }
} {code}
 

 

Workaround :

 
{code:java}
def getResourceRelativeOnlyOption(relPath: String, contextURI: URI): 
Option[URI] = {
    Assert.usage(relPath ne null)
    Assert.usage(contextURI ne null)
    if (contextURI.isOpaque) {
      //
      // We used to call new URL(jarURI, relativePathString)
      // but that is deprecated now (as of Java 20)
      //
      optRelativeJarFileURI(contextURI, relPath)
    } else {
      // context URI is not opaque. It's probably a file URI
      if (contextURI.getScheme == "file") {        val relURI = 
contextURI.resolve(relPath)
        if (Paths.get(relURI).toFile.exists())
          Some(relURI)
        else None
      } else if (contextURI.getScheme == "resource") { //Workaround here
        val relURI = contextURI.resolve(relPath)
        this.getClass().getResource(relURI.getPath())
        // that worked, so we can open it so it exists.
        Some(relURI)
      } else {
        // not a file nor an opaque resource URI. What is it?
        throw new IllegalArgumentException(s"Unrecognized URI type: 
$contextURI")
      }
    }
  }
 {code}
 

This method is the one Daffodil reaches when loading this XSD file, and it can 
only handle "jar" and "file" URI Scheme. In our case, since "resource" URI 
scheme is used, adding a case to handle this scheme seems to fix the issue.

 

Here is a github with a reproductible example that may help investigating : 
[https://github.com/isatoone/Quarkus-DFDL]

 

Quarkus being popular, fixing this issue might promote Daffodil usage in this 
kind of micro-services Framework.

 



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

Reply via email to