View | Details | Raw Unified | Return to bug 62453
Collapse All | Expand All

(-)java/javax/el/ImportHandler.java (-6 / +257 lines)
Lines 19-27 Link Here
19
import java.lang.reflect.Field;
19
import java.lang.reflect.Field;
20
import java.lang.reflect.Method;
20
import java.lang.reflect.Method;
21
import java.lang.reflect.Modifier;
21
import java.lang.reflect.Modifier;
22
import java.util.ArrayList;
22
import java.util.Collections;
23
import java.util.List;
23
import java.util.HashMap;
24
import java.util.HashSet;
24
import java.util.Map;
25
import java.util.Map;
26
import java.util.Set;
25
import java.util.concurrent.ConcurrentHashMap;
27
import java.util.concurrent.ConcurrentHashMap;
26
28
27
/**
29
/**
Lines 29-35 Link Here
29
 */
31
 */
30
public class ImportHandler {
32
public class ImportHandler {
31
33
32
    private List<String> packageNames = new ArrayList<>();
34
    private static final Map<String,Set<String>> standardPackages = new HashMap<>();
35
36
    static {
37
        // Servlet 4.0
38
        Set<String> servletClassNames = new HashSet<>();
39
        // Interfaces
40
        servletClassNames.add("AsyncContext");
41
        servletClassNames.add("AsyncListener");
42
        servletClassNames.add("Filter");
43
        servletClassNames.add("FilterChain");
44
        servletClassNames.add("FilterConfig");
45
        servletClassNames.add("FilterRegistration");
46
        servletClassNames.add("FilterRegistration.Dynamic");
47
        servletClassNames.add("ReadListener");
48
        servletClassNames.add("Registration");
49
        servletClassNames.add("Registration.Dynamic");
50
        servletClassNames.add("RequestDispatcher");
51
        servletClassNames.add("Servlet");
52
        servletClassNames.add("ServletConfig");
53
        servletClassNames.add("ServletContainerInitializer");
54
        servletClassNames.add("ServletContext");
55
        servletClassNames.add("ServletContextAttributeListener");
56
        servletClassNames.add("ServletContextListener");
57
        servletClassNames.add("ServletRegistration");
58
        servletClassNames.add("ServletRegistration.Dynamic");
59
        servletClassNames.add("ServletRequest");
60
        servletClassNames.add("ServletRequestAttributeListener");
61
        servletClassNames.add("ServletRequestListener");
62
        servletClassNames.add("ServletResponse");
63
        servletClassNames.add("SessionCookieConfig");
64
        servletClassNames.add("SingleThreadModel");
65
        servletClassNames.add("WriteListener");
66
        // Classes
67
        servletClassNames.add("AsyncEvent");
68
        servletClassNames.add("GenericFilter");
69
        servletClassNames.add("GenericServlet");
70
        servletClassNames.add("HttpConstraintElement");
71
        servletClassNames.add("HttpMethodConstraintElement");
72
        servletClassNames.add("MultipartConfigElement");
73
        servletClassNames.add("ServletContextAttributeEvent");
74
        servletClassNames.add("ServletContextEvent");
75
        servletClassNames.add("ServletInputStream");
76
        servletClassNames.add("ServletOutputStream");
77
        servletClassNames.add("ServletRequestAttributeEvent");
78
        servletClassNames.add("ServletRequestEvent");
79
        servletClassNames.add("ServletRequestWrapper");
80
        servletClassNames.add("ServletResponseWrapper");
81
        servletClassNames.add("ServletSecurityElement");
82
        // Enums
83
        servletClassNames.add("DispatcherType");
84
        servletClassNames.add("SessionTrackingMode");
85
        // Exceptions
86
        servletClassNames.add("ServletException");
87
        servletClassNames.add("UnavailableException");
88
        standardPackages.put("javax.servlet", servletClassNames);
89
90
        // Servlet 4.0
91
        Set<String> servletHttpClassNames = new HashSet<>();
92
        // Interfaces
93
        servletHttpClassNames.add("HttpServletMapping");
94
        servletHttpClassNames.add("HttpServletRequest");
95
        servletHttpClassNames.add("HttpServletResponse");
96
        servletHttpClassNames.add("HttpSession");
97
        servletHttpClassNames.add("HttpSessionActivationListener");
98
        servletHttpClassNames.add("HttpSessionAttributeListener");
99
        servletHttpClassNames.add("HttpSessionBindingListener");
100
        servletHttpClassNames.add("HttpSessionContext");
101
        servletHttpClassNames.add("HttpSessionIdListener");
102
        servletHttpClassNames.add("HttpSessionListener");
103
        servletHttpClassNames.add("HttpUpgradeHandler");
104
        servletHttpClassNames.add("Part");
105
        servletHttpClassNames.add("PushBuilder");
106
        servletHttpClassNames.add("WebConnection");
107
        // Classes
108
        servletHttpClassNames.add("Cookie");
109
        servletHttpClassNames.add("HttpFilter");
110
        servletHttpClassNames.add("HttpServlet");
111
        servletHttpClassNames.add("HttpServletRequestWrapper");
112
        servletHttpClassNames.add("HttpServletResponseWrapper");
113
        servletHttpClassNames.add("HttpSessionBindingEvent");
114
        servletHttpClassNames.add("HttpSessionEvent");
115
        servletHttpClassNames.add("HttpUtils");
116
        // Enums
117
        servletHttpClassNames.add("MappingMatch");
118
        standardPackages.put("javax.servlet.http", servletHttpClassNames);
119
120
        // JSP 2.3
121
        Set<String> servletJspClassNames = new HashSet<>();
122
        //Interfaces
123
        servletJspClassNames.add("HttpJspPage");
124
        servletJspClassNames.add("JspApplicationContext");
125
        servletJspClassNames.add("JspPage");
126
        // Classes
127
        servletJspClassNames.add("ErrorData");
128
        servletJspClassNames.add("JspContext");
129
        servletJspClassNames.add("JspEngineInfo");
130
        servletJspClassNames.add("JspFactory");
131
        servletJspClassNames.add("JspWriter");
132
        servletJspClassNames.add("PageContext");
133
        servletJspClassNames.add("Exceptions");
134
        servletJspClassNames.add("JspException");
135
        servletJspClassNames.add("JspTagException");
136
        servletJspClassNames.add("SkipPageException");
137
        standardPackages.put("javax.servlet.jsp", servletJspClassNames);
138
139
        Set<String> javaLangClassNames = new HashSet<>();
140
        // Taken from Java 11 EA18 Javadoc
141
        // Interfaces
142
        javaLangClassNames.add("Appendable");
143
        javaLangClassNames.add("AutoCloseable");
144
        javaLangClassNames.add("CharSequence");
145
        javaLangClassNames.add("Cloneable");
146
        javaLangClassNames.add("Comparable");
147
        javaLangClassNames.add("Iterable");
148
        javaLangClassNames.add("ProcessHandle");
149
        javaLangClassNames.add("ProcessHandle.Info");
150
        javaLangClassNames.add("Readable");
151
        javaLangClassNames.add("Runnable");
152
        javaLangClassNames.add("StackWalker.StackFrame");
153
        javaLangClassNames.add("System.Logger");
154
        javaLangClassNames.add("Thread.UncaughtExceptionHandler");
155
        //Classes
156
        javaLangClassNames.add("Boolean");
157
        javaLangClassNames.add("Byte");
158
        javaLangClassNames.add("Character");
159
        javaLangClassNames.add("Character.Subset");
160
        javaLangClassNames.add("Character.UnicodeBlock");
161
        javaLangClassNames.add("Class");
162
        javaLangClassNames.add("ClassLoader");
163
        javaLangClassNames.add("ClassValue");
164
        javaLangClassNames.add("Compiler");
165
        javaLangClassNames.add("Double");
166
        javaLangClassNames.add("Enum");
167
        javaLangClassNames.add("Float");
168
        javaLangClassNames.add("InheritableThreadLocal");
169
        javaLangClassNames.add("Integer");
170
        javaLangClassNames.add("Long");
171
        javaLangClassNames.add("Math");
172
        javaLangClassNames.add("Module");
173
        javaLangClassNames.add("ModuleLayer");
174
        javaLangClassNames.add("ModuleLayer.Controller");
175
        javaLangClassNames.add("Number");
176
        javaLangClassNames.add("Object");
177
        javaLangClassNames.add("Package");
178
        javaLangClassNames.add("Process");
179
        javaLangClassNames.add("ProcessBuilder");
180
        javaLangClassNames.add("ProcessBuilder.Redirect");
181
        javaLangClassNames.add("Runtime");
182
        javaLangClassNames.add("Runtime.Version");
183
        javaLangClassNames.add("RuntimePermission");
184
        javaLangClassNames.add("SecurityManager");
185
        javaLangClassNames.add("Short");
186
        javaLangClassNames.add("StackTraceElement");
187
        javaLangClassNames.add("StackWalker");
188
        javaLangClassNames.add("StrictMath");
189
        javaLangClassNames.add("String");
190
        javaLangClassNames.add("StringBuffer");
191
        javaLangClassNames.add("StringBuilder");
192
        javaLangClassNames.add("System");
193
        javaLangClassNames.add("System.LoggerFinder");
194
        javaLangClassNames.add("Thread");
195
        javaLangClassNames.add("ThreadGroup");
196
        javaLangClassNames.add("ThreadLocal");
197
        javaLangClassNames.add("Throwable");
198
        javaLangClassNames.add("Void");
199
        //Enums
200
        javaLangClassNames.add("Character.UnicodeScript");
201
        javaLangClassNames.add("ProcessBuilder.Redirect.Type");
202
        javaLangClassNames.add("StackWalker.Option");
203
        javaLangClassNames.add("System.Logger.Level");
204
        javaLangClassNames.add("Thread.State");
205
        //Exceptions
206
        javaLangClassNames.add("ArithmeticException");
207
        javaLangClassNames.add("ArrayIndexOutOfBoundsException");
208
        javaLangClassNames.add("ArrayStoreException");
209
        javaLangClassNames.add("ClassCastException");
210
        javaLangClassNames.add("ClassNotFoundException");
211
        javaLangClassNames.add("CloneNotSupportedException");
212
        javaLangClassNames.add("EnumConstantNotPresentException");
213
        javaLangClassNames.add("Exception");
214
        javaLangClassNames.add("IllegalAccessException");
215
        javaLangClassNames.add("IllegalArgumentException");
216
        javaLangClassNames.add("IllegalCallerException");
217
        javaLangClassNames.add("IllegalMonitorStateException");
218
        javaLangClassNames.add("IllegalStateException");
219
        javaLangClassNames.add("IllegalThreadStateException");
220
        javaLangClassNames.add("IndexOutOfBoundsException");
221
        javaLangClassNames.add("InstantiationException");
222
        javaLangClassNames.add("InterruptedException");
223
        javaLangClassNames.add("LayerInstantiationException");
224
        javaLangClassNames.add("NegativeArraySizeException");
225
        javaLangClassNames.add("NoSuchFieldException");
226
        javaLangClassNames.add("NoSuchMethodException");
227
        javaLangClassNames.add("NullPointerException");
228
        javaLangClassNames.add("NumberFormatException");
229
        javaLangClassNames.add("ReflectiveOperationException");
230
        javaLangClassNames.add("RuntimeException");
231
        javaLangClassNames.add("SecurityException");
232
        javaLangClassNames.add("StringIndexOutOfBoundsException");
233
        javaLangClassNames.add("TypeNotPresentException");
234
        javaLangClassNames.add("UnsupportedOperationException");
235
        //Errors
236
        javaLangClassNames.add("AbstractMethodError");
237
        javaLangClassNames.add("AssertionError");
238
        javaLangClassNames.add("BootstrapMethodError");
239
        javaLangClassNames.add("ClassCircularityError");
240
        javaLangClassNames.add("ClassFormatError");
241
        javaLangClassNames.add("Error");
242
        javaLangClassNames.add("ExceptionInInitializerError");
243
        javaLangClassNames.add("IllegalAccessError");
244
        javaLangClassNames.add("IncompatibleClassChangeError");
245
        javaLangClassNames.add("InstantiationError");
246
        javaLangClassNames.add("InternalError");
247
        javaLangClassNames.add("LinkageError");
248
        javaLangClassNames.add("NoClassDefFoundError");
249
        javaLangClassNames.add("NoSuchFieldError");
250
        javaLangClassNames.add("NoSuchMethodError");
251
        javaLangClassNames.add("OutOfMemoryError");
252
        javaLangClassNames.add("StackOverflowError");
253
        javaLangClassNames.add("ThreadDeath");
254
        javaLangClassNames.add("UnknownError");
255
        javaLangClassNames.add("UnsatisfiedLinkError");
256
        javaLangClassNames.add("UnsupportedClassVersionError");
257
        javaLangClassNames.add("VerifyError");
258
        javaLangClassNames.add("VirtualMachineError");
259
        //Annotation Types
260
        javaLangClassNames.add("Deprecated");
261
        javaLangClassNames.add("FunctionalInterface");
262
        javaLangClassNames.add("Override");
263
        javaLangClassNames.add("SafeVarargs");
264
        javaLangClassNames.add("SuppressWarnings");
265
        standardPackages.put("java.lang", javaLangClassNames);
266
267
    }
268
269
    private Map<String,Set<String>> packageNames = new ConcurrentHashMap<>();
33
    private Map<String,String> classNames = new ConcurrentHashMap<>();
270
    private Map<String,String> classNames = new ConcurrentHashMap<>();
34
    private Map<String,Class<?>> clazzes = new ConcurrentHashMap<>();
271
    private Map<String,Class<?>> clazzes = new ConcurrentHashMap<>();
35
    private Map<String,Class<?>> statics = new ConcurrentHashMap<>();
272
    private Map<String,Class<?>> statics = new ConcurrentHashMap<>();
Lines 127-133 Link Here
127
        // a) for sake of performance when used in JSPs (BZ 57142),
364
        // a) for sake of performance when used in JSPs (BZ 57142),
128
        // b) java.lang.Package.getPackage(name) is not reliable (BZ 57574),
365
        // b) java.lang.Package.getPackage(name) is not reliable (BZ 57574),
129
        // c) such check is not required by specification.
366
        // c) such check is not required by specification.
130
        packageNames.add(name);
367
        Set<String> preloaded = standardPackages.get(name);
368
        if (preloaded == null) {
369
            packageNames.put(name, Collections.emptySet());
370
        } else {
371
            packageNames.put(name, preloaded);
372
        }
131
    }
373
    }
