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

Olabusayo Kilo reassigned DAFFODIL-2973:
----------------------------------------

    Assignee: Olabusayo Kilo

> 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
>            Assignee: Olabusayo Kilo
>            Priority: Blocker
>
> 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 investigating, 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