Duvida sobre Maven(Dependências Maven)

47 respostas Resolvido
mavenspringmysqljavaprogramação
R

Bom dia a todos.

Tenho um arquivo.pdf e preciso abri-lo em um guia no navegador. Como uso Vaadin, que é um frame de front, no site eles disponibilizam um Add-On para fazer esta tarefa, então adicionei a dependência deste Add-On e copiei o código fornecido pelo site Vaadin para o sistema.

Código:

public void navegador() {
        
        VerticalLayout layout = new VerticalLayout();
        
        StreamResource streamResource = new StreamResource(
                "RelatorioVendas.pdf", () -> getClass().getResourceAsStream("/RelatorioVendas.pdf")); // file in src/main/resources/

        PdfBrowserViewer viewer = new PdfBrowserViewer(streamResource);
        viewer.setHeight("100%");
        layout.add(viewer);
    }

Mas este código gera este stack:

java.lang.NoClassDefFoundError: org/vaadin/alejandro/PdfBrowserViewer
	at br.com.fjsistemas.relatorios.PDF.navegador(PDF.java:53) ~[classes/:na]
	at br.com.fjsistemas.relatorios.RelatorioVendaView.lambda$5(RelatorioVendaView.java:131) ~[classes/:na]
	at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:205) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.component.ComponentEventBus.handleDomEvent(ComponentEventBus.java:373) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.component.ComponentEventBus.lambda$addDomTrigger$dd1b7957$1(ComponentEventBus.java:264) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.lambda$fireEvent$2(ElementListenerMap.java:443) ~[flow-server-2.6.3.jar:2.6.3]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1507) ~[na:na]
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.fireEvent(ElementListenerMap.java:443) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.rpc.EventRpcHandler.handleNode(EventRpcHandler.java:61) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:66) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:412) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$1(ServerRpcHandler.java:393) ~[flow-server-2.6.3.jar:2.6.3]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1507) ~[na:na]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:393) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:320) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:92) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1570) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:252) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:111) ~[vaadin-spring-12.4.0.jar:na]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:710) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:457) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at java.base/java.lang.Thread.run(Thread.java:830) ~[na:na]
Caused by: java.lang.ClassNotFoundException: org.vaadin.alejandro.PdfBrowserViewer
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
	at java.base/java.lang.Class.forName(Class.java:416) ~[na:na]
	at org.springframework.boot.devtools.restart.classloader.RestartClassLoader.loadClass(RestartClassLoader.java:145) ~[spring-boot-devtools-2.4.5.jar:2.4.5]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	... 70 common frames omitted

Fui pesquisar para ver o pq deste stack, e em um canal do Discord voltado para programadores vaadin, recebi esta resposta:

Você sabe o que isso significa? Que a implementação não está disponível em tempo de execução porque você a fornecerá de uma dependência diferente (ou JDK ou o contêiner que a executa). Exclua o escopo fornecido ou use compilar (é o padrão).

E deixou este link para descrever o problema
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#dependency-scope

Confesso que não entendi o que ele quis dizer com “JDK ou o contêiner que a executa”…alguém poderia me ajudar a entender?

47 Respostas

S

Posta o código do seu pom.xml.

R

@staroski

