Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grid with Custom Components based on PolymerTemplate throw NPE #7116

Closed
lanmaster opened this issue Dec 9, 2019 · 5 comments · Fixed by #7489
Closed

Grid with Custom Components based on PolymerTemplate throw NPE #7116

lanmaster opened this issue Dec 9, 2019 · 5 comments · Fixed by #7489
Assignees
Labels
BFP Bugfix priority, also known as Warranty bug
Milestone

Comments

@lanmaster
Copy link

Vaadin 14.1.1
I create own class component that extends PolymerTemplate.
Then i construct simple View extends VerticalLayout:

  • create Grid component;
  • add some columns to the Grid component, one of them is ComponentRenderer that realize my class;
  • attach Grid component to the View invoking add() method;
    Then i take NPE on view access from browser.
java.lang.RuntimeException: Push failed
	at com.vaadin.flow.server.communication.AtmospherePushConnection.push(AtmospherePushConnection.java:198)
	at com.vaadin.flow.server.communication.AtmospherePushConnection.connect(AtmospherePushConnection.java:287)
	at com.vaadin.flow.server.communication.PushHandler.lambda$new$0(PushHandler.java:97)
	at com.vaadin.flow.server.communication.PushHandler.callWithUi(PushHandler.java:217)
	at com.vaadin.flow.server.communication.PushHandler.onConnect(PushHandler.java:479)
	at com.vaadin.flow.server.communication.PushAtmosphereHandler.onConnect(PushAtmosphereHandler.java:101)
	at com.vaadin.flow.server.communication.PushAtmosphereHandler.onRequest(PushAtmosphereHandler.java:75)
	at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:225)
	at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:114)
	at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:67)
	at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2297)
	at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:594)
	at org.atmosphere.websocket.DefaultWebSocketProcessor.open(DefaultWebSocketProcessor.java:224)
	at org.atmosphere.container.JSR356Endpoint.onOpen(JSR356Endpoint.java:264)
	at org.eclipse.jetty.websocket.jsr356.endpoints.JsrEndpointEventDriver.onConnect(JsrEndpointEventDriver.java:139)
	at org.eclipse.jetty.websocket.common.events.AbstractEventDriver.openSession(AbstractEventDriver.java:216)
	at org.eclipse.jetty.websocket.jsr356.endpoints.AbstractJsrEventDriver.openSession(AbstractJsrEventDriver.java:103)
	at org.eclipse.jetty.websocket.common.WebSocketSession.open(WebSocketSession.java:474)
	at org.eclipse.jetty.websocket.common.WebSocketSession.onOpened(WebSocketSession.java:440)
	at org.eclipse.jetty.io.AbstractConnection.onOpened(AbstractConnection.java:213)
	at org.eclipse.jetty.io.AbstractConnection.onOpen(AbstractConnection.java:205)
	at org.eclipse.jetty.io.AbstractEndPoint.upgrade(AbstractEndPoint.java:442)
	at org.eclipse.jetty.server.HttpConnection.onCompleted(HttpConnection.java:385)
	at org.eclipse.jetty.server.HttpChannel.onCompleted(HttpChannel.java:734)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:363)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:270)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:388)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: null
	at com.vaadin.flow.component.polymertemplate.PolymerTemplate.<init>(PolymerTemplate.java:103)
	at ru.wap.wtwebordermanager.vaadincomponents.polymertextwithdblclick.PolymerTextWithDblClick.<init>(PolymerTextWithDblClick.java:25)
	at ru.wap.wtwebordermanager.jettyserv.vaadin.ordermanager.rightpart.assignedordersgrid.AssignedOrdersGridColumns$1.apply(AssignedOrdersGridColumns.java:265)
	at ru.wap.wtwebordermanager.jettyserv.vaadin.ordermanager.rightpart.assignedordersgrid.AssignedOrdersGridColumns$1.apply(AssignedOrdersGridColumns.java:254)
	at com.vaadin.flow.data.renderer.ComponentRenderer.createComponent(ComponentRenderer.java:239)
	at com.vaadin.flow.data.provider.ComponentDataGenerator.createComponent(ComponentDataGenerator.java:94)
	at com.vaadin.flow.data.provider.ComponentDataGenerator.generateData(ComponentDataGenerator.java:83)
	at com.vaadin.flow.data.provider.CompositeDataGenerator.lambda$generateData$0(CompositeDataGenerator.java:47)
	at java.lang.Iterable.forEach(Iterable.java:75)
	at com.vaadin.flow.data.provider.CompositeDataGenerator.generateData(CompositeDataGenerator.java:47)
	at com.vaadin.flow.data.provider.DataCommunicator.generateJson(DataCommunicator.java:660)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250)
	at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:110)
	at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.vaadin.flow.data.provider.DataCommunicator.getJsonItems(DataCommunicator.java:617)
	at com.vaadin.flow.data.provider.DataCommunicator.collectChangesToSend(DataCommunicator.java:560)
	at com.vaadin.flow.data.provider.DataCommunicator.flush(DataCommunicator.java:477)
	at com.vaadin.flow.data.provider.DataCommunicator.lambda$requestFlush$2f364bb9$1(DataCommunicator.java:425)
	at com.vaadin.flow.internal.StateTree.lambda$runExecutionsBeforeClientResponse$1(StateTree.java:368)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at com.vaadin.flow.internal.StateTree.runExecutionsBeforeClientResponse(StateTree.java:365)
	at com.vaadin.flow.server.communication.UidlWriter.encodeChanges(UidlWriter.java:411)
	at com.vaadin.flow.server.communication.UidlWriter.createUidl(UidlWriter.java:187)
	at com.vaadin.flow.server.communication.UidlWriter.createUidl(UidlWriter.java:225)
	at com.vaadin.flow.server.communication.AtmospherePushConnection.push(AtmospherePushConnection.java:194)

