Invoking EJB method from JUnit - "No such EJB method" - java

I'm trying to call a method on a remote EJB in a JUnit test that will run SQL against a DB and return results. Here's the message from the exception:
java.lang.IllegalArgumentException: No such EJB method org.jboss.ejb.client.EJBMethodLocator#3c2f505 found on SiViewDBFacadeEAR-0.0.1-SNAPSHOT/SiViewDBFacadeEJB-0.0.1-SNAPSHOT/SiViewMMDBAccessBean
First of all, this error seems to be intermittent. I have a couple different methods in the EJB that run different SQL and return results as a HashMap. In my JUnit test I was calling these methods back to back and I was noticing that the call to the second method was always failing even if I switched the order of the calls. Just recently I tried calling the exact same method twice and it comes back the first time but fails the second time.
Does this problem signature ring a bell with anyone. I'm somewhat new to working with EJBs but this problem seems strange in its inconsistent nature.
Thanks all.

most common reason for this this error to occur is the EJB is not initialized or not deployed at all to the server that hosts it. Look at the logs on both client and server side to make sure all necessary components are initialized and running.

Related

How to handle classes that need web resources?

I'm making a project in Java where I have a class that on its initialization connects to an API to retrieve some info. Based on that info it then provides several methods to use and analyse it.
But what if the web request fails ? Or if I have some other issue. Every method will now fail because they don't have the info required
What I did is having a boolean named loadInfo, and also a public method didLoadInfo, so that the client knows the state of the object. I also add a reloadInfo method to try to reload all info, and every method throws an exception if they are called when the loadInfo variable is false. That exception is a checked exception.
Is there another better way to handle this situation ? The exception thrown by all the methods should be checked or unchecked ?
EDIT:
Is a good idea to maintain default values, but how would you let the client know that the info returned may not be up to date ? Maybe another boolean indicating the info state ?
I think in this kind of scenarios you should use REST, so that your java components will be running on web server independently.
If you UI is up and running(it could be on angular or react js or html) and have REST calls in place to call java REST API, also you can configure other API in same web project independent of REST classes and will be initialized as soon at web context is loaded( for example if you are using spring, as soon as application context is loaded).
Since you are calling other services to retrieve info, use Netflix Hysytix to handle failure gracefully with a fallback method. Obviously, you have many more options to fallback logic.
Check out the official Hystrix Library here.
If you have time, check out my article on LinkedIn.

Parallel Tests with Jetty and Weld

I want to execute unit tests on an embedded Jetty with CDI/Weld in parallel in the same JVM.
For every test method a new jetty instance with a clean database is created. Execution in sequence works, however, in parallel I'm running into an exception.
org.jboss.weld.exceptions.DefinitionException:
Exception List with 1 exceptions:|Exception 0
:|java.lang.RuntimeException: javax.naming.NameAlreadyBoundException:
com<|?at com.sun.jersey.server.impl.cdi.CDIExtension.initialize(CDIExtension.java:196)
The full stacktrace is at pastebin.
The servers and context are isolated on different jetty server instances and ports. However, Weld does not realize this, although it detects a Jetty container and seems to be using a shared state some place (maybe this is Jetty specific?).
Has anyone come across this problem or has a tip how to tell Weld that it should not register twice?
You could try to fork on every test, so they're all done in different JVMs. It looks like Weld is storing beans per JVM (which makes sense) and when a new server is being started its running through the bootstrap again.

NoSuchEJBException when running maven test

I have a maven client project that i run as maven test. First thing i do in the junit test is a lookup using the jndi string. Here i receive a stateless bean proxy which is cast to a remote interface. As soon as i call a method from the interface (like saving some domain objects wich uses a data access object wich uses jpa) i receive the exception
javax.ejb.NoSuchEJBException: No such EJB[appname=,modulename=someName,distinctname=,beanname=SomeBean]
The documentation says: "A NoSuchEJBException is thrown if an attempt is made to invoke a business method on a stateful session or singleton object that no longer exists". The thing is that the bean is stateless and not stateful or a singleton. I'm also quite sure that the jndi string is correct, because if i make the same lookup and persistence-method-call in the main method of the client project (run as maven build with "install jboss-as:deploy") everything works fine.
Any suggestions how i could use the persistence methods from the proxy when testing? Some colleagues have a similar setup and it works for them without Arquillian or so.
I don't know why but it works now. What I did was removing the getter-method for the EntityManager within the abstract generic DaoBean that all DaoBeans inherit. Having the getter was suddenly shown as an Error while executing the client (it wasn't shown as error before).

Junit test case: Connection refused case

I am writing a Junit(4.x) test to test what happens when the web application is down.
When I hit the url in the browser, I get a message saying "Connection refused".
I am unsure about what to check for in the assert statements.
Do I check the header for this message? -- urlConnection.getResponseMessage() or
just say (expected = java.net.ConnectException) before the test case. I feel the latter is not specific enough.
EDIT: Right now, I'm using a combination of (expected = java.net.ConnectException) and assertEquals(502, urlConnection.getResponseCode). The test is passing.
Thanks,
Pratyusha.
First of all, your unit tests should not depend so much on external entities. What you describe is rather an integration test.
In a classic unit test, you could set up this scenario by using e.g. a mock HttpUrlConnection. This can be programmed to throw an exception from the desired method call. If you are not happy by simply acknowledging the type of exception thrown, you can always catch it within the test method, then assert the response message or whatever you are interested in.
However, from your post it is not clear to me what are you actually testing: a web client which depends on a server? A web app which calls another web app? Different tests may be adequate for different scenarios.
Integration tests in junit are fine. Many widely used open source projects use this approach. See CXF or Arquillian for examples of this approach.
For your question... you need to decide what the desired behaviour is and then test for this.
For example in this case you probably want to test the response code the server is returning. Or if "connection refused" really is desired behaviour then testing for (expected = java.net.ConnectException) should be sufficient.

What is the cause of EJB 2.x "reentrant method call detected" Exceptions? How to solve them?

I'm mantaining a EJB 2 CMP legacy app runing on a JBoss 4.0.4 GA application server with deployed entity/stateless session beans. All the EJB boilerplate code is generated via XDoclet from the EntityEJB/EntityEJBManager annotations.
I've noticed that when my GUI client invokes the facade create method, I have lots of cases of EJBException in my server log with the "Reentrant method call detected" message, which rollbacks the transaction.
What does this Exception means? How can I avoid having such error (which unfortunately, I wasn't able to reproduce yet)
Update: Found this link that explains what is meant by reentrancy, however, seems to me that it says my app cannot be accesed concurrently?
I've seen this before where EJB1 calls EJB2 which calls back to EJB1 within the container as part of the same transaction.
You can tell the container to allow this by marking EJB1 as reentrant which will allow it to be accessed multiple times in the same transaction.
This is done in the deployment descriptor with the following tag:
<reentrant>True</reentrant>
There should be a corresponding EntityEJB annotation that XDoclet can use to generate this for you.
we just came across the same problem and our solution was two-fold. Firstly we ensure that none of ejb's had transaction attributes of NotSupported within our ejb-jar.xml. We then used "instance per transaction" as our optimistic locking strategy. It's a bit of a belt-and-braces approach, but it works
It does mean that the Entity bean in question cannot be accessed concurrently, which makes sense since it would likely corrupt the data.

Categories