<?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>br.com.fjsistemas</groupId>
    <artifactId>fjsistemas</artifactId>
    <name>FJSistemas</name>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <java.version>1.8</java.version>
        <vaadin.version>14.6.3</vaadin.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
    </parent>

    <repositories>
        <!-- The order of definitions matters. Explicitly defining central here to make sure it has the highest priority. -->

        <!-- Main Maven repository -->
        <repository>
            <id>central</id>
            <url>https://repo.maven.apache.org/maven2</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <!-- 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>

    <pluginRepositories>
        <!-- Main Maven repository -->
        <pluginRepository>
            <id>central</id>
            <url>https://repo.maven.apache.org/maven2</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

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

    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <!-- Replace artifactId with vaadin-core to use only free components -->
            <artifactId>vaadin</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>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring-boot-starter</artifactId>
            <exclusions>
                <!-- Excluding so that webjars are not included. -->
                <exclusion>
                    <groupId>com.vaadin</groupId>
                    <artifactId>vaadin-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-testbench</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Include JUnit 4 support for TestBench and others -->
        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.hamcrest</groupId>
                    <artifactId>hamcrest-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
        	<groupId>javax.persistence</groupId>
        	<artifactId>javax.persistence-api</artifactId>
        	<version>2.2</version><!--$NO-MVN-MAN-VER$-->
        </dependency>
        <dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-starter-data-jpa</artifactId>
        	<version>2.5.0</version><!--$NO-MVN-MAN-VER$-->
        </dependency>
        <dependency>
        	<groupId>org.vaadin</groupId>
        	<artifactId>textfieldformatter</artifactId>
        	<version>5.2.0</version>
        </dependency>
        <dependency>
        	<groupId>mysql</groupId>
        	<artifactId>mysql-connector-java</artifactId>
        	<version>8.0.25</version><!--$NO-MVN-MAN-VER$-->
        </dependency>
        <dependency>
        	<groupId>net.sf.jasperreports</groupId>
        	<artifactId>jasperreports</artifactId>
        	<version>6.17.0</version>
        </dependency>
        <dependency>
        	<groupId>org.vaadin.alejandro</groupId>
        	<artifactId>pdf-browser</artifactId>
        	<version>3.1.0</version>
        </dependency>
    </dependencies>
		 
		 <build>
        <defaultGoal>spring-boot:run</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- Clean build and startup time for Vaadin apps sometimes may exceed
                     the default Spring Boot's 30sec timeout.  -->
                <configuration>
                    <wait>500</wait>
                    <maxAttempts>240</maxAttempts>
                </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>
        </plugins>
    </build>

    <profiles>
        <profile>
            <!-- Production mode is activated using -Pproduction -->
            <id>production</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>com.vaadin</groupId>
                        <artifactId>vaadin-maven-plugin</artifactId>
                        <version>${vaadin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>build-frontend</goal>
                                </goals>
                                <phase>compile</phase>
                            </execution>
                        </executions>
                        <configuration>
                            <productionMode>true</productionMode>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <id>it</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>start-spring-boot</id>
                                <phase>pre-integration-test</phase>
                                <goals>
                                    <goal>start</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>stop-spring-boot</id>
                                <phase>post-integration-test</phase>
                                <goals>
                                    <goal>stop</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

                    <!-- Runs the integration tests (*IT) after the server is started -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <trimStackTrace>false</trimStackTrace>
                            <enableAssertions>true</enableAssertions>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

    </profiles>
</project>
L

Opa, eae cara, bão?

O que acho que o cara quis dizer com isso, pelo pouco que conheço, está relacionado às dependências provided do maven.

Por exemplo. Supondo que vc tenha um projeto web rodando no servidor jboss. O Jboss já possui várias das implementações do JavaEE (libs) para que possam ser usadas pelas aplicações que irão rodar dentro dele. Com isso, se sua aplicação for usar alguma dessas dependências, basta vc informar no pom.xml a mesma com o escopo provided. Isso significa que o JAR dessa dependência não será baixada, mas sim usada a que foi provida pelo jboss. Nesse exemplo, o jboss é o container que está executando seu sistema.

A parte da jdk, penso que é referente à api do Java como a de collections, por exemplo, mas confesso que achei confuso a pessoa citar a jdk na explicação.

De qualquer forma, acho que isso não se aplica ao seu problema, pois se trata de alguma dependência que está faltando ou está na versão errada, pois o erro é um ClassNotFoundException.

pessoal do fórum, se falei bobeira ou esqueci de algo, por favor, me corrijam. Vlw!

R

@Lucas_Camara e ai mano, blz? Então, entendi o que vc disse, mas realmente está estranho…estou pensando em não utilizar este Add-On e tentar fazer com Java puro mesmo, talvez seja a solução, estou pesquisando como fazer isso em Java.

L

Esse link talvez te ajude a criar um botão que faça o download do pdf (vc deve ter acesso aos bytes do pdf): https://vaadin.com/forum/thread/17434646/vaadin-10-let-user-download-a-file-with-dynamically-defined-filename

R

@Lucas_Camara

Com servlet não ficaria melhor?

L

Com servlet funcionaria, mas como vc está usando o vaadin (junto com spring), não sei se compensaria. Ainda mais com o Spring. Sempre que trabalhei com spring, nunca tive a necessidade de escrever um servlet na aplicação, pois o spring fornece meios que abstrai toda a complexidade.

R

@Lucas_Camara, blz vou olhar este link que vc mandou…vlw!!

L

E esse add-on aqui, tu já viu?

Parece fácil de usar pelo menos:

Button button = new Button("Gerar relatório");
FileDownloadWrapper buttonWrapper = new FileDownloadWrapper(
    new StreamResource("relatorio.pdf", () -> relatorioService.gerarRelatorio()));
buttonWrapper.wrapComponent(button);
add(buttonWrapper);

Essa parte: relatorioService.gerarRelatorio(), seria responsável por retornar o relatório como um array de bytes (byte[]).

R

@Lucas_Camara

sim parece fácil, mas como ficaria a classe RelatorioService(que neste momento nem existe)?

L

Esse nome RelatorioService foi soh um nome qualquer somente para exemplificar. No seu caso, seria a classe que criou que gera o relatório, porém, em vez de salvar um arquivo no servidor, vc geraria o array de bytes e retornaria no método.

Em outro post, tu tinha postado uma classe que estava correta, mas não lembro o nome dela

R

Essa classe gera o pdf @Lucas_Camara

package br.com.fjsistemas.relatorios;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.stereotype.Component;

import br.com.fjsistemas.repository.VendaRepository;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;

@Component
public class ConverteJrxmlToPdf {

	@SuppressWarnings("unused")
	private VendaRepository vendaRepository;

	private DataSource dataSource;

	public ConverteJrxmlToPdf(VendaRepository vendaRepository, DataSource dataSource) {
		this.vendaRepository = vendaRepository;
		this.dataSource = dataSource;
	}

	public void conversor() throws JRException, SQLException {

		JasperReport document = JasperCompileManager.compileReport(
				"C:\\Users\\fjd2320\\eclipse-workspace\\fjsistemas-vendas-vaadin\\src\\main\\resources\\RelatorioVendas.jrxml");

		JasperPrint print = JasperFillManager.fillReport(document, null, dataSource.getConnection());

		JasperExportManager.exportReportToPdfFile(print,
				"C:\\Users\\fjd2320\\eclipse-workspace\\fjsistemas-vendas-vaadin\\src\\main\\resources\\RelatorioVendas.pdf");
	}

}
L

Essa mesmo, mas essa parte:

JasperExportManager.exportReportToPdfFile(
    print,
    "C:\\Users\\fjd2320\\eclipse-workspace\\fjsistemas-vendas-vaadin\\src\\main\\resources\\RelatorioVendas.pdf"
);

Trocaria por:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
JasperExportManager.exportReportToPdfStream(print, baos);
byte[] relatorio = baos.toByteArray();

return relatorio;

Talvez essa parte que converte o relatório para array de bytes não esteja 100% correta, mas a ideia é essa. E vc usaria o array de bytes no componente File Download Wrapper.

R

@Lucas_Camara
então a classe ficaria assim:

package br.com.fjsistemas.relatorios;

import java.io.ByteArrayOutputStream;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.stereotype.Component;

import br.com.fjsistemas.repository.VendaRepository;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;

@Component
public class ConverteJrxmlToPdf {

	@SuppressWarnings("unused")
	private VendaRepository vendaRepository;

	private DataSource dataSource;

	public ConverteJrxmlToPdf(VendaRepository vendaRepository, DataSource dataSource) {
		this.vendaRepository = vendaRepository;
		this.dataSource = dataSource;
	}

	public byte[] conversor() throws JRException, SQLException {

		JasperReport document = JasperCompileManager.compileReport(
				"C:\\Users\\fjd2320\\eclipse-workspace\\fjsistemas-vendas-vaadin\\src\\main\\resources\\RelatorioVendas.jrxml");

		JasperPrint print = JasperFillManager.fillReport(document, null, dataSource.getConnection());

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		JasperExportManager.exportReportToPdfStream(print, baos);
		byte[] relatorio = baos.toByteArray();

		return relatorio;
	}

}

e na classe view o botão ficaria assim:

exportarRelatorio.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		exportarRelatorio.getStyle().set("margin-top", "37px");
		exportarRelatorio.setWidth("180px");
		exportarRelatorio.addClickListener(event -> {

			FileDownloadWrapper buttonWrapper = new FileDownloadWrapper(
					new StreamResource("RelatorioVenda.pdf", () -> pdf.conversor()));
			buttonWrapper.wrapComponent(exportarRelatorio);
			add(buttonWrapper);
L

Isso.

Funcionou?

R

@Lucas_Camara

haha…não…da erro de assinatura no metodo:

Lambda expression's signature does not match the signature of the functional interface method accept(OutputStream, VaadinSession)

L

Eu que falei errado na verdade. Em vez de retornar o array de bytes, parece que ele pede o stream mesmo. Tente mudar para isso:

FileDownloadWrapper buttonWrapper = new FileDownloadWrapper(
	new StreamResource("RelatorioVenda.pdf", () -> new ByteArrayInputStream(pdf.conversor()))
);
R
java.lang.NoClassDefFoundError: org/vaadin/olli/FileDownloadWrapper
	at br.com.fjsistemas.relatorios.RelatorioVendaView.lambda$5(RelatorioVendaView.java:127) ~[classes/:na]
	at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:205) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.component.ComponentEventBus.handleDomEvent(ComponentEventBus.java:373) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.component.ComponentEventBus.lambda$addDomTrigger$dd1b7957$1(ComponentEventBus.java:264) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.lambda$fireEvent$2(ElementListenerMap.java:443) ~[flow-server-2.6.3.jar:2.6.3]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1507) ~[na:na]
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.fireEvent(ElementListenerMap.java:443) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.rpc.EventRpcHandler.handleNode(EventRpcHandler.java:61) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:66) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:412) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$1(ServerRpcHandler.java:393) ~[flow-server-2.6.3.jar:2.6.3]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1507) ~[na:na]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:393) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:320) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:92) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1570) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:252) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:111) ~[vaadin-spring-12.4.0.jar:na]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:710) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:457) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at java.base/java.lang.Thread.run(Thread.java:830) ~[na:na]
Caused by: java.lang.ClassNotFoundException: org.vaadin.olli.FileDownloadWrapper
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
	at java.base/java.lang.Class.forName(Class.java:416) ~[na:na]
	at org.springframework.boot.devtools.restart.classloader.RestartClassLoader.loadClass(RestartClassLoader.java:145) ~[spring-boot-devtools-2.4.5.jar:2.4.5]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	... 69 common frames omitted
