JUnit test with javax.websocket on embedded Jetty throws RejectedExecutionException: NonBlockingThread - junit

I'm trying to write a test case which creates a socket and connects to an embedded jetty instance. I'm using
Jetty: 9.2.0.RC0
javax.websocket-api & javax.websocket-client-api: 1.0
javax.websocket server & client impl: 9.1.5.v20140505
Starting the embedded jetty server with the websocket servlet seems to work fine. I took some code from this example. However this line
...
container.connectToServer(SocketClient.class, uri);
...
throws this exception
java.io.IOException: java.util.concurrent.RejectedExecutionException: org.eclipse.jetty.util.thread.NonBlockingThread#6f7476d
at org.eclipse.jetty.websocket.client.WebSocketClient.initialiseClient(WebSocketClient.java:462)
at org.eclipse.jetty.websocket.client.WebSocketClient.connect(WebSocketClient.java:187)
at org.eclipse.jetty.websocket.jsr356.ClientContainer.connect(ClientContainer.java:135)
at org.eclipse.jetty.websocket.jsr356.ClientContainer.connectToServer(ClientContainer.java:172)
at com.playquickly.socket.SocketClient.connect(SocketClient.java:18)
at com.playquickly.servlet.SocketServletTest.testSocket(SocketServletTest.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
Caused by: java.util.concurrent.RejectedExecutionException: org.eclipse.jetty.util.thread.NonBlockingThread#6f7476d
at org.eclipse.jetty.util.thread.QueuedThreadPool.execute(QueuedThreadPool.java:361)
at org.eclipse.jetty.io.SelectorManager.execute(SelectorManager.java:122)
at org.eclipse.jetty.io.SelectorManager.doStart(SelectorManager.java:207)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.websocket.client.io.ConnectionManager.doStart(ConnectionManager.java:200)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.websocket.client.WebSocketClient.initialiseClient(WebSocketClient.java:454)
... 30 more
This is my wrapper for stating the embedded jetty server.
public class EmbeddedJetty {
private final Logger LOG = Logger.getLogger(EmbeddedJetty.class.getSimpleName());
private final int port;
private Server server;
public EmbeddedJetty(int port) {
this.port = port;
}
public void start() throws Exception {
server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
server.addConnector(connector);
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
try {
// Initialize javax.websocket layer
ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
// Add WebSocket endpoint to javax.websocket layer
wscontainer.addEndpoint(SocketServlet.class);
System.out.println("Begin start");
server.start();
System.out.println("End start");
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
public void stop() throws Exception {
server.stop();
LOG.info("Jetty server stopped");
}
}
The client endpoint
#ClientEndpoint(encoders = {MessageCoder.class}, decoders = {MessageCoder.class})
public class SocketClient {
public static Session connect(URI uri) throws Exception {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
try {
// Attempt Connect
return container.connectToServer(SocketClient.class, uri);
} finally {
// Force lifecycle stop when done with container.
// This is to free up threads and resources that the
// JSR-356 container allocates. But unfortunately
// the JSR-356 spec does not handle lifecycles (yet)
if (container instanceof LifeCycle) {
((LifeCycle) container).stop();
}
}
}
#OnMessage
public void onMessage(Message msg, Session session) {
System.out.println(session.getId() + ": " + msg.toString());
}
}
And the test
public class SocketServletTest {
private static EmbeddedJetty server;
#ClassRule
public static final ExternalResource integrationServer = new ExternalResource() {
#Override
protected void before() throws Throwable {
System.out.println("Starting...");
server = new EmbeddedJetty(8080);
server.start();
System.out.println("Started");
}
};
#Before
public void setUp() throws Exception {
}
#After
public void shutdown() throws Exception {
server.stop();
}
#Test
public void testSocket() throws Exception {
URI uri = server.getWebsocketUri(SocketServlet.class);
Session s1 = SocketClient.connect(uri);
}
}

Don't mix versions of Jetty.
This is an unfortunate side effect of the design of the JSR-356 API.
(The Client implementation is the root implementation, and the Server implementation is built on top of that)
The Client container is initialized per JVM, and each server container is initialized per webapp.
Your stacktrace is not Jetty 9.2.0.RC0 as you indicated (the line numbers are off)
https://github.com/eclipse/jetty.project/blob/jetty-9.2.0.RC0/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java#L200
They seem to be from Jetty 9.1.5.v20140505
https://github.com/eclipse/jetty.project/blob/jetty-9.1.5.v20140505/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java#L200
Use Jetty 9.2.2.v20140723 everywhere.
Also, using this version means you can get rid of the finally container.stop() hack.

Related

How Do I Verify and Capture the Contents of an InputStream in JUnit Mockito?

I have the following setup:
public interface CommandRunner
{
void run(String cmd, InputStream is) throws IOException;
}
public class CommandRunnerInputFile
{
private final CommandRunner commandRunner;
public CommandRunnerInputFile(CommandRunner commandRunner) {
this.commandRunner = commandRunner;
}
public void run(String command, File inputFile) throws IOException {
try (FileInputStream is = new FileInputStream(inputFile)) {
this.commandRunner.run(command, is);
}
}
}
#ExtendWith(MockitoExtension.class)
public class TestCommandRunnerInputFile
{
#Mock CommandRunner commandRunner;
#Captor ArgumentCaptor<InputStream> inputStream;
private CommandRunnerInputFile commandRunnerInputFile;
#BeforeEach
void initService() {
commandRunnerInputFile = new CommandRunnerInputFile(commandRunner);
}
#Test
public void testHappyPath() throws IOException {
ClassLoader classLoader = this.getClass().getClassLoader();
File file = new File(classLoader.getResource("MyTestInputFile.txt").getFile());
commandRunnerInputFile .run("MyApplication.exe", file);
verify(commandRunner).run(eq("MyApplication.exe"), inputStream.capture());
assertEquals('c', (char)inputStream.getValue().read());
}
}
When I run this test, it fails with the following Exception:
java.io.IOException: Stream Closed
at java.io.FileInputStream.read0(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:207)
This make sense to me since, during the execution of the method, the underlying FileInputStream is closed when it has completed execution. That is to say, at the point in time that the FileInputStream is captured by Mockito, it is open, but by the time I verify that it was passed (and attempt to verify its contents) it is closed. What can I do not to simply capture the InputStream object itself, but actually capture its contents for verification?

Apache Flink: Could not extract key from ObjectNode::get

I'm using Flink to process the data coming from some data source (such as Kafka, Pravega etc).
In my case, the data source is Pravega, which provided me a flink connector.
My data source is sending me some JSON data as below:
{"device":"rand-numeric","id":"b4728895-741f-466a-b87b-79c7590893b4","origin":"1591095418904441036","readings":[{"origin":"1591095418904328442","valueType":"Int64","name":"int","device":"rand-numeric","value":"0"}]}
Here is my piece of code:
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.node.ObjectNode;
PravegaDeserializationSchema<ObjectNode> adapter = new PravegaDeserializationSchema<>(ObjectNode.class, new JavaSerializer<>());
FlinkPravegaReader<ObjectNode> source = FlinkPravegaReader.<ObjectNode>builder()
.withPravegaConfig(pravegaConfig)
.forStream(stream)
.withDeserializationSchema(adapter)
.build();
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<ObjectNode> dataStream = env.addSource(source).name("Pravega Stream");
dataStream.keyBy(new KeySelector<ObjectNode, String>() {
#Override
public String getKey(ObjectNode node) throws Exception {
return node.get("id").asText();
}
}).print();
env.execute("StreamingJob");
As you see, I used the FlinkPravegaReader and a proper deserializer to get the JSON stream coming from Pravega.
Then I try to KeyBy it with a custom KeySelector and print it.
However, I get an error:
Caused by: java.lang.RuntimeException: Could not extract key from
{"device":"rand-numeric","id":"b4728895-741f-466a-b87b-79c7590893b4","origin":"1591095418904441036","readings":[{"origin":"1591095418904328442","valueType":"Int64","name":"int","device":"rand-numeric","value":"0"}]}
It seems that node.get("id").asText(); threw this exception.
I don't know why. As we see there does exist a key named id in the JSON data. Why can't it be extracted? Have I used the class ObjectNode wrongly or some other reason?
Stack-trace:
org.apache.flink.client.program.ProgramInvocationException: The main method caused an error: org.apache.flink.client.program.ProgramInvocationException: Job failed (JobID: fa9846e6834ae1391acbf51d5ad35aac)
at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:335)
at org.apache.flink.client.program.PackagedProgram.invokeInteractiveModeForExecution(PackagedProgram.java:205)
at org.apache.flink.client.ClientUtils.executeProgram(ClientUtils.java:138)
at org.apache.flink.client.cli.CliFrontend.executeProgram(CliFrontend.java:662)
at org.apache.flink.client.cli.CliFrontend.run(CliFrontend.java:210)
at org.apache.flink.client.cli.CliFrontend.parseParameters(CliFrontend.java:893)
at org.apache.flink.client.cli.CliFrontend.lambda$main$10(CliFrontend.java:966)
at org.apache.flink.runtime.security.NoOpSecurityContext.runSecured(NoOpSecurityContext.java:30)
at org.apache.flink.client.cli.CliFrontend.main(CliFrontend.java:966)
Caused by: java.util.concurrent.ExecutionException: org.apache.flink.client.program.ProgramInvocationException: Job failed (JobID: fa9846e6834ae1391acbf51d5ad35aac)
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908)
at org.apache.flink.streaming.api.environment.StreamContextEnvironment.execute(StreamContextEnvironment.java:83)
at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.execute(StreamExecutionEnvironment.java:1620)
at myflink.StreamingJob.main(StreamingJob.java:137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:321)
... 8 more
Caused by: org.apache.flink.client.program.ProgramInvocationException: Job failed (JobID: fa9846e6834ae1391acbf51d5ad35aac)
at org.apache.flink.client.deployment.ClusterClientJobClientAdapter.lambda$null$6(ClusterClientJobClientAdapter.java:112)
at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:616)
at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:591)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1975)
at org.apache.flink.client.program.rest.RestClusterClient.lambda$pollResourceAsync$21(RestClusterClient.java:565)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1975)
at org.apache.flink.runtime.concurrent.FutureUtils.lambda$retryOperationWithDelay$8(FutureUtils.java:291)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.postFire(CompletableFuture.java:575)
at java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:943)
at java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.flink.runtime.client.JobExecutionException: Job execution failed.
at org.apache.flink.runtime.jobmaster.JobResult.toJobExecutionResult(JobResult.java:147)
at org.apache.flink.client.deployment.ClusterClientJobClientAdapter.lambda$null$6(ClusterClientJobClientAdapter.java:110)
... 19 more
Caused by: org.apache.flink.runtime.JobException: Recovery is suppressed by NoRestartBackoffTimeStrategy
at org.apache.flink.runtime.executiongraph.failover.flip1.ExecutionFailureHandler.handleFailure(ExecutionFailureHandler.java:110)
at org.apache.flink.runtime.executiongraph.failover.flip1.ExecutionFailureHandler.getFailureHandlingResult(ExecutionFailureHandler.java:76)
at org.apache.flink.runtime.scheduler.DefaultScheduler.handleTaskFailure(DefaultScheduler.java:192)
at org.apache.flink.runtime.scheduler.DefaultScheduler.maybeHandleTaskFailure(DefaultScheduler.java:186)
at org.apache.flink.runtime.scheduler.DefaultScheduler.updateTaskExecutionStateInternal(DefaultScheduler.java:180)
at org.apache.flink.runtime.scheduler.SchedulerBase.updateTaskExecutionState(SchedulerBase.java:496)
at org.apache.flink.runtime.jobmaster.JobMaster.updateTaskExecutionState(JobMaster.java:380)
at sun.reflect.GeneratedMethodAccessor77.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.flink.runtime.rpc.akka.AkkaRpcActor.handleRpcInvocation(AkkaRpcActor.java:284)
at org.apache.flink.runtime.rpc.akka.AkkaRpcActor.handleRpcMessage(AkkaRpcActor.java:199)
at org.apache.flink.runtime.rpc.akka.FencedAkkaRpcActor.handleRpcMessage(FencedAkkaRpcActor.java:74)
at org.apache.flink.runtime.rpc.akka.AkkaRpcActor.handleMessage(AkkaRpcActor.java:152)
at akka.japi.pf.UnitCaseStatement.apply(CaseStatements.scala:26)
at akka.japi.pf.UnitCaseStatement.apply(CaseStatements.scala:21)
at scala.PartialFunction.applyOrElse(PartialFunction.scala:123)
at scala.PartialFunction.applyOrElse$(PartialFunction.scala:122)
at akka.japi.pf.UnitCaseStatement.applyOrElse(CaseStatements.scala:21)
at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:171)
at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:172)
at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:172)
at akka.actor.Actor.aroundReceive(Actor.scala:517)
at akka.actor.Actor.aroundReceive$(Actor.scala:515)
at akka.actor.AbstractActor.aroundReceive(AbstractActor.scala:225)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:592)
at akka.actor.ActorCell.invoke(ActorCell.scala:561)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:258)
at akka.dispatch.Mailbox.run(Mailbox.scala:225)
at akka.dispatch.Mailbox.exec(Mailbox.scala:235)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.lang.RuntimeException: Could not extract key from {"device":"rand-numeric","id":"b4728895-741f-466a-b87b-79c7590893b4","origin":"1591095418904441036","readings":[{"origin":"1591095418904328442","valueType":"Int64","name":"int","device":"rand-numeric","value":"0"}]}
at org.apache.flink.streaming.runtime.io.RecordWriterOutput.pushToRecordWriter(RecordWriterOutput.java:110)
at org.apache.flink.streaming.runtime.io.RecordWriterOutput.collect(RecordWriterOutput.java:89)
at org.apache.flink.streaming.runtime.io.RecordWriterOutput.collect(RecordWriterOutput.java:45)
at org.apache.flink.streaming.api.operators.AbstractStreamOperator$CountingOutput.collect(AbstractStreamOperator.java:730)
at org.apache.flink.streaming.api.operators.AbstractStreamOperator$CountingOutput.collect(AbstractStreamOperator.java:708)
at org.apache.flink.streaming.api.operators.StreamSourceContexts$NonTimestampContext.collect(StreamSourceContexts.java:104)
at io.pravega.connectors.flink.FlinkPravegaReader.run(FlinkPravegaReader.java:307)
at org.apache.flink.streaming.api.operators.StreamSource.run(StreamSource.java:100)
at org.apache.flink.streaming.api.operators.StreamSource.run(StreamSource.java:63)
at org.apache.flink.streaming.runtime.tasks.SourceStreamTask$LegacySourceFunctionThread.run(SourceStreamTask.java:200)
Caused by: java.lang.RuntimeException: Could not extract key from {"device":"rand-numeric","id":"b4728895-741f-466a-b87b-79c7590893b4","origin":"1591095418904441036","readings":[{"origin":"1591095418904328442","valueType":"Int64","name":"int","device":"rand-numeric","value":"0"}]}
at org.apache.flink.streaming.runtime.partitioner.KeyGroupStreamPartitioner.selectChannel(KeyGroupStreamPartitioner.java:56)
at org.apache.flink.streaming.runtime.partitioner.KeyGroupStreamPartitioner.selectChannel(KeyGroupStreamPartitioner.java:32)
at org.apache.flink.runtime.io.network.api.writer.ChannelSelectorRecordWriter.emit(ChannelSelectorRecordWriter.java:60)
at org.apache.flink.streaming.runtime.io.RecordWriterOutput.pushToRecordWriter(RecordWriterOutput.java:107)
... 9 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.node.ObjectNode
at myflink.StreamingJob$1.getKey(StreamingJob.java:125)
at org.apache.flink.streaming.runtime.partitioner.KeyGroupStreamPartitioner.selectChannel(KeyGroupStreamPartitioner.java:54)
... 12 more
You can check the rules for POJO types here.
Rules for POJO types
By using POJO types, Flink can infer a lot of information about the data types that are exchanged and stored during the distributed computation.
The following codes define POJOs for you input.
public class FlinkPOJO {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(3);
DataStream<String> source =
env.addSource(new SourceFunction<String>() {
#Override
public void run(SourceContext<String> sourceContext) throws Exception {
while (true) {
sourceContext.collect("{\"device\":\"rand-numeric\",\"id\":\"b4728895-741f-466a-b87b-79c7590893b4\",\"origin\":\"1591095418904441036\",\"readings\":[{\"origin\":\"1591095418904328442\",\"valueType\":\"Int64\",\"name\":\"int\",\"device\":\"rand-numeric\",\"value\":\"0\"}]}");
Thread.sleep(1000);
}
}
#Override
public void cancel() {
}
});
DataStream<Info> parsedSource =
source.map(new MapFunction<String, Info>() {
#Override
public Info map(String s) throws Exception {
Gson gson = new Gson();
return gson.fromJson(s, Info.class);
}
});
DataStream<String> output = parsedSource.keyBy(Info::getId).timeWindow(Time.seconds(1))
.process(new ProcessWindowFunction<Info, String, String, TimeWindow>() {
#Override
public void process(String s, Context context, Iterable<Info> iterable, Collector<String> collector) throws Exception {
int count = 0;
Iterator<Info> iterator = iterable.iterator();
while (iterator.hasNext()) {
count++;
iterator.next();
}
collector.collect(String.format("key : %s, size : %s", s, count));
}
});
output.print();
env.execute();
}
public class Info {
public String getDevice() {
return device;
}
public void setDevice(String device) {
this.device = device;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public Reading[] getReadings() {
return readings;
}
public void setReadings(Reading[] readings) {
this.readings = readings;
}
public String device;
public String id;
public String origin;
public Reading[] readings;
public Info() {
}
}
public class Reading {
public String origin;
public String valueType;
public String name;
public String device;
public String value;
public Reading() {
}
}
}
Actually, you can define a brief POJO which only contains the fields you need.

