[ https://issues.apache.org/jira/browse/WW-4869?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16241871#comment-16241871 ]
ASF GitHub Bot commented on WW-4869: ------------------------------------ lukaszlenart closed pull request #172: WW-4869 Fixes JarEntryRevision URL: https://github.com/apache/struts/pull/172 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/core/src/main/java/com/opensymphony/xwork2/util/fs/JarEntryRevision.java b/core/src/main/java/com/opensymphony/xwork2/util/fs/JarEntryRevision.java index 4b962af08..268710fb8 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/fs/JarEntryRevision.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/fs/JarEntryRevision.java @@ -3,12 +3,10 @@ import com.opensymphony.xwork2.FileManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; -import org.apache.commons.io.FileUtils; import java.io.IOException; +import java.net.JarURLConnection; import java.net.URL; -import java.util.jar.JarFile; -import java.util.zip.ZipEntry; /** * Represents jar resource revision, used for jar://* resource @@ -17,66 +15,63 @@ private static Logger LOG = LogManager.getLogger(JarEntryRevision.class); - private static final String JAR_FILE_NAME_SEPARATOR = "!/"; - private static final String JAR_FILE_EXTENSION_END = ".jar/"; - - private String jarFileName; - private String fileNameInJar; + private URL jarFileURL; private long lastModified; public static Revision build(URL fileUrl, FileManager fileManager) { // File within a Jar // Find separator index of jar filename and filename within jar - String jarFileName = ""; + JarURLConnection conn = null; try { - String fileName = fileUrl.toString(); - int separatorIndex = fileName.indexOf(JAR_FILE_NAME_SEPARATOR); - if (separatorIndex == -1) { - separatorIndex = fileName.lastIndexOf(JAR_FILE_EXTENSION_END); - } - if (separatorIndex == -1) { - LOG.warn("Could not find end of jar file!"); - return null; - } - - // Split file name - jarFileName = fileName.substring(0, separatorIndex); - int index = separatorIndex + JAR_FILE_NAME_SEPARATOR.length(); - String fileNameInJar = fileName.substring(index).replaceAll("%20", " "); - + conn = (JarURLConnection) fileUrl.openConnection(); + conn.setUseCaches(false); URL url = fileManager.normalizeToFileProtocol(fileUrl); if (url != null) { - JarFile jarFile = new JarFile(FileUtils.toFile(url)); - ZipEntry entry = jarFile.getEntry(fileNameInJar); - return new JarEntryRevision(jarFileName, fileNameInJar, entry.getTime()); + return new JarEntryRevision(fileUrl, conn.getJarEntry().getTime()); } else { return null; } } catch (Throwable e) { - LOG.warn("Could not create JarEntryRevision for [{}]!", jarFileName, e); + LOG.warn("Could not create JarEntryRevision for [{}]!", fileUrl, e); return null; } + finally { + if(null != conn) { + try { + conn.getInputStream().close(); + } catch (IOException ignored) { + } + } + } } - private JarEntryRevision(String jarFileName, String fileNameInJar, long lastModified) { - if ((jarFileName == null) || (fileNameInJar == null)) { - throw new IllegalArgumentException("JarFileName and FileNameInJar cannot be null"); + private JarEntryRevision(URL jarFileURL, long lastModified) { + if (jarFileURL == null) { + throw new IllegalArgumentException("jarFileURL cannot be null"); } - this.jarFileName = jarFileName; - this.fileNameInJar = fileNameInJar; + this.jarFileURL = jarFileURL; this.lastModified = lastModified; } public boolean needsReloading() { - ZipEntry entry; + JarURLConnection conn = null; + long lastLastModified = lastModified; try { - JarFile jarFile = new JarFile(this.jarFileName); - entry = jarFile.getEntry(this.fileNameInJar); - } catch (IOException e) { - entry = null; + conn = (JarURLConnection) jarFileURL.openConnection(); + conn.setUseCaches(false); + lastLastModified = conn.getJarEntry().getTime(); + } catch (IOException ignored) { + } + finally { + if(null != conn) { + try { + conn.getInputStream().close(); + } catch (IOException ignored) { + } + } } - return entry != null && (lastModified < entry.getTime()); + return lastModified < lastLastModified; } } diff --git a/core/src/test/java/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.java b/core/src/test/java/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.java new file mode 100644 index 000000000..04826d502 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.java @@ -0,0 +1,54 @@ +package com.opensymphony.xwork2.util.fs; + +import com.opensymphony.xwork2.FileManager; +import com.opensymphony.xwork2.FileManagerFactory; +import com.opensymphony.xwork2.XWorkTestCase; +import org.apache.commons.io.IOUtils; + +import java.io.FileOutputStream; +import java.io.InputStream; +import java.net.URL; +import java.util.jar.Attributes; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; + +public class JarEntryRevisionTest extends XWorkTestCase { + + private FileManager fileManager; + + @Override + public void setUp() throws Exception { + super.setUp(); + fileManager = container.getInstance(FileManagerFactory.class).getFileManager(); + } + + private void createJarFile(long time) throws Exception { + Manifest manifest = new Manifest(); + manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); + FileOutputStream fos = new FileOutputStream("target/JarEntryRevisionTest_testNeedsReloading.jar", false); + JarOutputStream target = new JarOutputStream(fos, manifest); + target.putNextEntry(new ZipEntry("com/opensymphony/xwork2/util/fs/")); + ZipEntry entry = new ZipEntry("com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class"); + entry.setTime(time); + target.putNextEntry(entry); + InputStream source = getClass().getResourceAsStream("/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class"); + IOUtils.copy(source, target); + source.close(); + target.closeEntry(); + target.close(); + fos.close(); + } + + public void testNeedsReloading() throws Exception { + long now = System.currentTimeMillis(); + + createJarFile(now); + URL url = new URL("jar:file:target/JarEntryRevisionTest_testNeedsReloading.jar!/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class"); + Revision entry = JarEntryRevision.build(url, fileManager); + assertFalse(entry.needsReloading()); + + createJarFile(now + 60000); + assertTrue(entry.needsReloading()); + } +} ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org > Struts2.5.13 can't run in java9 win10 > ------------------------------------- > > Key: WW-4869 > URL: https://issues.apache.org/jira/browse/WW-4869 > Project: Struts 2 > Issue Type: Bug > Components: Dispatch Filter > Affects Versions: 2.5.13 > Environment: windows 10-jdk9-maven3.5 > Reporter: Smith Cruise > Assignee: Lukasz Lenart > Labels: java9 > Fix For: 2.5.14 > > Attachments: screenshot-1.png > > Original Estimate: 504h > Remaining Estimate: 504h > > I followed the official > tutorial,http://struts.apache.org/getting-started/how-to-create-a-struts2-web-application.html. > But always throw exception when i run webapp.i tried many times but I really > don't know how to reslove it. > Here is Exception > {noformat} > java.nio.file.InvalidPathException: Illegal char <:> at index 3: > jar:file:\D:\.m2\repository\org\apache\struts\struts2-core\2.5.13\struts2-core-2.5.13.jar > at > java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182) > at > java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153) > at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77) > at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92) > at > java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:229) > at java.base/java.io.File.toPath(File.java:2300) > at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:951) > at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:216) > at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:148) > at java.base/java.util.jar.JarFile.<init>(JarFile.java:324) > at java.base/java.util.jar.JarFile.<init>(JarFile.java:295) > at java.base/java.util.jar.JarFile.<init>(JarFile.java:234) > at > com.opensymphony.xwork2.util.fs.JarEntryRevision.needsReloading(JarEntryRevision.java:73) > at > com.opensymphony.xwork2.util.fs.DefaultFileManager.fileNeedsReloading(DefaultFileManager.java:62) > at > com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.needsReload(XmlConfigurationProvider.java:425) > at > org.apache.struts2.config.StrutsXmlConfigurationProvider.needsReload(StrutsXmlConfigurationProvider.java:163) > at > com.opensymphony.xwork2.config.ConfigurationManager.needReloadContainerProviders(ConfigurationManager.java:208) > at > com.opensymphony.xwork2.config.ConfigurationManager.conditionalReload(ConfigurationManager.java:174) > at > com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:69) > at > org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:960) > at > org.apache.struts2.dispatcher.ExecuteOperations.executeStaticResourceRequest(ExecuteOperations.java:59) > at > org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:130) > at > org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1476) > at > org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501) > at > org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137) > at > org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557) > at > org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231) > at > org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086) > at > org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429) > at > org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193) > at > org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020) > at > org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135) > at > org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255) > at > org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154) > at > org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116) > at org.eclipse.jetty.server.Server.handle(Server.java:370) > at > org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494) > at > org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971) > at > org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033) > at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644) > at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235) > at > org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82) > at > org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696) > at > org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53) > at > org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608) > at > org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543) > at java.base/java.lang.Thread.run(Thread.java:844) > {noformat} > !https://sfault-image.b0.upaiyun.com/315/537/315537393-59da0a0a714ea_articlex! -- This message was sent by Atlassian JIRA (v6.4.14#64029)