R

O vaadin é falho com Add-On para pdf

R
exportarRelatorio.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		exportarRelatorio.getStyle().set("margin-top", "37px");
		exportarRelatorio.setWidth("180px");
		exportarRelatorio.addClickListener(event -> {

			FileDownloadWrapper buttonWrapper = new FileDownloadWrapper(
					new StreamResource("RelatorioVenda.pdf", () -> {
						try {
							return new ByteArrayInputStream(pdf.conversor());
						} catch (JRException | SQLException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						return null;
					})
				);
			buttonWrapper.wrapComponent(exportarRelatorio);
			add(buttonWrapper);
		});
L

Tem algum outro add-on que vc esteja usando no seu projeto? Ou será que esse problema é para qualquer add-on que vc tente usar?

R

tenho outros adds, estão funcionando normalmente

L

Quando vc adicionou o add-on, será que o maven baixou a dependência corretamente?

R

creio que sim, não vi nenhum tipo de erro ou qualquer coisa neste sentido…este é o segundo add-on para pdf que da o mesmo erro

R

@Lucas_Camara

Mano, resolvi partir para o servlet, e aqui no guj encontrei um exemplo que adaptei para o meu caso, está correta a forma como fiz? Nunca fiz um servlet

package br.com.fjsistemas.embedded;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;

@Component
public class ImprimePDF extends HttpServlet {

	private static final long serialVersionUID = 1L;

	byte[] arquivo = null;

	File file = new File("C:\\Users\\fjd2320\\eclipse-workspace\\Vaadin-Application-Sales-master\\src\\main\\resources\\RelatorioVendas.pdf");

	public void service(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		try {
			arquivo = fileToByte(file);
		} catch (Exception e) {
			e.printStackTrace();
		}

		response.setContentType("application/pdf");
		response.setContentLength(arquivo.length);
		ServletOutputStream ouputStream = response.getOutputStream();
		ouputStream.write(arquivo, 0, arquivo.length);
		ouputStream.flush();
		ouputStream.close();
	}

	public static InputStream byteToInputStream(byte[] bytes) throws Exception {
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		return bais;
	}

	public static byte[] fileToByte(File imagem) throws Exception {
		@SuppressWarnings("resource")
		FileInputStream fis = new FileInputStream(imagem);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buffer = new byte[8192];
		int bytesRead = 0;
		while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
			baos.write(buffer, 0, bytesRead);
		}
		return baos.toByteArray();
	}
}
R

