From feda38ec496c892f432e15b6e1c3b4fbe4949f19 Mon Sep 17 00:00:00 2001 From: Alexandre Chatiron Date: Mon, 4 Aug 2014 11:34:37 +0800 Subject: [PATCH] [#1823] Fix play.exceptions.CompilationException --- .../play/classloading/ApplicationClasses.java | 25 ++++++++++++++----- .../classloading/ApplicationClassloader.java | 19 +++++++++++--- framework/src/play/vfs/VirtualFile.java | 19 ++++++++++++++ 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/framework/src/play/classloading/ApplicationClasses.java b/framework/src/play/classloading/ApplicationClasses.java index 547c0e5115..b5851c2504 100644 --- a/framework/src/play/classloading/ApplicationClasses.java +++ b/framework/src/play/classloading/ApplicationClasses.java @@ -45,10 +45,14 @@ public void clear() { * @return The ApplicationClass or null */ public ApplicationClass getApplicationClass(String name) { - if (!classes.containsKey(name) && getJava(name) != null) { - classes.put(name, new ApplicationClass(name)); + VirtualFile javaFile = getJava(name); + if(javaFile != null){ + if (!classes.containsKey(name)) { + classes.put(name, new ApplicationClass(name)); + } + return classes.get(name); } - return classes.get(name); + return null; } /** @@ -323,10 +327,19 @@ public static VirtualFile getJava(String name) { if (fileName.contains("$")) { fileName = fileName.substring(0, fileName.indexOf("$")); } - fileName = fileName.replace(".", "/") + ".java"; + // the local variable fileOrDir is important! + String fileOrDir = fileName.replace(".", "/"); + fileName = fileOrDir + ".java"; for (VirtualFile path : Play.javaPath) { - VirtualFile javaFile = path.child(fileName); - if (javaFile.exists()) { + // 1. check if there is a folder (without extension) + VirtualFile javaFile = path.child(fileOrDir); + + if (javaFile.exists() && javaFile.isDirectory() && javaFile.matchName(fileName)) { + return javaFile; + } + // 2. check if there is a file + javaFile = path.child(fileName); + if (javaFile.exists() && javaFile.matchName(fileName)) { return javaFile; } } diff --git a/framework/src/play/classloading/ApplicationClassloader.java b/framework/src/play/classloading/ApplicationClassloader.java index f732892f4d..c6b414638d 100644 --- a/framework/src/play/classloading/ApplicationClassloader.java +++ b/framework/src/play/classloading/ApplicationClassloader.java @@ -21,6 +21,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; + import play.Logger; import play.Play; import play.classloading.hash.ClassStateHashCreator; @@ -201,8 +202,8 @@ private void loadPackage(String className) { } else { className = "package-info"; } - if (findLoadedClass(className) == null) { - loadApplicationClass(className); + if (this.findLoadedClass(className) == null) { + this.loadApplicationClass(className); } } @@ -211,7 +212,7 @@ private void loadPackage(String className) { */ protected byte[] getClassDefinition(String name) { name = name.replace(".", "/") + ".class"; - InputStream is = getResourceAsStream(name); + InputStream is = this.getResourceAsStream(name); if (is == null) { return null; } @@ -245,6 +246,18 @@ public InputStream getResourceAsStream(String name) { return res.inputstream(); } } + URL url = this.getResource(name); + if (url != null) { + try { + File file = new File(url.toURI()); + String fileName = file.getCanonicalFile().getName(); + if (!name.endsWith(fileName)) { + return null; + } + } catch (Exception e) { + } + } + return super.getResourceAsStream(name); } diff --git a/framework/src/play/vfs/VirtualFile.java b/framework/src/play/vfs/VirtualFile.java index a1794f6960..8a55ef06f5 100644 --- a/framework/src/play/vfs/VirtualFile.java +++ b/framework/src/play/vfs/VirtualFile.java @@ -256,4 +256,23 @@ public static VirtualFile fromRelativePath(String relativePath) { return null; } + + /** + * Method to check if the name really match (very useful on system without case sensibility (like windows)) + * @param fileName + * @return true if match + */ + public boolean matchName(String fileName) { + // we need to check the name case to be sure we is not conflict with a file with the same name + String canonicalName = null; + try { + canonicalName = this.realFile.getCanonicalFile().getName(); + } catch (IOException e) { + } + // Name case match + if (fileName != null && canonicalName != null && fileName.endsWith(canonicalName)) { + return true; + } + return false; + } } \ No newline at end of file