Mock a jUnit test using powermockito

I am trying to mock the following functionality
public class ServerConnection{
public ServerConnection(ClientConnection cn) {
super(cn);
}
public void setUrl(String url) {
this.url = URLUtil.processURL(url);
try {
URL dst = new URL(this.url);
InputStream is = dst.openStream();
Scanner scanner = new Scanner(is);
StringBuilder sb = new StringBuilder();
while(scanner.hasNextLine())
sb.append(scanner.nextLine()).append("\n");
if (validate(sb.toString())) {
--------
} else { }
is.close();
scanner.close();
} catch (Exception ex) {
}
}
private boolean validate(String content) {
JSONParser parser = new JSONParser();
Boolean isJsonValid = false;
JSONObject json = null;
try {
--------
//json validation goes here
} catch (Exception e) {
}
return isJsonValid;
}
public void setId(Integer id) {
if(id == null)
this.id = 0;
else
this.id = id;
}
}
PowerMockito Junit code
#RunWith(PowerMockRunner.class)
#PrepareForTest({PathTest.class })
public class URLTest {
ServerConnection sc ;
String URL = "http://test.com";
#Before
public void setUp() throws Throwable{
ClientConnection con =PathTest.getCon(); // Here getCon() is a static method
sc = new ServerConnection(con);
sc.setId(1000);
}
#Test
public void testName() throws Throwable {
String expectedResponse = "test";
URL url = PowerMockito.mock(URL.class);
HttpURLConnection connection = PowerMockito.mock(HttpURLConnection.class);
InputStream inputStream = PowerMockito.mock(InputStream.class);
Scanner scanner = PowerMockito.mock(Scanner.class);
PowerMockito.whenNew(URL.class).withArguments(URL).thenReturn(url);
PowerMockito.whenNew(Scanner.class).withArguments(inputStream).thenReturn(scanner);
PowerMockito.when(scanner.useDelimiter("\\A")).thenReturn(scanner);
PowerMockito.when(url.openConnection()).thenReturn(connection);
// Response code mocked here
PowerMockito.when(connection.getResponseCode()).thenReturn(200);
PowerMockito.when(connection.getInputStream()).thenReturn(inputStream);
PowerMockito.when(scanner.hasNext()).thenReturn(true);
PowerMockito.when(scanner.next()).thenReturn(expectedResponse);
sc.setUrl(URL);
}
}
While Iam executing this I observed following error message
URLTest
com.objects.URLTest
testName(com.objects.URLTest)
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at javassist.runtime.Desc.getClassObject(Desc.java:43)
at javassist.runtime.Desc.getClassType(Desc.java:152)
at javassist.runtime.Desc.getType(Desc.java:122)
at javassist.runtime.Desc.getType(Desc.java:78)
at com.objects.PathTest.getCon(TargetPathTest.java:24)
at com.objects.URLTest.setUp(URLTest.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:133)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:298)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:218)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:160)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:134)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:136)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NullPointerException
... 38 more
So many things wrong with this code.
The first technical answer is: you seem to not know what you are doing. You have #PrepareForTest({PathTest.class }) which indicates that you intend to mock a static method of that class.
But then you aren't doing what is necessary to mock a static method in that class. Simply follow their documentation step by step. I also think that the URL class is final, so you would have to prepare-annotate that class as well, in order for it be used with whenNew()!
But then: you should avoid mocking URL or URL connection objects. Simply use some sort of dependency injection, and make sure you can pass some mocked instance into your code under test, for example using the #InjectMocks annotation of Mockito. From there, you might also avoid using a static method.
Long story short: your production code is badly written, and your unit test is (honestly) plain horrible. You should seriously step back here, and throw that stuff away. Then re-think your production code to not use new directly, and to not rely on static methods. By doing so, you can get rid of PowerMockito, you go with ordinary Mockito (well, you need to enable mocking of final classes). But rest assured: there is no point in using PowerMock(ito) unless you absolutely have to.
And then: don't "invent" mocking code. Read tutorials, and follow them step by step. You are mocking like everything in your test case, but you should do the exact opposite: you only mock things when there is absolutely no other way to test your code. And you absolutely do not make a method static when that breaks your ability to reasonably unit test your code.
( static has its place, but when it gets in your way, you are doing the wrong thing ! )