@Lucas_Camara

Mano, bom dia!

Bom é o seguinte…Minha classe conversão, onde converto o jrxml está assim:

package br.com.fjsistemas.relatorios;

import java.io.ByteArrayOutputStream;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.stereotype.Component;

import br.com.fjsistemas.repository.VendaRepository;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;

@Component
public class ConverteJrxmlToPdf {

	@SuppressWarnings("unused")
	private VendaRepository vendaRepository;

	private DataSource dataSource;

	public ConverteJrxmlToPdf(VendaRepository vendaRepository, DataSource dataSource) {
		this.vendaRepository = vendaRepository;
		this.dataSource = dataSource;
	}

	public byte[] conversor() throws JRException, SQLException {

		JasperReport document = JasperCompileManager.compileReport(
				"C:\\Users\\fjd2320\\eclipse-workspace\\fjsistemas-vendas-vaadin\\src\\main\\resources\\RelatorioVendas.jrxml");

		JasperPrint print = JasperFillManager.fillReport(document, null, dataSource.getConnection());

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		JasperExportManager.exportReportToPdfStream(print, baos);
		byte[] relatorio = baos.toByteArray();

		return relatorio;
	}

}

Na minha classe view tenho o botão onde forneço o Download para o usuario, o botão está assim:

exportarRelatorio.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		exportarRelatorio.getStyle().set("margin-top", "37px");
		exportarRelatorio.setWidth("180px");
		exportarRelatorio.addClickListener(event -> {

			FileDownloadWrapper buttonWrapper = new FileDownloadWrapper(
					new StreamResource("RelatorioVenda.pdf", () -> {
						try {
							return new ByteArrayInputStream(pdf.conversor());
						} catch (JRException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (SQLException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						return null;
					})
				);
			buttonWrapper.wrapComponent(exportarRelatorio);
			add(buttonWrapper);
		});

Veja o que está acontecendo:

Esta imagem é no momento em que a aplicação se abre(não houve nenhuma ação por parte do usuario ainda)

Quando dou 1 click sobre o botão exportar relatorio veja o que acontece:

o botão veio parar la embaixo da grid…mas continuando…vou clicar mais uma vez no mesmo botão:

o Download é chamado porem da um erro no download, não sei se vc consegue ver, mas está escrito: Não foi possivel baixar, problema no servidor

e gerou este stack:

java.lang.NullPointerException: null
	at com.vaadin.flow.server.StreamResource$Pipe.read(StreamResource.java:104) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.StreamResource$Pipe.copy(StreamResource.java:94) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.StreamResource$Pipe.accept(StreamResource.java:77) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.StreamResourceHandler.handleRequest(StreamResourceHandler.java:89) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.StreamRequestHandler.handleRequest(StreamRequestHandler.java:106) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1570) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:252) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:111) ~[vaadin-spring-12.4.0.jar:na]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:710) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:457) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at java.base/java.lang.Thread.run(Thread.java:830) ~[na:na]

