Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Bartel2013-08-09 04:19:04 +0000
committerJan Bartel2013-08-09 04:19:04 +0000
commit66620b77b8b524bbeaae1d1516df2994997d1853 (patch)
tree6f7f7d7708c5cafbeb711b07bc2afbe4a16bca7f
parent4ce461559739c4280914c806ada4b32dd0f169ee (diff)
downloadorg.eclipse.jetty.project-66620b77b8b524bbeaae1d1516df2994997d1853.tar.gz
org.eclipse.jetty.project-66620b77b8b524bbeaae1d1516df2994997d1853.tar.xz
org.eclipse.jetty.project-66620b77b8b524bbeaae1d1516df2994997d1853.zip
414507 Ensure AnnotationParser ignores parent dir hierarchy when checking for hidden dirnames
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java71
-rw-r--r--jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java150
2 files changed, 167 insertions, 54 deletions
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
index 8f2bd36161..8ae4267034 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
@@ -529,7 +529,7 @@ public class AnnotationParser
if (!dir.isDirectory() || !dir.exists() || dir.getName().startsWith("."))
return;
-
+
String[] files=dir.list();
for (int f=0;files!=null && f<files.length;f++)
{
@@ -538,15 +538,20 @@ public class AnnotationParser
Resource res = dir.addPath(files[f]);
if (res.isDirectory())
parse(res, resolver);
- String name = res.getName();
- if (isValidClassFileName(name))
+ else
{
- if ((resolver == null)|| (!resolver.isExcluded(name) && (!isParsed(name) || resolver.shouldOverride(name))))
+ String fullname = res.getName();
+ String filename = res.getFile().getName();
+
+ if (isValidClassFileName(filename))
{
- Resource r = Resource.newResource(res.getURL());
- scanClass(r.getInputStream());
- }
+ if ((resolver == null)|| (!resolver.isExcluded(fullname) && (!isParsed(fullname) || resolver.shouldOverride(fullname))))
+ {
+ Resource r = Resource.newResource(res.getURL());
+ scanClass(r.getInputStream());
+ }
+ }
}
}
catch (Exception ex)
@@ -585,8 +590,8 @@ public class AnnotationParser
if (entry.isDirectory())
return;
- String name = entry.getName();
- if (isValidClassFileName(name))
+ String name = entry.getName();
+ if (isValidClassFilePath(name) && isValidClassFileName(name))
{
String shortName = name.replace('/', '.').substring(0,name.length()-6);
if ((resolver == null)
@@ -634,9 +639,7 @@ public class AnnotationParser
return;
String name = entry.getName();
-
- //skip any class files that are in a hidden directory (ie dirname starts with .)
- if (isValidClassFileName(name))
+ if (isValidClassFilePath(name) && isValidClassFileName(name))
{
String shortName = name.replace('/', '.').substring(0,name.length()-6);
@@ -702,23 +705,53 @@ public class AnnotationParser
* @param path
* @return
*/
- private boolean isValidClassFileName (String path)
+ private boolean isValidClassFileName (String name)
{
+ //no name cannot be valid
+ if (name == null || name.length()==0)
+ return false;
+
//skip anything that is not a class file
- if (!path.toLowerCase(Locale.ENGLISH).endsWith(".class"))
+ if (!name.toLowerCase(Locale.ENGLISH).endsWith(".class"))
+ {
+ if (LOG.isDebugEnabled()) LOG.debug("Not a class: {}",name);
return false;
-
- //skip any classfiles that are not a valid name
- int c0 = 0;
- int ldir = path.lastIndexOf('/', path.length()-6);
+ }
+
+ //skip any classfiles that are not a valid java identifier
+ int c0 = 0;
+ int ldir = name.lastIndexOf('/', name.length()-6);
c0 = (ldir > -1 ? ldir+1 : c0);
+ if (!Character.isJavaIdentifierStart(name.charAt(c0)))
+ {
+ if (LOG.isDebugEnabled()) LOG.debug("Not a java identifier: {}"+name);
+ return false;
+ }
- if (!Character.isJavaIdentifierStart(path.charAt(c0)))
+ return true;
+ }
+
+
+
+ /**
+ * Check that the given path does not contain hidden directories
+ *
+ * @param path
+ * @return
+ */
+ private boolean isValidClassFilePath (String path)
+ {
+ //no path is not valid
+ if (path == null || path.length()==0)
return false;
+
//skip any classfiles that are in a hidden directory
if (path.startsWith(".") || path.contains("/."))
+ {
+ if (LOG.isDebugEnabled()) LOG.debug("Contains hidden dirs: {}"+path);
return false;
+ }
return true;
}
diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
index 9b22174911..7822095565 100644
--- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
+++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
@@ -19,12 +19,24 @@
package org.eclipse.jetty.annotations;
import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
+import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
+import org.eclipse.jetty.toolchain.test.TestingDir;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.resource.Resource;
+import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@@ -33,6 +45,46 @@ import static org.junit.Assert.fail;
public class TestAnnotationParser
{
+
+ @Rule
+ public TestingDir testdir = new TestingDir();
+
+
+
+ public static class TrackingAnnotationHandler implements DiscoverableAnnotationHandler
+ {
+ public final Set<String> foundClasses;
+
+ public TrackingAnnotationHandler()
+ {
+ this.foundClasses = new HashSet<String>();
+ }
+
+
+ public void handleClass(String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
+ List<Value> values)
+ {
+ foundClasses.add(className);
+ }
+
+
+ public void handleMethod(String className, String methodName, int access, String desc, String signature, String[] exceptions, String annotation,
+ List<Value> values)
+ {
+ /* ignore */
+ }
+
+
+ public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
+ List<Value> values)
+ {
+ /* ignore */
+ }
+ }
+
+
+
+
@Test
public void testSampleAnnotation() throws Exception
{
@@ -50,35 +102,20 @@ public class TestAnnotationParser
}
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
- List<Value> values)
+ List<Value> values)
{
- assertEquals ("m", fieldName);
- assertEquals (org.objectweb.asm.Type.OBJECT, org.objectweb.asm.Type.getType(fieldType).getSort());
- assertEquals (1, values.size());
- Value anv1 = values.get(0);
- assertEquals ("value", anv1.getName());
- assertEquals (7, anv1.getValue());
+ assertEquals ("m", fieldName);
+ assertEquals (org.objectweb.asm.Type.OBJECT, org.objectweb.asm.Type.getType(fieldType).getSort());
+ assertEquals (1, values.size());
+ Value anv1 = values.get(0);
+ assertEquals ("value", anv1.getName());
+ assertEquals (7, anv1.getValue());
}
public void handleMethod(String className, String methodName, int access, String desc, String signature, String[] exceptions, String annotation,
List<Value> values)
{
- System.err.println("Sample annotated method : classname="+className+" methodName="+methodName+" access="+access+" desc="+desc+" signature="+signature);
-
- org.objectweb.asm.Type retType = org.objectweb.asm.Type.getReturnType(desc);
- System.err.println("REturn type = "+retType);
- org.objectweb.asm.Type[] params = org.objectweb.asm.Type.getArgumentTypes(desc);
- if (params == null)
- System.err.println("No params");
- else
- System.err.println(params.length+" params");
-
- if (exceptions == null)
- System.err.println("No exceptions");
- else
- System.err.println(exceptions.length+" exceptions");
-
assertEquals("org.eclipse.jetty.annotations.ClassA", className);
assertTrue(methods.contains(methodName));
assertEquals("org.eclipse.jetty.annotations.Sample", annotation);
@@ -102,8 +139,7 @@ public class TestAnnotationParser
});
long end = System.currentTimeMillis();
-
- System.err.println("Time to parse class: "+((end-start)));
+ //System.err.println("Time to parse class: "+((end-start)));
}
@Test
@@ -118,11 +154,6 @@ public class TestAnnotationParser
List<Value> values)
{
assertTrue("org.eclipse.jetty.annotations.ClassB".equals(className));
-
- for (Value anv: values)
- {
- System.err.println(anv.toString());
- }
}
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
@@ -137,18 +168,14 @@ public class TestAnnotationParser
{
assertTrue("org.eclipse.jetty.annotations.ClassB".equals(className));
assertTrue("a".equals(methodName));
- for (Value anv: values)
- {
- System.err.println(anv.toString());
- }
}
}
parser.registerAnnotationHandler("org.eclipse.jetty.annotations.Multi", new MultiAnnotationHandler());
parser.parse(classNames, null);
}
-
-
+
+
@Test
public void testHiddenFilesInJar () throws Exception
{
@@ -157,4 +184,57 @@ public class TestAnnotationParser
parser.parse(badClassesJar.toURI(), null);
//only the valid classes inside bad-classes.jar should be parsed. If any invalid classes are parsed and exception would be thrown here
}
+
+ @Test
+ public void testBasedirExclusion() throws Exception
+ {
+ // Build up basedir, which itself has a path segment that violates java package and classnaming.
+ // The basedir should have no effect on annotation scanning.
+ // Intentionally using a base director name that starts with a "."
+ // This mimics what you see in jenkins, hudson, hadoop, solr, camel, and selenium for their
+ // installed and/or managed webapps
+ File basedir = testdir.getFile(".base/workspace/classes");
+ FS.ensureEmpty(basedir);
+
+ // Copy in class that is known to have annotations.
+ copyClass(ClassA.class,basedir);
+
+ // Setup Tracker
+ TrackingAnnotationHandler tracker = new TrackingAnnotationHandler();
+
+ // Setup annotation scanning
+ AnnotationParser parser = new AnnotationParser();
+ parser.registerAnnotationHandler(Sample.class.getName(), tracker);
+
+ // Parse
+ parser.parse(Resource.newResource(basedir),null);
+
+ // Validate
+ assertTrue(tracker.foundClasses.contains(ClassA.class.getName()));
+ }
+
+ private void copyClass(Class<?> clazz, File basedir) throws IOException
+ {
+ String classname = clazz.getName().replace('.',File.separatorChar) + ".class";
+ URL url = this.getClass().getResource('/'+classname);
+ assertTrue(url != null);
+
+ String classpath = classname.substring(0,classname.lastIndexOf(File.separatorChar));
+ FS.ensureDirExists(new File(basedir,classpath));
+
+ InputStream in = null;
+ OutputStream out = null;
+ try
+ {
+ in = url.openStream();
+ out = new FileOutputStream(new File(basedir,classname));
+ IO.copy(in,out);
+ }
+ finally
+ {
+ IO.close(out);
+ IO.close(in);
+ }
+ }
+
}

Back to the top