Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

di il
8 risposte

Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

Ciao ragazzi, ho un problema con un errore in Eclipse. L'errore è il seguente: org.apache.jasper.JasperException: Unable to compile class for JSP.

Il codice è il seguente:

pom.xml
<dependencies>
   <!--Spring framework related jars-->
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.2.10.RELEASE</version>
   </dependency>
   <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
   </dependency>
   <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
   </dependency>
</dependencies>
PhoneService.java
package com.kswaughs.web.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.kswaughs.web.beans.Phone;

@Service
public class PhoneService {
    
    public List<Phone> getPhoneslist() {
        
        List<Phone> phonesList = new ArrayList<Phone>();
        
        phonesList.add(buildPhone("1", "Samsung Galaxy Y"));
        phonesList.add(buildPhone("2", "Nokia Lumia"));
        phonesList.add(buildPhone("3", "Moto G"));
        phonesList.add(buildPhone("4", "Lenovo A 7000 white"));
        phonesList.add(buildPhone("5", "Sony XPeria"));
        
        return phonesList;
    }
    
    private Phone buildPhone(String id, String name) {
        
        Phone phone = new Phone(id, name);
        return phone;
    }
    
}
Phone.java
package com.kswaughs.web.beans;

public class Phone {
    
    private String id;
    
    private String name;
    
    public Phone() {
        
    }
    
    public Phone(String id, String name) {
        this.id = id;
        this.name = name;
    }
    
    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

}
PhoneController.java
package com.kswaughs.web.controller;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.support.PagedListHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.kswaughs.web.beans.Phone;
import com.kswaughs.web.service.PhoneService;

@Controller
@RequestMapping(value = "/phones")
public class PhoneController {
    
    @Autowired
    PhoneService phoneSvc;
    
    @RequestMapping(value = {"/all/{type}","/all"}, method = RequestMethod.GET)
    public ModelAndView all(
            @PathVariable Map<String, String> pathVariablesMap, 
            HttpServletRequest req) {
        
        PagedListHolder<Phone> productList = null;
        
        String type = pathVariablesMap.get("type");
        
        if(null == type) {
            // First Request, Return first set of list
            List<Phone> phonesList = phoneSvc.getPhoneslist();
            
            productList = new PagedListHolder<Phone>();
            productList.setSource(phonesList);
            productList.setPageSize(2);
            
            req.getSession().setAttribute("phonesList",  productList);
        
            printPageDetails(productList);
            
        } else if("next".equals(type)) {
            // Return next set of list
            productList = (PagedListHolder<Phone>) req.getSession()
                                .getAttribute("phonesList");
            
            productList.nextPage();
            
            printPageDetails(productList);
            
        } else if("prev".equals(type)) {
            // Return previous set of list
            productList = (PagedListHolder<Phone>) req.getSession()
                                .getAttribute("phonesList");
            
            productList.previousPage();
            
            printPageDetails(productList);
            
        } else {
            // Return specific index set of list
            System.out.println("type:" + type);
            
            productList = (PagedListHolder<Phone>) req.getSession()
                                .getAttribute("phonesList");
            
            int pageNum = Integer.parseInt(type);
            
            productList.setPage(pageNum);
            
            printPageDetails(productList);
        }
                    
        ModelAndView mv = new ModelAndView("index");
        
        return  mv;
    }

    private void printPageDetails(PagedListHolder productList) {
        
        System.out.println("curent page - productList.getPage() :"
                + productList.getPage());
        
        System.out.println("Total Num of pages - productList.getPageCount :"
                + productList.getPageCount());
        
        System.out.println("is First page - productList.isFirstPage :"
                + productList.isFirstPage());
        
        System.out.println("is Last page - productList.isLastPage :"
                + productList.isLastPage());
    }
}
SpringWebConfig
package com.kswaughs.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@EnableWebMvc 
@Configuration
@ComponentScan({ "com.kswaughs.web" })
public class SpringWebConfig extends WebMvcConfigurerAdapter {
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }
    
    @Bean
    public ViewResolver jspViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/jsps/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }        
}
SpringWebInitializer
package com.kswaughs.servlet;