2021-06-24 09:00:26.656  WARN 8236 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class java.util.LinkedHashMap] with preset Content-Type 'application/pdf']
L

Opa, então, na verdade, vc criou um botão que, quando acionado, adiciona outro botão na tela. Pelo que entendi, esse FileDownloadWrapper será renderizado como um botão.

Tente assim:

exportarRelatorio.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
exportarRelatorio.getStyle().set("margin-top", "37px");
exportarRelatorio.setWidth("180px");

FileDownloadWrapper buttonWrapper = new FileDownloadWrapper(
	new StreamResource("RelatorioVenda.pdf", () -> {
		try {
			return new ByteArrayInputStream(pdf.conversor());
		} catch (JRException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	})
);

buttonWrapper.wrapComponent(exportarRelatorio);
add(buttonWrapper);

acho que não precisa adicionar o botão “exportarRelatorio” na tela

R

@Lucas_Camara

com este ultimo código que vc passou o botão permaneceu em seu lugar, não criou outro botão, porém agora, quando eu clico no botão para gerar o Download, nenhuma ação ocorre, consequentemente não acorre erros de execução

É como se tivesse um botão na tela, sem função lógica

L

Veja se apareceu algo no console do navegador.

Não aparece nenhum erro no console do navegador?

Tente rodar em modo debug e colocar o breakpoint no método que gera o relatório (o que retorna os bytes) para ver se o método está sendo executado pelo menos.

L

Depois, tente deixar o FileDownloadWrapper assim:

FileDownloadWrapper buttonWrapper = new FileDownloadWrapper("RelatorioVenda.pdf", () -> {
	try {
		return new ByteArrayInputStream(pdf.conversor());
	} catch (JRException e) {
		e.printStackTrace();
	} catch (SQLException e) {
		e.printStackTrace();
	}

	return null;
});
R

@Lucas_Camara

Mano…o botão está certo, está no devido lugar e o download está sendo acionado…mas ele ainda está dando a msg Não foi possivel baixar, problema no servidor

e ainda está dando o mesmo stack:

java.lang.NullPointerException: null
	at com.vaadin.flow.server.StreamResource$Pipe.read(StreamResource.java:104) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.StreamResource$Pipe.copy(StreamResource.java:94) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.StreamResource$Pipe.accept(StreamResource.java:77) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.StreamResourceHandler.handleRequest(StreamResourceHandler.java:89) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.communication.StreamRequestHandler.handleRequest(StreamRequestHandler.java:106) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1570) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:252) ~[flow-server-2.6.3.jar:2.6.3]
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:111) ~[vaadin-spring-12.4.0.jar:na]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:710) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:457) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.6.jar:5.3.6]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.45.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.6.jar:5.3.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.6.jar:5.3.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.45.jar:9.0.45]
	at java.base/java.lang.Thread.run(Thread.java:830) ~[na:na]

