JDO-827 Simplify JNDI (#81)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 92d3157..35bb46a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -67,7 +67,6 @@
java-version: ${{ matrix.java }}
# Builds JDO & Runs the TCK
- # Skips JNDI-related tests as they require external libraries
- name: Build JDO & Run TCK
run: |
- mvn -Djdo.tck.skipJndi clean install
+ mvn clean install
diff --git a/README.md b/README.md
index 4db52e4..c8a51c6 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@
Apache JDO releases may be downloaded from [the Apache JDO downloads page](http://db.apache.org/jdo/downloads.html).
Minor updates of releases are only available as source from the GitHub repository.
-Follow the instructions [below](link:#building-the-jdo-api) to build the API from source.
+Follow the instructions [below](#building-the-jdo-api) to build the API from source.
For complete rules for certifying a JDO implementation, see [RunRules.html](https://github.com/apache/db-jdo/blob/main/tck/RunRules.html) in the *tck* project directory.
@@ -61,8 +61,11 @@
### JNDI Implementation (fscontext.jar and providerutil.jar)
-The JNDI test cases in *tck* need a JNDI implementation. The TCK is configured to use Sun's JNDI implementation. To use your own implementation, put the implementation jar files into `lib/ext` and update `jndi.properties` in the TCK directory `src/conf`.
-To download Oracle's implementation, go [here](http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#7110-jndi-1.2.1-oth-JPR). Accept the license agreement and download *File System Service Provider, 1.2 Beta 3* and then unpack the downloaded zip into `lib/ext`. It includes the jars `fscontext.jar` and `providerutil.jar`.
+The JNDI test cases in *tck* need a JNDI implementation. The TCK is configured to use the TCK's own JNDI mock implementation. To use your own implementation, add the dependencies to the TCK's `.pom` or put the implementation jar files directly into `lib/ext`. Then update `jndi.properties` in the TCK directory `src/conf`.
+
+For example, to use Oracle's implementation, go [here](http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#7110-jndi-1.2.1-oth-JPR). Accept the license agreement and download *File System Service Provider, 1.2 Beta 3* and then unpack the downloaded zip into `lib/ext`. It includes the jars `fscontext.jar` and `providerutil.jar`.
+Then update the factory class property in `tck/src/main/resources/conf/jndi.properties`:
+`java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory`.
## Building from Top Level Project
diff --git a/tck/src/main/java/org/apache/jdo/tck/util/jndi/MockContext.java b/tck/src/main/java/org/apache/jdo/tck/util/jndi/MockContext.java
new file mode 100644
index 0000000..3a469a9
--- /dev/null
+++ b/tck/src/main/java/org/apache/jdo/tck/util/jndi/MockContext.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.util.jndi;
+
+import java.util.Hashtable;
+import java.util.Map;
+import javax.naming.*;
+
+public class MockContext implements Context {
+ private final Map<String, Object> map;
+ private boolean isActive = true;
+
+ public MockContext(Map<String, Object> environment) {
+ map = environment;
+ }
+
+ @Override
+ public Object lookup(Name name) throws NamingException {
+ throw new UnsupportedOperationException("lookup(name)");
+ }
+
+ @Override
+ public Object lookup(String name) throws NamingException {
+ assertActive();
+ if (!map.containsKey(name)) {
+ throw new NamingException("lookup(\"" + name + "\")");
+ }
+ return map.get(name);
+ }
+
+ @Override
+ public void bind(Name name, Object obj) throws NamingException {
+ throw new UnsupportedOperationException("bind(name, obj)");
+ }
+
+ @Override
+ public void bind(String name, Object obj) throws NamingException {
+ if (map.containsKey(name)) {
+ throw new NamingException("bind(\"" + name + "\")");
+ }
+ map.put(name, obj);
+ }
+
+ @Override
+ public void rebind(Name name, Object obj) throws NamingException {
+ throw new UnsupportedOperationException("rebind(name, obj)");
+ }
+
+ @Override
+ public void rebind(String name, Object obj) throws NamingException {
+ if (!map.containsKey(name)) {
+ throw new IllegalStateException("rebind(\"" + name + "\")");
+ }
+ map.put(name, obj);
+ }
+
+ @Override
+ public void unbind(Name name) throws NamingException {
+ throw new UnsupportedOperationException("unbind(name)");
+ }
+
+ @Override
+ public void unbind(String name) throws NamingException {
+ map.remove(name);
+ }
+
+ @Override
+ public void rename(Name oldName, Name newName) throws NamingException {
+ throw new UnsupportedOperationException("rename(oldName, newName)");
+ }
+
+ @Override
+ public void rename(String oldName, String newName) throws NamingException {
+ throw new UnsupportedOperationException("rename(oldName, newName)");
+ }
+
+ @Override
+ public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
+ throw new UnsupportedOperationException("list(name)");
+ }
+
+ @Override
+ public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
+ throw new UnsupportedOperationException("list(name)");
+ }
+
+ @Override
+ public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
+ throw new UnsupportedOperationException("listBindings(name)");
+ }
+
+ @Override
+ public NamingEnumeration<Binding> listBindings(String name) throws NamingException {
+ throw new UnsupportedOperationException("listBindings(name)");
+ }
+
+ @Override
+ public void destroySubcontext(Name name) throws NamingException {
+ throw new UnsupportedOperationException("destroySubcontext(name)");
+ }
+
+ @Override
+ public void destroySubcontext(String name) throws NamingException {
+ throw new UnsupportedOperationException("destroySubcontext(name)");
+ }
+
+ @Override
+ public Context createSubcontext(Name name) throws NamingException {
+ throw new UnsupportedOperationException("createSubcontext(name)");
+ }
+
+ @Override
+ public Context createSubcontext(String name) throws NamingException {
+ throw new UnsupportedOperationException("createSubcontext(name)");
+ }
+
+ @Override
+ public Object lookupLink(Name name) throws NamingException {
+ throw new UnsupportedOperationException("lookupLink(name)");
+ }
+
+ @Override
+ public Object lookupLink(String name) throws NamingException {
+ throw new UnsupportedOperationException("lookupLink(name)");
+ }
+
+ @Override
+ public NameParser getNameParser(Name name) throws NamingException {
+ throw new UnsupportedOperationException("getNameParser(name)");
+ }
+
+ @Override
+ public NameParser getNameParser(String name) throws NamingException {
+ throw new UnsupportedOperationException("getNameParser(name)");
+ }
+
+ @Override
+ public Name composeName(Name name, Name prefix) throws NamingException {
+ throw new UnsupportedOperationException("composeName(name, prefix)");
+ }
+
+ @Override
+ public String composeName(String name, String prefix) throws NamingException {
+ throw new UnsupportedOperationException("composeName(name, prefix)");
+ }
+
+ @Override
+ public Object addToEnvironment(String propName, Object propVal) throws NamingException {
+ throw new UnsupportedOperationException("addToEnvironment(propName, propVal):");
+ }
+
+ @Override
+ public Object removeFromEnvironment(String propName) throws NamingException {
+ throw new UnsupportedOperationException("removeFromEnvironment(propName)");
+ }
+
+ @Override
+ public Hashtable<?, ?> getEnvironment() throws NamingException {
+ throw new UnsupportedOperationException("getEnvironment()");
+ }
+
+ @Override
+ public void close() throws NamingException {
+ isActive = false;
+ }
+
+ @Override
+ public String getNameInNamespace() throws NamingException {
+ throw new UnsupportedOperationException("getNameInNamespace()");
+ }
+
+ private void assertActive() throws NamingException {
+ if (!isActive) {
+ throw new NamingException("This context has already been closed.");
+ }
+ }
+}
diff --git a/tck/src/main/java/org/apache/jdo/tck/util/jndi/MockContextFactory.java b/tck/src/main/java/org/apache/jdo/tck/util/jndi/MockContextFactory.java
new file mode 100644
index 0000000..edf3482
--- /dev/null
+++ b/tck/src/main/java/org/apache/jdo/tck/util/jndi/MockContextFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jdo.tck.util.jndi;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+
+public class MockContextFactory implements InitialContextFactory {
+
+ @Override
+ public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
+ HashMap<String, Object> map = new HashMap<>();
+ environment.forEach((key, value) -> map.put((String) key, value));
+ return new MockContext(map);
+ }
+}
diff --git a/tck/src/main/resources/conf/jndi.properties b/tck/src/main/resources/conf/jndi.properties
index 91179f3..e290158 100644
--- a/tck/src/main/resources/conf/jndi.properties
+++ b/tck/src/main/resources/conf/jndi.properties
@@ -14,4 +14,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
+# This is the factory name for Oracle's full JNDI implementation that was used
+# previously in the TCK.
+# java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
+
+java.naming.factory.initial=org.apache.jdo.tck.util.jndi.MockContextFactory