running antlr inside a javafx and swing app

I have built a gui with javafx and swing and when I add an action listener to parse the expression in a textfield I get a error, I am not sure what the problem is.
the error is:
Exception in thread "AWT-EventQueue-0" java.lang.ExceptionInInitializerError
at functionparsergui.Test.parseFunction(Test.java:110)
at functionparsergui.Test.access$000(Test.java:38)
at functionparsergui.Test$2.actionPerformed(Test.java:88)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:702)
at java.awt.EventQueue$4.run(EventQueue.java:700)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Caused by: java.lang.UnsupportedOperationException: java.io.InvalidClassException: org.antlr.v4.runtime.atn.ATN; Could not deserialize ATN with version 3 (expected 2).
at org.antlr.v4.runtime.atn.ATNSimulator.deserialize(ATNSimulator.java:114)
at edu.chrr.util.function.FunctionLexer.<clinit>(FunctionLexer.java:504)
... 39 more
Caused by: java.io.InvalidClassException: org.antlr.v4.runtime.atn.ATN; Could not deserialize ATN with version 3 (expected 2).
... 41 more
My code starting from declaring the actionlistener is as follows:
ActionListener clearField = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
exprField.setText("");
JOptionPane.showMessageDialog(frame, "Input Cleared");
}
};
clearButton.addActionListener(clearField);
ActionListener parserButton;
parserButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String expression = exprField.getText();
String nowhiteExpr = expression.replaceAll("\\s+", "");
parseFunction(nowhiteExpr, frame);
}
};
parseButton.addActionListener(parserButton);
Platform.runLater(new Runnable() {
#Override
public void run() {
initFX(fxPanel);
}
});
}
private static void parseFunction(final String function, final JFrame frame) {
try {
ANTLRInputStream input = new ANTLRInputStream(function);
FunctionLexer lexer = new FunctionLexer(input);
CommonTokenStream tokens = new CommonTokenStream((TokenSource) lexer);
FunctionParser parser = new FunctionParser(tokens);
parser.start();
int errorsCount = parser.getNumberOfSyntaxErrors();
if (errorsCount == 0) {
JOptionPane.showMessageDialog(frame, "Syntax is Correct");
} else {
Token t = parser.getCurrentToken();
String msg = "Syntax Incorrect: Missing " + t.getText();
JOptionPane.showMessageDialog(frame, msg);
}
} catch (RecognitionException ex) {
JOptionPane.showMessageDialog(frame, "Syntax is Incorrect");
}
}
private static void initFX(JFXPanel fxPanel) {
// This method is invoked on the JavaFX thread
Scene scene = createScene();
fxPanel.setScene(scene);
}
private static Scene createScene() {
Group root = new Group();
Scene scene = new Scene(root, Color.ALICEBLUE);
return (scene);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
initAndShowGUI();
}
});
}
}
ANTLR 4.1 is not compatible with ANTLR 4.0. You are generating your code with ANTLR 4.1 but attempting to run it with the ANTLR 4.0 runtime library.

How to load a configuration file at startup within tomcat

I want to be able to load my configuration for the webapp at startup of tomcat (apache commons configuration library) is this a possible way:
public class MyAppCfg implements javax.servlet.ServletContextListener {
private ServletContext context = null;
#Override
public void contextInitialized(ServletContextEvent event) {
try{
this.context = event.getServletContext();
XMLConfiguration config = new XMLConfiguration("cfg.xml");
config.setReloadingStrategy(new FileChangedReloadingStrategy());
this.context.setAttribute("mycfg", config);
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
this.context = null;
}
}
web.xml
<listener>
<listener-class>mypackage.MyAppCfg</listener-class>
</listener>
and later acces them in the webapp via
this.cfg = (XMLConfiguration) servletRequest.getAttribute("mycfg");
No. You wouldn't be able to get the configuration this way. You are setting it in servlet context but retrieving it in request context.
You need to retrieve the cfg in your Servlet init like this,
public void init(final ServletConfig config) {
// log it to the ServletContext
ServletContext context = config.getServletContext();
this.cfg = (Configuration)context.getAttribute("mycfg");
}