import org.springframework.web.servlet.support.
    AbstractAnnotationConfigDispatcherServletInitializer;

import com.kswaughs.config.SpringWebConfig;

public class SpringWebInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class[] getServletConfigClasses() {
        return new Class[] { SpringWebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Class[] getRootConfigClasses() {
        return new Class[] {};
    }
    
}
index.jsp
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
    <head>
    </head>
    <body>
    <div>
        <p>Welcome to Phones Store</p>
        <p>List of the Phones in our store.</p>
    </div>
    <div>
        <c:set var="pageListHolder" value="${phonesList}" scope="session" />
        <table cellspacing="0">
            <thead><tr><th>ID</th><th>Name</th></tr></thead>
            <tbody>
            <c:forEach var="ph" items="${pageListHolder.pageList}">
                <tr><td>${ph.id}</td><td>${ph.name}</td></tr>
            </c:forEach>
            </tbody>
        </table>
    </div>
    <div>
    <span style="float:left;">
    <c:choose>
        <c:when test="${pageListHolder.firstPage}">Prev</c:when>
        <c:otherwise><a href="${pageurl}/prev">Prev</a></c:otherwise>
    </c:choose>
    </span>
    <span>
    <c:forEach begin="0" end="${pageListHolder.pageCount-1}" varStatus="loop">
    &nbsp;&nbsp;
    <c:choose>
        <c:when test="${loop.index == pageListHolder.page}">${loop.index+1}</c:when>
        <c:otherwise><a href="${pageurl}/${loop.index}">${loop.index+1}</a></c:otherwise>
    </c:choose>
    &nbsp;&nbsp;
    </c:forEach>
    </span>
    <span>
    <c:choose>
        <c:when test="${pageListHolder.lastPage}">Next</c:when>
        <c:otherwise><a href="${pageurl}/next">Next</a></c:otherwise>
    </c:choose>
    </span>
    </div>
    </body>
</html>

8 Risposte

  • Re: Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

    alex989 ha scritto:


    L'errore è il seguente: org.apache.jasper.JasperException: Unable to compile class for JSP.
    Se hai uno stacktrace, verifica meglio la causa più "interna" di questa JasperException. E' molto probabile che ci sia ....
  • Re: Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

    andbin ha scritto:


    alex989 ha scritto:


