NoInitialContextException in CXF Local Transport for testing the JAX-RS

142 views Asked by At

I am following this tutorial: https://cwiki.apache.org/confluence/display/CXF20DOC/JAXRS+Testing

But I get this error:

javax.naming.NoInitialContextException:Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial

This is my local server class:

public class CXFLocalTransportTestSuite {

    public static final Logger LOGGER = LogManager.getLogger();

    public static final String ENDPOINT_ADDRESS = "local://service0";   

    private static Server server;

    @BeforeClass
    public static void initialize() throws Exception {

        startServer();
    }

    private static void startServer() throws Exception {

        JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();

        factory.setAddress(ENDPOINT_ADDRESS);

        List<Class<?>> resourceClasses = new ArrayList<Class<?>>();
        resourceClasses.add(CommunicationWSRESTImpl.class);

        factory.setResourceClasses(resourceClasses);

        List<ResourceProvider> resourceProviders = new ArrayList<>();
        resourceProviders.add(new SingletonResourceProvider(new CommunicationWSRESTImpl()));

        factory.setResourceProviders(resourceProviders);

        List<Object> providers = new ArrayList<Object>();
        providers.add(new JacksonJaxbJsonProvider());
        providers.add(new ApiOriginFilter());
        providers.add(new AuthenticationFilter());
        providers.add(new AuthorizationFilter());

        factory.setProviders(providers);

        server = factory.create();

        server.start();

        LOGGER.info("LOCAL TRANSPORT STARTED");
    }

    @AfterClass
    public static void destroy() throws Exception {

        server.stop();

        server.destroy();

        LOGGER.info("LOCAL TRANSPORT STOPPED");
    }
}

And a client example:

public class CommunicationApiTest {

    // [PUBLIC PROFILE]
    // --------------------------------------------------------------------------------------------------------

    @Test
    public void getLinkedComponentsTest() {

        // PATH. PARAM.
        // ********************************************************************************************************
        String userId = "1";
        String componentInstance = "a3449197-cc72-49eb-bc14-5d43a80dfa80";
        String portId = "00";
        // ********************************************************************************************************

        WebClient client = WebClient.create(CXFLocalTransportTestSuite.ENDPOINT_ADDRESS);
        client.path("/communication/getLinkedComponents/{userId}-{componentInstance}-{portId}", userId, componentInstance, portId);

        client.header("Authorization", "Bearer " + CXFLocalTransportTestSuite.authenticationTokenPublicProfile);

        Response res = client.get();

        if (null != res) {

            assertEquals(StatusCode.SUCCESSFUL_OPERATION.getStatusCode(), res.getStatus());

            assertNotNull(res.getEntity());

            // VALID RESPONSE
            // ********************************************************************************************************
            assertEquals("> Modules has not been initialized for userID = 1", res.readEntity(GetLinksResult.class).getMessage());
            // ********************************************************************************************************
        }

    }
}

Finally, this is the jax-rs implementation on the server side:

@Path("/communication")
public class CommunicationWSRESTImpl implements CommunicationWS {

    @Path("/getLinkedComponents/{userId}-{componentInstance}-{portId}")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getLinkedComponents(
            @HeaderParam("Authorization") String accessToken,
            @PathParam("userId") String userId,
            @PathParam("componentInstance") String componentInstance,
            @PathParam("portId") String portId) {

        LOGGER.info("[CommunicationWSREST - getLinksComponents] userId: " + userId + " -- componentInstace: "
                + componentInstance + " -- portId: " + portId);

        GetLinksResult result = new GetLinksResult();
        result.setGotten(false);
        result.setPortList(null);

        if (userId != null && userId.compareTo("") != 0) {
            if (componentInstance != null && componentInstance.compareTo("") != 0) {
                if (portId != null && portId.compareTo("") != 0) {

                    TMM tmm = null;
                    javax.naming.Context initialContext;

                    try {
                        initialContext = new InitialContext();
                        tmm = (TMM) initialContext.lookup("java:app/cos/TMM");

                        result = tmm.calculateConnectedPorts(userId, componentInstance, portId);

                    } catch (Exception e) {
                        LOGGER.error(e);
                        result.setMessage("> Internal Server Error");
                        return Response.status(Status.INTERNAL_SERVER_ERROR).entity(result).build();
                    }
                } else {
                    LOGGER.error("Not found or Empty Port Error");
                    result.setMessage("> Not found or Empty Port Error");
                    return Response.status(Status.NOT_FOUND).entity(result).build();
                }
            } else {
                LOGGER.error("Not found or Empty Component Instance Error");
                result.setMessage("> Not found or Empty Component Instance Error");
                return Response.status(Status.NOT_FOUND).entity(result).build();
            }
        } else {
            LOGGER.error("Not found or Empty userid Error");
            result.setMessage("> Not found or Empty username Error");
            return Response.status(Status.NOT_FOUND).entity(result).build();
        }
        return Response.ok(result).build();
    }
}

Maybe the problem is the local transport is not correctly configured what launches the exception because of the lookup (see: server side):

    TMM tmm = null;
    javax.naming.Context initialContext;

    try {
        initialContext = new InitialContext();
        tmm = (TMM) initialContext.lookup("java:app/cos/TMM");

        result = tmm.calculateConnectedPorts(userId, componentInstance, portId);

    } catch (Exception e) {

..

1

There are 1 answers

0
Andy McCright On

The problem is most likely because you are running your test in a Java SE environment that is not configured with a JNDI server. If you run your test as part of a WAR inside a Java EE app server, this would probably work just fine.

So you might need to either run your unit test inside an app server or you could try mocking a JNDI server like what is described here: http://en.newinstance.it/2009/03/27/mocking-jndi/#

Hope this helps, Andy