org.apache.jasper.JasperException: The function test must be used with a prefix when a default namespace is not specified

I'm using the following things for my project: Spring 3.0.1 + Apache Tiles 2.2.1 + Glassfish 2.1. What I'm trying to do is to call some method in a jsp-page and pass some parameters to it. For example, I have a bean:

@Component
@Scope(value = "singleton")
public class TestBean {
    public void test(String param){
        System.out.println("param = " + param);
    }
}

and I have a jsp-page:

<%@page contentType="text/html; charset=utf-8"%>
${testBean.test("hello")}

This code gives me an exception like:

org.apache.jasper.JasperException: The function test must be used with a prefix when a default namespace is not specified

If I call some method without passing parameters to it - everything is OK.

I have tried to put jboss-el.jar in my WEB-INF/lib and put required parameters in web.xml (as explained here), but with no effect.

I'm restricted to the set of technologies that I have listed above, so I can't add anything or, for example, can't change the version of my app-server.

With all these conditions, is there a solution for my problem?


org.apache.jasper.JasperException: The function test must be used with a prefix when a default namespace is not specified

This indicates that the environment doesn't support the new EL 2.2 feature of invoking bean methods with arguments. The outdated environment is trying to interpret the expression as an EL function which has the notation namespace:functionName() (like as JSTL functions). The exception is merely complaining that namespace: part cannot be found in order to identify the EL function. But it is wrong, after all.

You need to ensure that the following conditions are met in order to be able to invoke bean methods with arguments in EL:

  1. The target container must support EL 2.2. All Servlet 3.0 compatible containers do, as EL 2.2 is part of Java EE 6 which in turn also covers Servlet 3.0. Examples of Servlet 3.0 containers are Tomcat 7.x, Glassfish 3.x and JBoss AS 6.x/7.x.

  2. The /WEB-INF/web.xml file is declared conform Servlet 3.0 specification (and thus not older, such as 2.5).

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app 
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        version="3.0">
    
        <!-- Config here. -->
    
    </web-app>
    

    Otherwise your container will run in a fallback modus matching the version matching in web.xml root declaration, hereby losing all the new Servlet 3.0 and EL 2.2 awesomeness.

  3. The webapp's /WEB-INF/lib does not contain container-specific EL implementation libraries originating from a container of an older make/version, such as el-api.jar and/or el-impl.jar originating from Tomcat 6.x or so.

Your concrete problem is caused by using a non-Servlet 3.0 compatible container: the old Glassfish 2.x.

Upgrade to Glassfish 3.x or look for alternate ways. The JBoss EL approach works only for JSF, not for Spring nor "plain JSP".


Please use tomcat 7 if you are using el 2.2 and servlet 3.0 We faced the same and got fixed with above version


Because I have to work on Servlet 2.5, I made this hack:

JSP:

${testBean.test["hello"]}

Bean:

private Map test;

public Map getTest() {
    if (test == null) {
        test = new Map() {
            @Override
            public Object get(Object key) {
                System.out.println("param = " + key);
                return null;
            }

            @Override
            public int size() {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public boolean isEmpty() {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public boolean containsKey(Object key) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public boolean containsValue(Object value) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public Object put(Object key, Object value) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public Object remove(Object key) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void putAll(Map m) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void clear() {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public Set keySet() {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public Collection values() {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public Set entrySet() {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

        };
    }
    return test;
}