Index: modeshape-jcr/src/main/java/org/modeshape/jcr/JcrI18n.java =================================================================== --- modeshape-jcr/src/main/java/org/modeshape/jcr/JcrI18n.java (revision 2499) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/JcrI18n.java (working copy) @@ -80,6 +80,7 @@ public final class JcrI18n { public static I18n cleaningUpLocks; public static I18n cleanedUpLocks; public static I18n invalidRelativePath; + public static I18n invalidAbsolutePath; public static I18n invalidPathParameter; public static I18n invalidNamePattern; public static I18n invalidNodeTypeNameParameter; Index: modeshape-jcr/src/main/java/org/modeshape/jcr/JcrSession.java =================================================================== --- modeshape-jcr/src/main/java/org/modeshape/jcr/JcrSession.java (revision 2499) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/JcrSession.java (working copy) @@ -632,6 +632,20 @@ class JcrSession implements Session { } /** + * Throws a {@code RepositoryException} if {@code path} is not an absolute path, otherwise returns silently. + * + * @param pathAsString the string representation of the path + * @param path the path to check + * @throws RepositoryException if {@code !path.isAbsolute()} + */ + private void checkAbsolute( String pathAsString, + Path path ) throws RepositoryException { + if (!path.isAbsolute()) { + throw new RepositoryException(JcrI18n.invalidAbsolutePath.text(pathAsString)); + } + } + + /** * @param absolutePath an absolute path * @return the specified node * @throws IllegalArgumentException if absolutePath is empty or null. @@ -646,6 +660,9 @@ class JcrSession implements Session { if (path.isRoot()) { return getRootNode(); } + + checkAbsolute(absolutePath, path); + return getNode(path); } @@ -665,6 +682,9 @@ class JcrSession implements Session { if (path.isRoot()) { return true; } + + checkAbsolute(absolutePath, path); + try { cache.findJcrNode(null, path); return true; @@ -692,6 +712,8 @@ class JcrSession implements Session { throw new PathNotFoundException(JcrI18n.identifierPathNeverReferencesProperty.text()); } + checkAbsolute(absolutePath, path); + Segment lastSegment = path.getLastSegment(); if (lastSegment.hasIndex()) { throw new RepositoryException(JcrI18n.pathCannotHaveSameNameSiblingIndex.text(absolutePath)); @@ -724,6 +746,8 @@ class JcrSession implements Session { return false; } + checkAbsolute(absolutePath, path); + Segment lastSegment = path.getLastSegment(); if (lastSegment.hasIndex()) { throw new RepositoryException(JcrI18n.pathCannotHaveSameNameSiblingIndex.text(absolutePath)); Index: modeshape-jcr/src/main/resources/org/modeshape/jcr/JcrI18n.properties =================================================================== --- modeshape-jcr/src/main/resources/org/modeshape/jcr/JcrI18n.properties (revision 2499) +++ modeshape-jcr/src/main/resources/org/modeshape/jcr/JcrI18n.properties (working copy) @@ -70,6 +70,7 @@ cleaningUpLocks = Lock clean up process begun cleanedUpLocks = Lock clean up process completed errorWhileInitializingTheNamespaceRegistry = Error while initializing the namespace registry for workspace "{0}" invalidRelativePath = "{0}" is not a valid relative path +invalidAbsolutePath = "{0}" is not a valid absolute path invalidPathParameter = The "{1}" parameter value "{0}" was not a valid path invalidNamePattern = The "{1}" name pattern contained the '{0}' character, which is not allowed in a name pattern invalidNodeTypeNameParameter = The "{1}" parameter value "{0}" was not a valid node type name Index: modeshape-jcr/src/test/java/org/modeshape/jcr/ModeShapeTckTest.java =================================================================== --- modeshape-jcr/src/test/java/org/modeshape/jcr/ModeShapeTckTest.java (revision 2499) +++ modeshape-jcr/src/test/java/org/modeshape/jcr/ModeShapeTckTest.java (working copy) @@ -1240,4 +1240,30 @@ public class ModeShapeTckTest extends AbstractJCRTest { child.setProperty("foo", (Calendar)null); } + @FixFor( "MODE-1005" ) + public void testShouldThrowRepositoryExceptionForRelativePathsInSessionGetNode() throws Exception { + try { + Node root = superuser.getRootNode(); + root.addNode("nodeForRelativePathTest", "nt:unstructured"); + + superuser.getNode("nodeForRelativePathTest"); + fail("Should throw RepositoryException when attempting to call Session.getNode(String) with a relative path"); + } catch (RepositoryException re) { + // Expected + } + } + + @FixFor( "MODE-1005" ) + public void testShouldThrowRepositoryExceptionForRelativePathsInSessionGetProperty() throws Exception { + try { + Node root = superuser.getRootNode(); + root.addNode("propertyNodeForRelativePathTest", "nt:unstructured"); + + superuser.getProperty("propertyNodeForRelativePathTest/jcr:primaryType"); + fail("Should throw RepositoryException when attempting to call Session.getProperty(String) with a relative path"); + } catch (RepositoryException re) { + // Expected + } + } + }