    L'errore è il seguente: org.apache.jasper.JasperException: Unable to compile class for JSP.
    Se hai uno stacktrace, verifica meglio la causa più "interna" di questa JasperException. E' molto probabile che ci sia ....
    Intendi questo??
    Root Cause
    java.lang.NumberFormatException: For input string: "${pageListHolder.pageCount-1}"
    java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
    java.base/java.lang.Integer.parseInt(Integer.java:644)
    java.base/java.lang.Integer.valueOf(Integer.java:989)
    org.apache.jasper.compiler.JspUtil.coerceToInt(JspUtil.java:561)
    org.apache.jasper.compiler.Generator$GenerateVisitor.convertString(Generator.java:3327)
    org.apache.jasper.compiler.Generator$GenerateVisitor.evaluateAttribute(Generator.java:3130)
    org.apache.jasper.compiler.Generator$GenerateVisitor.generateSetters(Generator.java:3235)
    org.apache.jasper.compiler.Generator$GenerateVisitor.generateCustomStart(Generator.java:2421)
    org.apache.jasper.compiler.Generator$GenerateVisitor.visit(Generator.java:1911)
    org.apache.jasper.compiler.Node$CustomTag.accept(Node.java:1544)
    org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2389)
    org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2441)
    org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2447)
    org.apache.jasper.compiler.Node$Root.accept(Node.java:470)
    org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2389)
    org.apache.jasper.compiler.Generator.generate(Generator.java:3676)
    org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:257)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:386)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:362)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:346)
    org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:605)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:400)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
    org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
    org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1201)
    org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:986)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:933)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
  • Re: Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

    alex989 ha scritto:


    Intendi questo??
    Root Cause
    java.lang.NumberFormatException: For input string: "${pageListHolder.pageCount-1}"
    Esattamente!

    E la questione è molto semplice: "${pageListHolder.pageCount-1}" lo sta prendendo come stringa pura e non come "espressione" del EL (expression language) da valutare.

    Devi chiarire quale è la versione di specifica Servlet che è dichiarata nel web.xml (è all'inizio). E' quella che conta anche.
  • Re: Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

    andbin ha scritto:


    alex989 ha scritto:


    Intendi questo??
    Root Cause
    java.lang.NumberFormatException: For input string: "${pageListHolder.pageCount-1}"
    Esattamente!

    E la questione è molto semplice: "${pageListHolder.pageCount-1}" lo sta prendendo come stringa pura e non come "espressione" del EL (expression language) da valutare.

    Devi chiarire quale è la versione di specifica Servlet che è dichiarata nel web.xml (è all'inizio). E' quella che conta anche.
    Capito, cosa dovrei fare di preciso nel codice? E' la prima volta che faccio questo.
  • Re: Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

    alex989 ha scritto:


    cosa dovrei fare di preciso nel codice? E' la prima volta che faccio questo.
    Devi dirmi prima come è la dichiarazione iniziale nel web.xml, se hai una versione fino alla 2.3 (che usa il DTD) o una versione dalla 2.4 in poi (che usa gli XSD).
  • Re: Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

    andbin ha scritto:


    alex989 ha scritto:


    cosa dovrei fare di preciso nel codice? E' la prima volta che faccio questo.
    Devi dirmi prima come è la dichiarazione iniziale nel web.xml, se hai una versione fino alla 2.3 (che usa il DTD) o una versione dalla 2.4 in poi (che usa gli XSD).
    Mi dice web-app_2_3.dtd, quindi usa il DTD
  • Re: Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

    alex989 ha scritto:


    Mi dice web-app_2_3.dtd, quindi usa il DTD
    Infatti è quello il problema. Nota innanzitutto che c'è una piccola incoerenza (nulla di grave), perché la specifica delle Servlet nel web.xml è 2.3 mentre hai la dependency servlet-api versione 2.5 .

    Comunque, ecco una breve descrizione della questione. In JSTL 1.0 (e comunque fino alle Servlet 2.3/JSP 1.2) l'Expression Language era gestito dai custom tag. Cioè era ciascun tag tipo <c:out>, <c:forEach> ecc... che doveva avere internamente il "motore" di valutazione delle espressioni. Ai tag si passava una espressione in stringa tipo end="${ blabla }" e il tag parsava e interpretava autonomamente l'espressione.

    Con l'avvento delle Servlet 2.4/JSP 2.0 le cose sono cambiate. Ora è il servlet container che ha il motore di valutazione delle espressioni, perché il Expression Language fa ora parte delle specifiche JSP. Infatti le espressioni EL si possono usare ovunque in una JSP, pure fuori dai custom tag, ad esempio nella parte "template" HTML:

    <span>${persona.annoNascita}</span>

    Questa nuova funzionalità è stata sfruttata da JSTL 1.1+ per cui un tag come il <c:forEach> ha l'attributo end che riceve direttamente un int, non una stringa. Perché si aspetta che ci sia qualcuno esternamente che valuta una espressione EL come valore int e lo assegna all'attributo.

    Nel jar di JSTL 1.2 ci sono comunque vari file .tld, compresi quelli per JSTL 1.0 per mantenere compatibilità all'indietro. Per distinguere tra i tag di JSTL 1.0 e quelli di JSTL 1.1+ è stato cambiato il URI. Tu hai usato:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

    Questo è il nuovo uri per JSTL 1.1+ e i suoi tag si aspettano che il EL sia valutato esternamente. MA la tua webapp dichiara le servlet 2.3, quindi anche se la fai girare su un servlet container che supporta Servlet 2.4 o superiore, le nuove feature NON vengono attivate. Ecco perché non sta valutando il EL e perché una stringa come "${pageListHolder.pageCount-1}" tenta di parsarla banalmente come numero (end si aspetta un int).

    La cosa più semplice da fare sarebbe aggiornare il web.xml per dichiarare la conformità della webapp alle specifiche Servlet 2.4 (o più). La dichiarazione iniziale va proprio cambiata, NON basta solo mettere 2.4 ! (perché usa gli XSD)

    Purtroppo non so perché hai messo 2.3. Hai preso il primo web.xml di esempio che ti è capitato per caso? O c'è un motivo ben preciso?
  • Re: Errore Eclipse: Unable to compile class for JSP - JasperException Spring MVC

    andbin ha scritto:


    alex989 ha scritto:


    Mi dice web-app_2_3.dtd, quindi usa il DTD
    Infatti è quello il problema. Nota innanzitutto che c'è una piccola incoerenza (nulla di grave), perché la specifica delle Servlet nel web.xml è 2.3 mentre hai la dependency servlet-api versione 2.5 .

    Comunque, ecco una breve descrizione della questione. In JSTL 1.0 (e comunque fino alle Servlet 2.3/JSP 1.2) l'Expression Language era gestito dai custom tag. Cioè era ciascun tag tipo <c:out>, <c:forEach> ecc... che doveva avere internamente il "motore" di valutazione delle espressioni. Ai tag si passava una espressione in stringa tipo end="${ blabla }" e il tag parsava e interpretava autonomamente l'espressione.

    Con l'avvento delle Servlet 2.4/JSP 2.0 le cose sono cambiate. Ora è il servlet container che ha il motore di valutazione delle espressioni, perché il Expression Language fa ora parte delle specifiche JSP. Infatti le espressioni EL si possono usare ovunque in una JSP, pure fuori dai custom tag, ad esempio nella parte "template" HTML:

    <span>${persona.annoNascita}</span>

    Questa nuova funzionalità è stata sfruttata da JSTL 1.1+ per cui un tag come il <c:forEach> ha l'attributo end che riceve direttamente un int, non una stringa. Perché si aspetta che ci sia qualcuno esternamente che valuta una espressione EL come valore int e lo assegna all'attributo.

    Nel jar di JSTL 1.2 ci sono comunque vari file .tld, compresi quelli per JSTL 1.0 per mantenere compatibilità all'indietro. Per distinguere tra i tag di JSTL 1.0 e quelli di JSTL 1.1+ è stato cambiato il URI. Tu hai usato:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

    Questo è il nuovo uri per JSTL 1.1+ e i suoi tag si aspettano che il EL sia valutato esternamente. MA la tua webapp dichiara le servlet 2.3, quindi anche se la fai girare su un servlet container che supporta Servlet 2.4 o superiore, le nuove feature NON vengono attivate. Ecco perché non sta valutando il EL e perché una stringa come "${pageListHolder.pageCount-1}" tenta di parsarla banalmente come numero (end si aspetta un int).

    La cosa più semplice da fare sarebbe aggiornare il web.xml per dichiarare la conformità della webapp alle specifiche Servlet 2.4 (o più). La dichiarazione iniziale va proprio cambiata, NON basta solo mettere 2.4 ! (perché usa gli XSD)

    Purtroppo non so perché hai messo 2.3. Hai preso il primo web.xml di esempio che ti è capitato per caso? O c'è un motivo ben preciso?
    Perfetto, ho capito. Ti ringrazio infinitamente.
    Non l'ho messo io quel 2.3; nel momento che creo il progetto quel valore viene messo in web.xml in modo automatico.
    Grazie ancora, sei stato chiarissimo.
Devi accedere o registrarti per scrivere nel forum
8 risposte