NoInitialContextException в CXF Local Transport для тестирования JAX-RS
Я следую этому руководству: https://cwiki.apache.org/confluence/display/CXF20DOC/JAXRS+Testing
Но я получаю эту ошибку:
javax.naming.NoInitialContextException: необходимо указать имя класса в среде или системном свойстве, либо в качестве параметра апплета, либо в файле ресурсов приложения: java.naming.factory.initial
Это мой класс локального сервера:
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");
}
}
И пример клиента:
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());
// ********************************************************************************************************
}
}
}
Наконец, это реализация jax-rs на стороне сервера:
@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();
}
}
Возможно, проблема в том, что локальный транспорт неправильно настроен, что запускает исключение из-за поиска (см.: сторона сервера):
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 ответ
Проблема, скорее всего, связана с тем, что вы запускаете тест в среде Java SE, которая не настроена на сервере JNDI. Если вы запустите свой тест как часть WAR на сервере приложений Java EE, это, вероятно, будет работать нормально.
Таким образом, вам может потребоваться запустить модульный тест на сервере приложений или попытаться смоделировать сервер JNDI, как описано здесь: http://en.newinstance.it/2009/03/27/mocking-jndi/
Надеюсь, это поможет, Энди