2021-06-24 10:22:24.433  WARN 8236 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class java.util.LinkedHashMap] with preset Content-Type 'application/pdf']
L

Está parecendo que o método pdf.conversor() está retornando null. Veja no debug se o método conversor está criando o array de bytes corretamente.

R

linha 133 está o break @Lucas_Camara

L

E o que o pdf.conversor() está retornando?

Em modo debug, o eclipse permite vc selecionar o trecho de código e inspecionar para ver qual é o resultado da execução (ao clicar com o botão direito do mouse sobre o trecho selecionado, deve aparecer uma opção inspect ou algo parecido).

R

L

Ah mano, o método conversor que está pipocando erro. Vc deve colocar o breakpoint no método conversor (dentro dele) e ver o que está acontecendo. Pense assim, o NullPointerException é consequência de outro erro (que é a causa do problema).

R

em qual linha exatamente?

L

Coloca na primeira e vai executando linha a linha, até vc descobrir qual linha está estourando o erro.

L
Solucao aceita

Ah, mas nesse ultimo print, já apareceu um erro de FileNotFoundException. O sistema não deve ter encontrado o jrxml nesse caminho que vc colocou nessa string gigante ai.

Já adianto que essa forma está errada, a forma mais correta é carregar do classpath assim:

InputStream reportJrxml = this.getClass().getResourceAsStream("RelatorioVendas.jrxml"); // se não der, tente colocar uma barra no começo: "/RelatorioVendas.jrxml"
JasperReport document = JasperCompileManager.fillReport(reportJrxml);
R

esse JasperDocument não existe…diz que tenho que criar esta classe

L

Opa, digitei errado, é JasperReport mesmo (só copiei seu código que já estava, incluíndo a parte do InputStream).

R

mas posso trocar por isso, certo?

R

MANOOO DEU CERTO…pra variar vc é o cara!!! Mais uma vez, muito obrigado por sua ajuda, apenas tire uma duvida…o que seria este classpath?

L

O classpath é onde todo o código compilado e os resources ficam depois que o projeto é compilado.

Esse seu projeto tem uma configuração que diz que todo código que está em src/main/java e todo arquivo em src/main/resources devem ser incluídos no classpath (assim como as dependências).

Como seu projeto é maven, ele que já deixa isso organizado para vc

Com isso, qdo o projeto for executado, a jvm irá saber onde buscar o código que deverá ser executado e os recursos que serão utilizados (os recursos são arquivos de propriedades, imagens, jrxmls, etc.)

Quando acontece algum ClassNotFoundException, significa que é alguma classe que o sistema tentou executar e não foi encontrado no classpath.

R

agora entendi…mano do céu, muito obg por sua ajudar(como sempre) aprendendo muito com vc…mais uma vez, muito obrigado, grato por tudo!!!

L

Massa. Olha, depois que vc terminar esse sistema, recomendo que vc crie um sisteminha (nem precisa ser grande, pode ser apenas uma tela simples) apenas usando servlets, para vc entender esse fluxo http que acontece entre a página aberta no navegador e o servidor.

Isso vai clarear muitas coisas que vc estava com dúvida nesse projeto usando o vaadin.

R

blz mano. farei isso…muito obg!!!

Criado 21 de junho de 2021
Ultima resposta 24 de jun. de 2021
Respostas 47
Participantes 3