132
374
133
375
Lines 159-166 Link Here
159
401
160
        // Search the package imports - note there may be multiple matches
402
        // Search the package imports - note there may be multiple matches
161
        // (which correctly triggers an error)
403
        // (which correctly triggers an error)
162
        for (String p : packageNames) {
404
        for (Map.Entry<String,Set<String>> entry : packageNames.entrySet()) {
163
            className = p + '.' + name;
405
            if (!entry.getValue().isEmpty()) {
406
                // Standard package where we know all the class names
407
                if (!entry.getValue().contains(name)) {
408
                    // Requested name isn't in the list so it isn't in this
409
                    // package so move on to next package. This allows the
410
                    // class loader look-up to be skipped.
411
                    continue;
412
                }
413
            }
414
            className = entry.getKey() + '.' + name;
164
            Class<?> clazz = findClass(className, false);
415
            Class<?> clazz = findClass(className, false);
165
            if (clazz != null) {
416
            if (clazz != null) {
166
                if (result != null) {
417
                if (result != null) {
(-)test/javax/el/TestImportHandlerStandardPackages.java (+156 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
package javax.el;
18
19
import java.io.File;
20
import java.lang.reflect.Field;
21
import java.lang.reflect.Modifier;
22
import java.net.URL;
23
import java.util.Enumeration;
24
import java.util.Map;
25
import java.util.Optional;
26
import java.util.Set;
27
import java.util.stream.Stream;
28
29
import org.junit.Assert;
30
import org.junit.Test;
31
32
import org.apache.tomcat.util.compat.JreCompat;
33
34
public class TestImportHandlerStandardPackages {
35
36
    @Test
37
    public void testClassListsAreComplete() throws Exception {
38
        // Use reflection to get hold of the internal Map
39
        Class<?> clazz = ImportHandler.class;
40
        Field f = clazz.getDeclaredField("standardPackages");
41
        f.setAccessible(true);
42
        Object obj = f.get(null);
43
44
        Assert.assertTrue("Not Map", obj instanceof Map);
45
46
        @SuppressWarnings("unchecked")
47
        Map<String,Set<String>> standardPackageName = (Map<String, Set<String>>) obj;
48
49
        for (Map.Entry<String,Set<String>> entry : standardPackageName.entrySet()) {
50
            checkPackageClassList(entry.getKey(), entry.getValue());
51
        }
52
    }
53
54
55
    private void checkPackageClassList(String packageName, Set<String> classNames) throws Exception {
56
57
        if ("java.lang".equals(packageName)) {
58
            // The code below is designed to run on Java 9 so skip this check
59
            // if running on Java 8. The test has previously been run with Java
60
            // 9 (and later) so it is not necessary that this is executed on
61
            // every test run. The intention is that it will catch new classes
62
            // when the tests are run on a newer JRE.
63
            // The latest version of the JRE where this test is known to pass is
64
            // Java 11, Early Access 15
65
            if (!JreCompat.isJre9Available()) {
66
                return;
67
            }
68
            getJavaBaseClasses().filter(c -> (c.startsWith("java/lang/")))
69
                    .filter(c -> c.lastIndexOf('/') == 9)             // Exclude sub-packages
70
                    .filter(c -> c.endsWith(".class"))                // Exclude non-class resources
71
                    .map(c -> c.substring(10, c.length() - 6))        // Extract class name
72
                    .map(c-> {
73
                        try {
74
                            return Class.forName("java.lang." + c);   // Get the class object
75
                        } catch (ClassNotFoundException e) {
76
                            throw new RuntimeException();
77
                        }
78
                    })
79
                    .filter(c -> Modifier.isPublic(c.getModifiers())) // Exclude non-public classes
80
                    .map(c -> c.getName().substring(10))              // Back to the class name
81
                    .map(c -> c.replace('$',  '.'))
82
                    .filter(c -> !classNames.contains(c))             // Skip classes already listed
83
                    .filter(c -> !c.startsWith("FdLibm."))            // Skip public inner class
84
                    .filter(c -> !c.startsWith("LiveStackFrame."))    // Skip public inner class
85
                    .filter(c -> !c.startsWith("WeakPairMap."))       // Skip public inner class
86
                    .forEach(c -> Assert.fail("java.lang." + c));     // Should have in list
87
        } else {
88
            // When this test runs, the class loader will be loading resources
89
            // from a directory for each of these packages.
90
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
91
92
            String path = packageName.replace('.', '/');
93
            Enumeration<URL> resources = cl.getResources(path);
94
            while (resources.hasMoreElements()) {
95
                URL resource = resources.nextElement();
96
                File dir = new File(resource.toURI());
97
                String[] files = dir.list();
98
                for (String file : files) {
99
                    if (!file.endsWith(".class")) {
100
                        // Skip non-class resoucres
101
                        continue;
102
                    }
103
                    if (file.startsWith("Test")) {
104
                        // Skip test resources
105
                        continue;
106
                    }
107
                    if (file.matches(".*\\$[0-9]?\\.class")) {
108
                        // Skip anonymous inner classes
109
                        continue;
110
                    }
111
                    String name = file.substring(0, file.length() - 6);
112
                    name = name.replace('$', '.');
113
                    if (classNames.contains(name)) {
114
                        // Skip classes already known
115
                        continue;
116
                    }
117
                    File f = new File (dir, file);
118
                    if (!f.isFile()) {
119
                        // Skip directories
120
                        continue;
121
                    }
122
                    Class<?> clazz = Class.forName(packageName + "." + name);
123
                    if (!Modifier.isPublic(clazz.getModifiers())) {
124
                        // Skip non-public classes
125
                        continue;
126
                    }
127
128
                    // There should be nothing left unless we missed something
129
                    Assert.fail(packageName + "." + name);
130
                }
131
            }
132
        }
133
    }
134
135
136
    private static Stream<String> getJavaBaseClasses() throws Exception {
137
        // While this code is only used on Java 9 and later, it needs to compile
138
        // with Java 8 so use reflection foir now.
139
        Class<?> clazzModuleFinder = Class.forName("java.lang.module.ModuleFinder");
140
        Class<?> clazzModuleReference = Class.forName("java.lang.module.ModuleReference");
141
        Class<?> clazzModuleReader = Class.forName("java.lang.module.ModuleReader");
142
143
        // Returns ModuleFinder
144
        Object mf = clazzModuleFinder.getMethod("ofSystem").invoke(null);
145
        // Returns ModuleReference
146
        Object mRef = ((Optional<?>) clazzModuleFinder.getMethod(
147
                "find", String.class).invoke(mf, "java.base")).get();
148
        // Returns ModuleReader
149
        Object mr = clazzModuleReference.getMethod("open").invoke(mRef);
150
        // Returns the contents of the module
151
        @SuppressWarnings("unchecked")
152
        Stream<String> result = (Stream<String>) clazzModuleReader.getMethod("list").invoke(mr);
153
        return result;
154
    }
155
}
156
native
(-)test/javax/el/TesterImportHandlerPerformance.java (+50 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
package javax.el;
18
19
import org.junit.Test;
20
21
public class TesterImportHandlerPerformance {
22
23
    /*
24
     * This test is looking at the cost of looking up a class when the standard
25
     * JSP package imports are present:
26
     * - java.lang
27
     * - javax.servlet
28
     * - javax.servlet.http
29
     * - javax.servlet.jsp
30
     *
31
     * Before optimisation, this test took ~4.6s on markt's desktop
32
     * After optimisation, this test took ~0.05s on markt's desktop
33
     */
34
    @Test
35
    public void testBug62453() throws Exception {
36
        long totalTime = 0;
37
        for (int i = 0; i < 100000; i++) {
38
            ImportHandler ih = new ImportHandler();
39
            ih.importPackage("javax.servlet");
40
            ih.importPackage("javax.servlet.http");
41
            ih.importPackage("javax.servlet.jsp");
42
            long start = System.nanoTime();
43
            ih.resolveClass("unknown");
44
            long end = System.nanoTime();
45
            totalTime += (end -start);
46
        }
47
        System.out.println("Time taken: " + totalTime + "ns");
48
    }
49
}
50
native
(-)test/javax/servlet/jsp/el/TestScopedAttributeELResolver.java (+38 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
package javax.servlet.jsp.el;
18
19
import org.junit.Assert;
20
import org.junit.Test;
21
22
import org.apache.catalina.startup.TomcatBaseTest;
23
import org.apache.tomcat.util.buf.ByteChunk;
24
25
public class TestScopedAttributeELResolver extends TomcatBaseTest {
26
27
    @Test
28
    public void testBug49196() throws Exception {
29
        getTomcatInstanceTestWebapp(true, true);
30
31
        ByteChunk res = getUrl("http://localhost:" + getPort() +
32
                "/test/bug6nnnn/bug62453.jsp");
33
34
        String result = res.toString();
35
        Assert.assertTrue(result, result.contains("OK"));
36
    }
37
}
38
native
(-)test/webapp/WEB-INF/tags/bug62453.tag (+26 lines)
Line 0 Link Here
1
<%--
2
 Licensed to the Apache Software Foundation (ASF) under one or more
3
  contributor license agreements.  See the NOTICE file distributed with
4
  this work for additional information regarding copyright ownership.
5
  The ASF licenses this file to You under the Apache License, Version 2.0
6
  (the "License"); you may not use this file except in compliance with
7
  the License.  You may obtain a copy of the License at
8
9
      http://www.apache.org/licenses/LICENSE-2.0
10
11
  Unless required by applicable law or agreed to in writing, software
12
  distributed under the License is distributed on an "AS IS" BASIS,
13
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
  See the License for the specific language governing permissions and
15
  limitations under the License.
16
--%>
17
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
18
<%@ attribute name="foo" required="true" %>
19
<%@ attribute name="bar" %>
20
<%@ attribute name="baz" %>
21
22
<div>
23
  <div>foo:  ${foo.toString()}</div>
24
  <div>bar:  ${bar.toString()}</div>
25
  <div>baz:  ${baz.toString()}</div>
26
</div>
(-)test/webapp/bug6nnnn/bug62453.jsp (+25 lines)
Line 0 Link Here
1
<%--
2
 Licensed to the Apache Software Foundation (ASF) under one or more
3
  contributor license agreements.  See the NOTICE file distributed with
4
  this work for additional information regarding copyright ownership.
5
  The ASF licenses this file to You under the Apache License, Version 2.0
6
  (the "License"); you may not use this file except in compliance with
7
  the License.  You may obtain a copy of the License at
8
9
      http://www.apache.org/licenses/LICENSE-2.0
10
11
  Unless required by applicable law or agreed to in writing, software
12
  distributed under the License is distributed on an "AS IS" BASIS,
13
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
  See the License for the specific language governing permissions and
15
  limitations under the License.
16
--%>
17
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
18
19
<html>
20
  <body>
21
    <h2>Example of Uninitialized Tag Attributes</h2>
22
    <tags:bug62453 foo="FOO"/>
23
  </body>
24
</html>
25
native

Return to bug 62453