I look at default constructor of PolymerTemplate:

    public PolymerTemplate() {
        this(VaadinService.getCurrent().getDeploymentConfiguration()
                .isCompatibilityMode() ? DefaultTemplateParser.getInstance()
                        : NpmTemplateParser.getInstance(),
                VaadinService.getCurrent());
    }

The VaadinService.getCurrent() return NULL.
It looks like similar to #3789. From it i saw that i need to create components in current UI context. Is it true? If yes, why it is necessary? And why there is invocation of isCompatibilityMode()? Is this redundant in the current version of Vaadin?

@lanmaster
Copy link
Author

lanmaster commented Dec 10, 2019

Added an scheduler that update grid's data. Interesting that is no errors on 5 seconds period of updates. But on 1 second there is an error occured. Looks like thread unsafe operations. In some cases VaadinService.getCurrent() returns Null.

@lanmaster
Copy link
Author

lanmaster commented Dec 11, 2019

grid_update.zip
Create some example.
In MainView.java you can change these parameters:

        // Parameters for error occur
        int initialRowCount = 10;
        int updatePeriodSeconds = 1;

The error occured on my machine with these parameters when starts app. When error occured - the Thread ID with absent VaadinService is printed to console.

Testing environment:
JVM: 1.8.0.45
Windows 7 Pro x64

@lanmaster lanmaster changed the title PolymerTemplate constructor NPE Grid with Custom Components based on PolymerTemplate throw NPE Dec 11, 2019
@denis-anisimov
Copy link
Contributor

The reason of NPE is apparently null returned by VaadinService.getCurrent() .
That may happen if the code is called from a thread other than request dispatching thread without UI:access.

But stacktrace shows that the code is invoked inside StateTree.runExecutionsBeforeClientResponse which definitely should be called so that all locks are acquired and current instances are set correctly.
This happens inside AtmospherePushConnection.push and it's looks like that's the reason:
apparently current instances are not set properly inside push.
This is a bug.

@denis-anisimov
Copy link
Contributor

As a workaround for this bug you may use protected constructor PolymerTemplate(TemplateParser parser, VaadinService service) and pass argument values explicitly by yourself.

@pleku pleku added the BFP Bugfix priority, also known as Warranty label Jan 30, 2020
@denis-anisimov denis-anisimov self-assigned this Feb 3, 2020
@denis-anisimov
Copy link
Contributor

denis-anisimov commented Feb 4, 2020

  • First : thanks a lot for providing a project which can be used to reproduce the bug. I'm able to reproduce it.
  • Second: The project is a bit complicated. It uses embedded Jetty. It's possible to use just jetty maven plugin .The simplified pom file content for the future reference is below.
  • Third: the reason of the bug is: PushHandler::callWithUi is invoked with websocket parameter value false .As a result if (websocket) { is skipped and this part sets the Current instances. At the same time the AtmosphereResource has transport=WEBSOCKET.

So websocket parameter value is wrong. I have to find the reason why it's wrong.

<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>vaadin14-embedded-jetty</artifactId>
    <name>Vaadin 14 with Embedded Jetty</name>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <failOnMissingWebXml>false</failOnMissingWebXml>

        <vaadin.version>14.1.2</vaadin.version>
        <jetty.version>9.4.20.v20190813</jetty.version>
    </properties>

    <repositories>
        <!-- Repository used by many Vaadin add-ons -->
        <repository>
             <id>Vaadin Directory</id>
             <url>https://maven.vaadin.com/vaadin-addons</url>
            <snapshots><enabled>false</enabled></snapshots>
        </repository>
    </repositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <type>pom</type>
                <scope>import</scope>
                <version>${vaadin.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-core</artifactId>
            <exclusions>
                <!-- Webjars are only needed when running in Vaadin 13 compatibility mode -->
                <exclusion>
                    <groupId>com.vaadin.webjar</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.insites</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymer</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymerelements</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.vaadin</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.webcomponents</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- Added to provide logging output as Vaadin uses -->
        <!-- the unbound SLF4J no-operation (NOP) logger implementation -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-continuation</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>websocket-server</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>javax-websocket-server-impl</artifactId>
            <version>${jetty.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.websocket</groupId>
                    <artifactId>javax.websocket-client-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
            </plugin>
             <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.19.v20190610</version>
                <configuration>
                    <!-- If using IntelliJ IDEA with autocompilation, this
                    might cause lots of unnecessary compilations in the
                    background.-->
                    <scanIntervalSeconds>2</scanIntervalSeconds>
                    <!-- Use war output directory to get the webpack files -->
                    <webAppConfig>
                        <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
                    </webAppConfig>
                </configuration>
            </plugin>

            <!--
                Take care of synchronizing java dependencies and imports in
                package.json and main.js files.
                It also creates webpack.config.js if not exists yet.
            -->
            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-frontend</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>


            <!-- Need at least 2.22.0 to support JUnit 5 -->
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M3</version>
            </plugin>
        </plugins>
    </build>
   
</project>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BFP Bugfix priority, also known as Warranty bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants