matthiasblaesing commented on PR #6160:
URL: https://github.com/apache/netbeans/pull/6160#issuecomment-1634748996

   @asbachb as I feared, in offline mode this was problematic. I removed the 
`jsf-impl` artifact from the local repository and cut the network connections.  
I got two error cases:
   
   **The first issue** is, that the check if the maven artifact is present is 
not correct/incomplete. The maven resolver gives back a path, but the path 
point to a non-existing file. I got this exception:
   
   <details>
   <summary>Exception</summary>
   
   ```
   WARNING [org.netbeans.modules.csl.editor.semantic.SemanticHighlighter]: 
SemanticAnalyzer = 
org.netbeans.modules.html.editor.gsf.HtmlSemanticAnalyzer@13bbb006; Language = 
org.netbeans.modules.csl.core.Language@541b0c9[text/html (mimetype = text/html; 
ParserResult = 
org.netbeans.modules.html.editor.api.gsf.HtmlParserResult$Lkp@66b7c8cd(mimepath 
= MimePath[text/xhtml/text/html])
   java.lang.NullPointerException: Cannot invoke 
"org.openide.filesystems.FileObject.isValid()" because "fo" is null
        at 
org.openide.filesystems.JarArchiveRootProvider.isArchiveFile(JarArchiveRootProvider.java:72)
        at org.openide.filesystems.FileUtil.getArchiveRoot(FileUtil.java:1918)
        at 
org.netbeans.modules.web.jsf.editor.facelets.DefaultFaceletLibraries.init(DefaultFaceletLibraries.java:80)
        at 
org.netbeans.modules.web.jsf.editor.facelets.DefaultFaceletLibraries.<init>(DefaultFaceletLibraries.java:67)
        at 
org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport.parseLibraries(FaceletsLibrarySupport.java:368)
        at 
org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport._findLibraries(FaceletsLibrarySupport.java:327)
        at 
org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport.findLibraries(FaceletsLibrarySupport.java:272)
        at 
org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport.getNamespaceLibraryMapping(FaceletsLibrarySupport.java:175)
        at 
org.netbeans.modules.web.jsf.editor.JsfSupportImpl.getLibrary(JsfSupportImpl.java:224)
        at 
org.netbeans.modules.web.jsf.editor.JsfPageMetadataProvider.getMetadataMap(JsfPageMetadataProvider.java:74)
        at 
org.netbeans.modules.web.common.api.WebPageMetadata.getMetadata(WebPageMetadata.java:54)
        at 
org.netbeans.modules.web.common.api.WebPageMetadata.getMetadata(WebPageMetadata.java:113)
        at 
org.netbeans.modules.web.common.api.WebPageMetadata.getContentMimeType(WebPageMetadata.java:87)
        at 
org.netbeans.modules.html.editor.gsf.HtmlSemanticAnalyzer.run(HtmlSemanticAnalyzer.java:60)
   ```
   </details>
   
   I suggest to adjust the contract of the provider to require the provider to 
only return valid paths.
   
   <details>
   <summary>Suggested fix</summary>
   
   ```diff
   --- 
a/enterprise/web.jsfapi/src/org/netbeans/modules/web/jsfapi/spi/JsfReferenceImplementationProvider.java
   +++ 
b/enterprise/web.jsfapi/src/org/netbeans/modules/web/jsfapi/spi/JsfReferenceImplementationProvider.java
   @@ -27,5 +27,11 @@
     */
    public interface JsfReferenceImplementationProvider {
    
   +    /**
   +     * Determine the path to the JSF reference implementation JAR.
   +     *
   +     * @param jsfVersion
   +     * @return path to the JAR or {@code null} if not found
   +     */
        Path artifactPathFor(JsfVersion jsfVersion);
    }
   --- 
a/enterprise/maven.j2ee/src/org/netbeans/modules/maven/j2ee/MavenJsfReferenceImplementationProvider.java
   +++ 
b/enterprise/maven.j2ee/src/org/netbeans/modules/maven/j2ee/MavenJsfReferenceImplementationProvider.java
   @@ -18,11 +18,12 @@
     */
    package org.netbeans.modules.maven.j2ee;
    
   +import java.nio.file.Files;
    import java.nio.file.Path;
   -import java.nio.file.Paths;
    import java.util.Collections;
    import java.util.EnumMap;
    import java.util.Map;
   +import java.util.Optional;
    import org.apache.maven.artifact.Artifact;
    import org.apache.maven.artifact.repository.ArtifactRepository;
    import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
   @@ -82,6 +83,10 @@
                return null;
            }
    
   -        return Paths.get(jsfRIArtifact.getFile().toURI());
   +        return Optional.ofNullable(jsfRIArtifact)
   +                .map(artifact -> artifact.getFile())
   +                .map(file -> file.toPath())
   +                .filter(file -> Files.exists(file))
   +                .orElse(null);
        }
    }
   
   ```
   </details>
   
   **The second issue** is that the schemas in the reference implementation 
