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

(-)java/org/apache/jasper/JspCompilationContext.java (-5 / +5 lines)
Lines 295-301 Link Here
295
                // May not be in a JAR in some IDE environments
295
                // May not be in a JAR in some IDE environments
296
                result = context.getResource(canonicalURI(res));
296
                result = context.getResource(canonicalURI(res));
297
            }
297
            }
298
        } else if (res.startsWith("jar:file:")) {
298
        } else if (res.startsWith("jar:jndi:")) {
299
                // This is a tag file packaged in a jar that is being checked
299
                // This is a tag file packaged in a jar that is being checked
300
                // for a dependency
300
                // for a dependency
301
                result = new URL(res);
301
                result = new URL(res);
Lines 385-398 Link Here
385
        return jspUri;
385
        return jspUri;
386
    }
386
    }
387
387
388
    public long getJspLastModified() {
388
    public Long getLastModified(String resource) {
389
        long result = -1;
389
        long result = -1;
390
        URLConnection uc = null;
390
        URLConnection uc = null;
391
        try {
391
        try {
392
            URL jspUrl = getResource(getJspFile());
392
            URL jspUrl = getResource(resource);
393
            if (jspUrl == null) {
393
            if (jspUrl == null) {
394
                incrementRemoved();
394
                incrementRemoved();
395
                return result;
395
                return Long.valueOf(result);
396
            }
396
            }
397
            uc = jspUrl.openConnection();
397
            uc = jspUrl.openConnection();
398
            if (uc instanceof JarURLConnection) {
398
            if (uc instanceof JarURLConnection) {
Lines 419-425 Link Here
419
                }
419
                }
420
            }
420
            }
421
        }
421
        }
422
        return result;
422
        return Long.valueOf(result);
423
    }
423
    }
424
424
425
    public boolean isTagFile() {
425
    public boolean isTagFile() {
(-)java/org/apache/jasper/compiler/Compiler.java (-11 / +19 lines)
Lines 27-33 Link Here
27
import java.net.URL;
27
import java.net.URL;
28
import java.net.URLConnection;
28
import java.net.URLConnection;
29
import java.util.Iterator;
29
import java.util.Iterator;
30
import java.util.List;
30
import java.util.Map;
31
import java.util.Map.Entry;
31
32
32
import org.apache.jasper.JasperException;
33
import org.apache.jasper.JasperException;
33
import org.apache.jasper.JspCompilationContext;
34
import org.apache.jasper.JspCompilationContext;
Lines 370-375 Link Here
370
371
371
        try {
372
        try {
372
            String[] smap = generateJava();
373
            String[] smap = generateJava();
374
            File javaFile = new File(ctxt.getServletJavaFileName());
375
            Long jspLastModified = ctxt.getLastModified(ctxt.getJspFile());
376
            javaFile.setLastModified(jspLastModified.longValue());
373
            if (compileClass) {
377
            if (compileClass) {
374
                generateClass(smap);
378
                generateClass(smap);
375
                // Fix for bugzilla 41606
379
                // Fix for bugzilla 41606
Lines 377-384 Link Here
377
                String targetFileName = ctxt.getClassFileName();
381
                String targetFileName = ctxt.getClassFileName();
378
                if (targetFileName != null) {
382
                if (targetFileName != null) {
379
                    File targetFile = new File(targetFileName);
383
                    File targetFile = new File(targetFileName);
380
                    if (targetFile.exists() && jsw != null) {
384
                    if (targetFile.exists()) {
381
                        jsw.setServletClassLastModifiedTime(targetFile.lastModified());
385
                        targetFile.setLastModified(jspLastModified.longValue());
386
                        if (jsw != null) {
387
                            jsw.setServletClassLastModifiedTime(
388
                                    jspLastModified.longValue());
389
                        }
382
                    }
390
                    }
383
                }
391
                }
384
            }
392
            }
Lines 440-447 Link Here
440
            jsw.setLastModificationTest(System.currentTimeMillis());
448
            jsw.setLastModificationTest(System.currentTimeMillis());
441
        }
449
        }
442
450
443
        long jspRealLastModified = ctxt.getJspLastModified();
451
        Long jspRealLastModified = ctxt.getLastModified(ctxt.getJspFile());
444
        if (jspRealLastModified < 0) {
452
        if (jspRealLastModified.longValue() < 0) {
445
            // Something went wrong - assume modification
453
            // Something went wrong - assume modification
446
            return true;
454
            return true;
447
        }
455
        }
Lines 463-469 Link Here
463
        if (checkClass && jsw != null) {
471
        if (checkClass && jsw != null) {
464
            jsw.setServletClassLastModifiedTime(targetLastModified);
472
            jsw.setServletClassLastModifiedTime(targetLastModified);
465
        }
473
        }
466
        if (targetLastModified < jspRealLastModified) {
474
        if (targetLastModified != jspRealLastModified.longValue()) {
467
            if (log.isDebugEnabled()) {
475
            if (log.isDebugEnabled()) {
468
                log.debug("Compiler: outdated: " + targetFile + " "
476
                log.debug("Compiler: outdated: " + targetFile + " "
469
                        + targetLastModified);
477
                        + targetLastModified);
Lines 477-492 Link Here
477
            return false;
485
            return false;
478
        }
486
        }
479
487
480
        List<String> depends = jsw.getDependants();
488
        Map<String,Long> depends = jsw.getDependants();
481
        if (depends == null) {
489
        if (depends == null) {
482
            return false;
490
            return false;
483
        }
491
        }
484
492
485
        Iterator<String> it = depends.iterator();
493
        Iterator<Entry<String,Long>> it = depends.entrySet().iterator();
486
        while (it.hasNext()) {
494
        while (it.hasNext()) {
487
            String include = it.next();
495
            Entry<String,Long> include = it.next();
488
            try {
496
            try {
489
                URL includeUrl = ctxt.getResource(include);
497
                URL includeUrl = ctxt.getResource(include.getKey());
490
                if (includeUrl == null) {
498
                if (includeUrl == null) {
491
                    return true;
499
                    return true;
492
                }
500
                }
Lines 501-507 Link Here
501
                }
509
                }
502
                iuc.getInputStream().close();
510
                iuc.getInputStream().close();
503
511
504
                if (includeLastModified > targetLastModified) {
512
                if (includeLastModified != include.getValue().longValue()) {
505
                    return true;
513
                    return true;
506
                }
514
                }
507
            } catch (Exception e) {
515
            } catch (Exception e) {
(-)java/org/apache/jasper/compiler/Generator.java (-8 / +16 lines)
Lines 34-39 Link Here
34
import java.util.Hashtable;
34
import java.util.Hashtable;
35
import java.util.Iterator;
35
import java.util.Iterator;
36
import java.util.List;
36
import java.util.List;
37
import java.util.Map;
38
import java.util.Map.Entry;
37
import java.util.Set;
39
import java.util.Set;
38
import java.util.TimeZone;
40
import java.util.TimeZone;
39
import java.util.Vector;
41
import java.util.Vector;
Lines 525-544 Link Here
525
        out.println();
527
        out.println();
526
528
527
        // Static data for getDependants()
529
        // Static data for getDependants()
528
        out.printil("private static java.util.List<java.lang.String> _jspx_dependants;");
530
        out.printil("private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;");
529
        out.println();
531
        out.println();
530
        List<String> dependants = pageInfo.getDependants();
532
        Map<String,Long> dependants = pageInfo.getDependants();
531
        Iterator<String> iter = dependants.iterator();
533
        Iterator<Entry<String,Long>> iter = dependants.entrySet().iterator();
532
        if (!dependants.isEmpty()) {
534
        if (!dependants.isEmpty()) {
533
            out.printil("static {");
535
            out.printil("static {");
534
            out.pushIndent();
536
            out.pushIndent();
535
            out.printin("_jspx_dependants = new java.util.ArrayList<java.lang.String>(");
537
            out.printin("_jspx_dependants = new java.util.HashMap<java.lang.String,java.lang.Long>(");
536
            out.print("" + dependants.size());
538
            out.print("" + dependants.size());
537
            out.println(");");
539
            out.println(");");
538
            while (iter.hasNext()) {
540
            while (iter.hasNext()) {
539
                out.printin("_jspx_dependants.add(\"");
541
                Entry<String,Long> entry = iter.next();
540
                out.print(iter.next());
542
                out.printin("_jspx_dependants.put(\"");
541
                out.println("\");");
543
                out.print(entry.getKey());
544
                out.print("\", Long.valueOf(");
545
                out.print(entry.getValue().toString());
546
                out.println("L));");
542
            }
547
            }
543
            out.popIndent();
548
            out.popIndent();
544
            out.printil("}");
549
            out.printil("}");
Lines 576-582 Link Here
576
     */
581
     */
577
    private void genPreambleMethods() {
582
    private void genPreambleMethods() {
578
        // Method used to get compile time file dependencies
583
        // Method used to get compile time file dependencies
579
        out.printil("public java.util.List<java.lang.String> getDependants() {");
584
        out.printil("public java.util.Map<java.lang.String,java.lang.Long> getDependants() {");
580
        out.pushIndent();
585
        out.pushIndent();
581
        out.printil("return _jspx_dependants;");
586
        out.printil("return _jspx_dependants;");
582
        out.popIndent();
587
        out.popIndent();
Lines 3494-3499 Link Here
3494
        out.println(" * Version: " + ctxt.getServletContext().getServerInfo());
3499
        out.println(" * Version: " + ctxt.getServletContext().getServerInfo());
3495
        out.println(" * Generated at: " + timestampFormat.format(new Date()) +
3500
        out.println(" * Generated at: " + timestampFormat.format(new Date()) +
3496
                " UTC");
3501
                " UTC");
3502
        out.println(" * Note: The last modified time of this file was set to");
3503
        out.println(" *       the last modified time of the source file after");
3504
        out.println(" *       generation to assit with modification tracking.");
3497
        out.println(" */");
3505
        out.println(" */");
3498
    }
3506
    }
3499
3507
(-)java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java (-1 / +1 lines)
Lines 121-127 Link Here
121
                            
121
                            
122
                            // Add implicit TLD to dependency list
122
                            // Add implicit TLD to dependency list
123
                            if (pi != null) {
123
                            if (pi != null) {
124
                                pi.addDependant(path);
124
                                pi.addDependant(path, ctxt.getLastModified(path));
125
                            }
125
                            }
126
                            
126
                            
127
                            ParserUtils pu = new ParserUtils();
127
                            ParserUtils pu = new ParserUtils();
(-)java/org/apache/jasper/compiler/PageInfo.java (-6 / +7 lines)
Lines 21-26 Link Here
21
import java.util.HashSet;
21
import java.util.HashSet;
22
import java.util.LinkedList;
22
import java.util.LinkedList;
23
import java.util.List;
23
import java.util.List;
24
import java.util.Map;
24
import java.util.Set;
25
import java.util.Set;
25
import java.util.Vector;
26
import java.util.Vector;
26
27
Lines 39-45 Link Here
39
class PageInfo {
40
class PageInfo {
40
41
41
    private Vector<String> imports;
42
    private Vector<String> imports;
42
    private Vector<String> dependants;
43
    private Map<String,Long> dependants;
43
44
44
    private BeanRepository beanRepository;
45
    private BeanRepository beanRepository;
45
    private Set<String> varInfoNames;
46
    private Set<String> varInfoNames;
Lines 108-114 Link Here
108
        this.xmlPrefixMapper = new HashMap<String, LinkedList<String>>();
109
        this.xmlPrefixMapper = new HashMap<String, LinkedList<String>>();
109
        this.nonCustomTagPrefixMap = new HashMap<String, Mark>();
110
        this.nonCustomTagPrefixMap = new HashMap<String, Mark>();
110
        this.imports = new Vector<String>();
111
        this.imports = new Vector<String>();
111
        this.dependants = new Vector<String>();
112
        this.dependants = new HashMap<String,Long>();
112
        this.includePrelude = new Vector<String>();
113
        this.includePrelude = new Vector<String>();
113
        this.includeCoda = new Vector<String>();
114
        this.includeCoda = new Vector<String>();
114
        this.pluginDcls = new Vector<String>();
115
        this.pluginDcls = new Vector<String>();
Lines 146-157 Link Here
146
        return jspFile;
147
        return jspFile;
147
    }
148
    }
148
149
149
    public void addDependant(String d) {
150
    public void addDependant(String d, Long lastModified) {
150
        if (!dependants.contains(d) && !jspFile.equals(d))
151
        if (!dependants.containsKey(d) && !jspFile.equals(d))
151
                dependants.add(d);
152
                dependants.put(d, lastModified);
152
    }
153
    }
153
154
154
    public List<String> getDependants() {
155
    public Map<String,Long> getDependants() {
155
        return dependants;
156
        return dependants;
156
    }
157
    }
157
158
(-)java/org/apache/jasper/compiler/ParserController.java (-2 / +5 lines)
Lines 192-201 Link Here
192
        if (parent != null) {
192
        if (parent != null) {
193
            // Included resource, add to dependent list
193
            // Included resource, add to dependent list
194
            if (jarFile == null) {
194
            if (jarFile == null) {
195
                compiler.getPageInfo().addDependant(absFileName);
195
                compiler.getPageInfo().addDependant(absFileName,
196
                        ctxt.getLastModified(absFileName));
196
            } else {
197
            } else {
198
                String entry = absFileName.substring(1);
197
                compiler.getPageInfo().addDependant(
199
                compiler.getPageInfo().addDependant(
198
                        jarResource.getEntry(absFileName.substring(1)).toString());
200
                        jarResource.getEntry(entry).toString(),
201
                        Long.valueOf(jarFile.getEntry(entry).getTime()));
199
                        
202
                        
200
            }
203
            }
201
        }
204
        }
(-)java/org/apache/jasper/compiler/TagFileProcessor.java (-9 / +22 lines)
Lines 21-26 Link Here
21
import java.io.IOException;
21
import java.io.IOException;
22
import java.util.HashMap;
22
import java.util.HashMap;
23
import java.util.Iterator;
23
import java.util.Iterator;
24
import java.util.Map.Entry;
24
import java.util.Vector;
25
import java.util.Vector;
25
26
26
import javax.el.MethodExpression;
27
import javax.el.MethodExpression;
Lines 586-595 Link Here
586
            try {
587
            try {
587
                Object tagIns = tagClazz.newInstance();
588
                Object tagIns = tagClazz.newInstance();
588
                if (tagIns instanceof JspSourceDependent) {
589
                if (tagIns instanceof JspSourceDependent) {
589
                    Iterator<String> iter = ((JspSourceDependent) tagIns)
590
                    Iterator<Entry<String,Long>> iter = ((JspSourceDependent)
590
                            .getDependants().iterator();
591
                            tagIns).getDependants().entrySet().iterator();
591
                    while (iter.hasNext()) {
592
                    while (iter.hasNext()) {
592
                        parentPageInfo.addDependant(iter.next());
593
                        Entry<String,Long> entry = iter.next();
594
                        parentPageInfo.addDependant(entry.getKey(),
595
                                entry.getValue());
593
                    }
596
                    }
594
                }
597
                }
595
            } catch (Exception e) {
598
            } catch (Exception e) {
Lines 628-643 Link Here
628
                            tagFileInfo.getTagInfo().getTagLibrary().getURI());
631
                            tagFileInfo.getTagInfo().getTagLibrary().getURI());
629
                    JarResource jarResource = location.getJarResource();
632
                    JarResource jarResource = location.getJarResource();
630
                    if (jarResource != null) {
633
                    if (jarResource != null) {
631
                        // Add TLD
634
                        try {
632
                        pageInfo.addDependant(jarResource.getEntry(location.getName()).toString());
635
                            // Add TLD
633
                        // Add Tag
636
                            pageInfo.addDependant(jarResource.getEntry(location.getName()).toString(),
634
                        pageInfo.addDependant(jarResource.getEntry(tagFilePath.substring(1)).toString());
637
                                    Long.valueOf(jarResource.getJarFile().getEntry(location.getName()).getTime()));
638
                            // Add Tag
639
                            pageInfo.addDependant(jarResource.getEntry(tagFilePath.substring(1)).toString(),
640
                                    Long.valueOf(jarResource.getJarFile().getEntry(tagFilePath.substring(1)).getTime()));
641
                        } catch (IOException ioe) {
642
                            throw new JasperException(ioe);
643
                        }
635
                    }
644
                    }
636
                    else {
645
                    else {
637
                        pageInfo.addDependant(tagFilePath);
646
                        pageInfo.addDependant(tagFilePath,
647
                                compiler.getCompilationContext().getLastModified(
648
                                        tagFilePath));
638
                    }
649
                    }
639
                } else {
650
                } else {
640
                    pageInfo.addDependant(tagFilePath);
651
                    pageInfo.addDependant(tagFilePath,
652
                            compiler.getCompilationContext().getLastModified(
653
                                    tagFilePath));
641
                }
654
                }
642
                Class<?> c = loadTagFile(compiler, tagFilePath, n.getTagInfo(),
655
                Class<?> c = loadTagFile(compiler, tagFilePath, n.getTagInfo(),
643
                        pageInfo);
656
                        pageInfo);
(-)java/org/apache/jasper/compiler/TagLibraryInfoImpl.java (-1 / +2 lines)
Lines 170-176 Link Here
170
                // Add TLD to dependency list
170
                // Add TLD to dependency list
171
                PageInfo pageInfo = ctxt.createCompiler().getPageInfo();
171
                PageInfo pageInfo = ctxt.createCompiler().getPageInfo();
172
                if (pageInfo != null) {
172
                if (pageInfo != null) {
173
                    pageInfo.addDependant(tldName);
173
                    pageInfo.addDependant(tldName,
174
                            ctxt.getLastModified(tldName));
174
                }
175
                }
175
            } else {
176
            } else {
176
                // Tag library is packaged in JAR file
177
                // Tag library is packaged in JAR file
(-)java/org/apache/jasper/runtime/JspSourceDependent.java (-4 / +4 lines)
Lines 17-23 Link Here
17
17
18
package org.apache.jasper.runtime;
18
package org.apache.jasper.runtime;
19
19
20
import java.util.List;
20
import java.util.Map;
21
21
22
/**
22
/**
23
 * Interface for tracking the source files dependencies, for the purpose
23
 * Interface for tracking the source files dependencies, for the purpose
Lines 31-39 Link Here
31
public interface JspSourceDependent {
31
public interface JspSourceDependent {
32
32
33
   /**
33
   /**
34
    * Returns a list of files names that the current page has a source
34
    * Returns a map of file names and last modified time where the current page
35
    * dependency on.
35
    * has a source dependency on the file.
36
    */
36
    */
37
    public List<String> getDependants();
37
    public Map<String,Long> getDependants();
38
38
39
}
39
}
(-)java/org/apache/jasper/servlet/JspServletWrapper.java (-1 / +1 lines)
Lines 266-272 Link Here
266
    /**
266
    /**
267
     * Get a list of files that the current page has source dependency on.
267
     * Get a list of files that the current page has source dependency on.
268
     */
268
     */
269
    public java.util.List<String> getDependants() {
269
    public java.util.Map<String,Long> getDependants() {
270
        try {
270
        try {
271
            Object target;
271
            Object target;
272
            if (isTagFile) {
272
            if (isTagFile) {
(-)webapps/docs/changelog.xml (+8 lines)
Lines 64-69 Link Here
64
  </subsection>
64
  </subsection>
65
  <subsection name="Jasper">
65
  <subsection name="Jasper">
66
    <changelog>
66
    <changelog>
67
      <fix>
68
        <bug>33453</bug>: Recompile JSPs if last modified time of the source or
69
        any of its dependencies changes either forwards or backwards. Note that
70
        this introduces an incompatible change to the code generated for JSPs
71
        and the work directory must be emptied before starting a Tomcat instance
72
        that has been upgraded from 7.0.14 or earlier to 7.0.15 or later.
73
        (markt)
74
      </fix>
67
      <add>
75
      <add>
68
        <bug>51220</bug>: Add a system property to enable tag pooling with JSPs
76
        <bug>51220</bug>: Add a system property to enable tag pooling with JSPs
69
        that use a custom base class. Based on a patch by Dan Mikusa. (markt)
77
        that use a custom base class. Based on a patch by Dan Mikusa. (markt)

Return to bug 33453