JARs are not optimal. They contain this:
   
   ```xml
     <xsd:import namespace="http://www.w3.org/XML/1998/namespace";
              schemaLocation="http://www.w3.org/2001/xml.xsd"/>
   ```
   
   The schema parse will then try to load the XSD from network. This is a 
privacy and performance problem. NetBeans has a solution for this: We carry the 
schemas and can use the NetBeans `UserCatalog` to resolve them. In offline mode 
I see an exception:
   
   <details>
   <summary>Exception</summary>
   
   ```
   INFO [null]: Error parsing facelets library descriptor
   org.xml.sax.SAXParseException; systemId: 
jar:file:/home/matthias/src/netbeans/nbbuild/netbeans/enterprise/modules/ext/jsf-2_2/javax.faces.jar!/com/sun/faces/javaee_5.xsd;
 lineNumber: 182; columnNumber: 33; src-resolve: Name 'xml:lang' kann nicht als 
'attribute declaration'-Komponente aufgelöst werden.
        at 
java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
        at 
java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:135)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:396)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4254)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:4237)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl(XSDHandler.java:1728)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDAttributeTraverser.traverseLocal(XSDAttributeTraverser.java:90)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDAbstractTraverser.traverseAttrsAndAttrGrps(XSDAbstractTraverser.java:760)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDComplexTypeTraverser.traverseSimpleContent(XSDComplexTypeTraverser.java:656)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDComplexTypeTraverser.traverseComplexTypeDecl(XSDComplexTypeTraverser.java:304)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDComplexTypeTraverser.traverseGlobal(XSDComplexTypeTraverser.java:191)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseSchemas(XSDHandler.java:1480)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:663)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:618)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:577)
        at 
java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:543)
        at 
java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:281)
        at 
java.xml/javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:612)
        at 
java.xml/javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:644)
        at 
org.netbeans.modules.web.jsf.editor.facelets.mojarra.ConfigManager$ParseTask.getSchema(ConfigManager.java:1216)
        at 
org.netbeans.modules.web.jsf.editor.facelets.mojarra.ConfigManager$ParseTask.getDocument(ConfigManager.java:1140)
        at 
org.netbeans.modules.web.jsf.editor.facelets.mojarra.ConfigManager$ParseTask.call(ConfigManager.java:1045)
   Caused: com.sun.faces.config.ConfigurationException: Unable to parse 
document 
'jar:file:/home/matthias/.m2/repository/org/primefaces/primefaces/11.0.0/primefaces-11.0.0.jar!/META-INF/primefaces-p.taglib.xml':
 src-resolve: Name 'xml:lang' kann nicht als 'attribute declaration'-Komponente 
aufgelöst werden.
        at 
org.netbeans.modules.web.jsf.editor.facelets.mojarra.ConfigManager$ParseTask.call(ConfigManager.java:1054)
        at 
org.netbeans.modules.web.jsf.editor.facelets.mojarra.ConfigManager$ParseTask.call(ConfigManager.java:971)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at 
org.netbeans.modules.web.jsf.editor.facelets.mojarra.ConfigManager.getConfigDocuments(ConfigManager.java:775)
   Caused: java.util.concurrent.ExecutionException
        at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
   [catch] at 
org.netbeans.modules.web.jsf.editor.facelets.mojarra.ConfigManager.getConfigDocuments(ConfigManager.java:792)
        at 
org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport.parseLibraries(FaceletsLibrarySupport.java:408)
        at 
org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport._findLibraries(FaceletsLibrarySupport.java:327)
        at 
org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport.findLibraries(FaceletsLibrarySupport.java:272)
        at 
org.netbeans.modules.web.jsf.editor.facelets.FaceletsLibrarySupport.getNamespaceLibraryMapping(FaceletsLibrarySupport.java:175)
        at 
org.netbeans.modules.web.jsf.editor.JsfSupportImpl.getLibrary(JsfSupportImpl.java:224)
        at 
org.netbeans.modules.web.jsf.editor.JsfPageMetadataProvider.getMetadataMap(JsfPageMetadataProvider.java:74)
        at 
org.netbeans.modules.web.common.api.WebPageMetadata.getMetadata(WebPageMetadata.java:54)
        at 
org.netbeans.modules.web.common.api.WebPageMetadata.getMetadata(WebPageMetadata.java:113)
        at 
org.netbeans.modules.web.common.api.WebPageMetadata.getContentMimeType(WebPageMetadata.java:87)
        at 
org.netbeans.modules.html.editor.gsf.HtmlSemanticAnalyzer.run(HtmlSemanticAnalyzer.java:60)
        at 
org.netbeans.modules.csl.editor.semantic.SemanticHighlighter.process(SemanticHighlighter.java:278)
        at 
org.netbeans.modules.csl.editor.semantic.SemanticHighlighter.access$000(SemanticHighlighter.java:57)
        at 
org.netbeans.modules.csl.editor.semantic.SemanticHighlighter$1.run(SemanticHighlighter.java:108)
        at 
org.netbeans.modules.csl.editor.semantic.SemanticHighlighter$1.run(SemanticHighlighter.java:117)
        at 
org.netbeans.modules.parsing.impl.TaskProcessor.callUserTask(TaskProcessor.java:586)
        at 
org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:132)
        at 
org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:116)
        at 
org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:181)
        at 
org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:178)
        at 
org.netbeans.modules.masterfs.filebasedfs.utils.FileChangedManager.priorityIO(FileChangedManager.java:153)
        at 
org.netbeans.modules.masterfs.providers.ProvidedExtensions.priorityIO(ProvidedExtensions.java:335)
        at 
org.netbeans.modules.parsing.nb.DataObjectEnvFactory.runPriorityIO(DataObjectEnvFactory.java:118)
        at 
org.netbeans.modules.parsing.impl.Utilities.runPriorityIO(Utilities.java:67)
        at 
org.netbeans.modules.parsing.impl.TaskProcessor.runUserTask(TaskProcessor.java:178)
        at 
org.netbeans.modules.parsing.api.ParserManager.parse(ParserManager.java:83)
        at 
org.netbeans.modules.csl.editor.semantic.SemanticHighlighter.run(SemanticHighlighter.java:98)
        at 
org.netbeans.modules.csl.editor.semantic.SemanticHighlighter.run(SemanticHighlighter.java:57)
        at 
org.netbeans.modules.parsing.impl.TaskProcessor.callParserResultTask(TaskProcessor.java:561)
        at 
org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.run(TaskProcessor.java:786)
        at org.openide.util.lookup.Lookups.executeWith(Lookups.java:288)
        at 
org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.execute(TaskProcessor.java:702)
        at 
org.netbeans.modules.parsing.impl.TaskProcessor$CompilationJob.run(TaskProcessor.java:663)
        at 
java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at 
org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1419)
        at 
org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
        at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287)
        at 
org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2034)
   INFO [null]: Error parsing facelets library descriptor
   ```
   </details>
   
   <details>
   <summary>Suggested fix</summary>
   
   ```diff
   # This patch file was generated by NetBeans IDE
   # It uses platform neutral UTF-8 encoding and \n newlines.
   --- 
a/enterprise/web.jsf.editor/src/org/netbeans/modules/web/jsf/editor/facelets/mojarra/ConfigManager.java
   +++ 
b/enterprise/web.jsf.editor/src/org/netbeans/modules/web/jsf/editor/facelets/mojarra/ConfigManager.java
   @@ -68,6 +68,8 @@
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
   +import java.io.Reader;
   +import java.io.StringWriter;
    import java.lang.annotation.Annotation;
    import java.lang.ref.WeakReference;
    import java.net.MalformedURLException;
   @@ -120,9 +122,13 @@
    import javax.xml.transform.stream.StreamSource;
    import javax.xml.validation.Schema;
    import javax.xml.validation.SchemaFactory;
   +import org.netbeans.api.xml.services.UserCatalog;
    import org.netbeans.modules.web.jsf.editor.facelets.DefaultFaceletLibraries;
    import org.netbeans.modules.web.jsfapi.api.JsfNamespaces;
   +import org.openide.util.Exceptions;
    import org.w3c.dom.*;
   +import org.w3c.dom.ls.LSInput;
   +import org.w3c.dom.ls.LSResourceResolver;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXException;
    import org.xml.sax.SAXParseException;
   @@ -1180,6 +1186,31 @@
                WeakReference<Schema> schema = SCHEMA_CACHE.get(id);
                if (schema == null || schema.get() == null) {
                    SchemaFactory schemaFactory = 
SchemaFactory.newDefaultInstance();
   +                schemaFactory.setResourceResolver(new LSResourceResolver() {
   +                    @Override
   +                    public LSInput resolveResource(String type, String 
namespaceURI, String publicId, String systemId, String baseURI) {
   +                        try {
   +                            InputSource is = UserCatalog.getDefault().
   +                                    getEntityResolver().
   +                                    resolveEntity(publicId, systemId);
   +                            if (is != null) {
   +                                return new LSInputFromInputSource(is);
   +                            }
   +                        } catch (SAXException | IOException ex) {
   +                            LOGGER.log(
   +                                    Level.FINE,
   +                                    "Failed to resolve namespaceURI: {}, 
publicId: {}, systemId: {}, baseURI: {}",
   +                                    new Object[] {
   +                                        namespaceURI,
   +                                        publicId,
   +                                        systemId,
   +                                        baseURI
   +                                    }
   +                            );
   +                        }
   +                        return null;
   +                    }
   +                });
                    schema = new 
WeakReference<>(schemaFactory.newSchema(jsfRIClassLoader.getResource(schemaResourceName)));
    
                    SCHEMA_CACHE.put(id, schema);
   @@ -1345,4 +1376,96 @@
        } // END URITask
    
    
   +    /**
   +     * Helperclass to supply the SchemaFactory with XSDs from the NB catalog
   +     */
   +    private static class LSInputFromInputSource implements LSInput {
   +
   +        private final InputSource is;
   +
   +        public LSInputFromInputSource(InputSource is) {
   +            this.is = is;
   +        }
   +
   +        @Override
   +        public Reader getCharacterStream() {
   +            return is.getCharacterStream();
   +        }
   +
   +        @Override
   +        public void setCharacterStream(Reader characterStream) {
   +        }
   +
   +        @Override
   +        public InputStream getByteStream() {
   +            return is.getByteStream();
   +        }
   +
   +        @Override
   +        public void setByteStream(InputStream byteStream) {
   +        }
   +
   +        @Override
   +        public String getStringData() {
   +            try (Reader r = getCharacterStream()) {
   +                if (r == null) {
   +                    return null;
   +                }
   +                StringWriter sw = new StringWriter();
   +                getCharacterStream().transferTo(sw);
   +                return sw.toString();
   +            } catch (IOException ex) {
   +                throw new RuntimeException(ex);
   +            }
   +        }
   +
   +        @Override
   +        public void setStringData(String stringData) {
   +        }
   +
   +        @Override
   +        public String getSystemId() {
   +            return is.getSystemId();
   +        }
   +
   +        @Override
   +        public void setSystemId(String systemId) {
   +        }
   +
   +        @Override
   +        public String getPublicId() {
   +            return is.getPublicId();
   +        }
   +
   +        @Override
   +        public void setPublicId(String publicId) {
   +        }
   +
   +        @Override
   +        public String getBaseURI() {
   +            return "";
   +        }
   +
   +        @Override
   +        public void setBaseURI(String baseURI) {
   +        }
   +
   +        @Override
   +        public String getEncoding() {
   +            return is.getEncoding();
   +        }
   +
   +        @Override
   +        public void setEncoding(String encoding) {
   +        }
   +
   +        @Override
   +        public boolean getCertifiedText() {
   +            return false;
   +        }
   +
   +        @Override
   +        public void setCertifiedText(boolean certifiedText) {
   +        }
   +    }
    }
   ```
   </details>


-- 
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: notifications-unsubscr...@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@netbeans.apache.org
For additional commands, e-mail: notifications-h...@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to