I'm following an online guide to learn EJB. Before the introdution of Singleton (@ConcurrencyManagement, @Lock, and so on) everything worked perfectly, testing by JUnit Test. When I start to use singleton, I discovered, during the testing, thet JNDI gived an error about ClassNotFoundException. I searched on internet but I didn't solve it. Thus I decided to reboot my pc, after that previously junit test about the previously WORKING methods, not works! And now they give me the same error: ClassNotFoundException. I use wildfly9
JunitTest:
package it.html.progetto1.test;
import java.util.Properties;
import javax.naming.*;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import it.html.progetto1.ejb30.ConverterBeanRemote;
import it.html.progetto1.singleton.ejb32.NewsSingleton;
import it.html.progetto1.singleton.ejb32.NewsSingletonRemote;
import it.html.progetto1.stateful.ejb32.ShoppingCartRemote;
import junit.framework.TestCase;
public class IntegrationTestCase {
private static Context namingContext;
private static ConverterBeanRemote converteBeanRemote;
private static ShoppingCartRemote<String> shoppingCartRemote;
private static NewsSingleton<String> newsSingletonRemote;
private static final String CONVERTER_REMOTE_JNDI_NAME="/Progetto1Ear/ProgettoEjb1/ConverterBean!it.html.progetto1.ejb30.ConverterBeanRemote";
private static final String SHOPPING_CART_REMOTE_JNDI_NAME="/Progetto1Ear/ProgettoEjb1/ShoppingCartBean!it.html.progetto1.stateful.ejb32.ShoppingCartRemote";
private static final String SINGLETON_REMOTE_JNDI_NAME="/Progetto1Ear/ProgettoEjb1/NewsSingletonBean!it.html.progetto1.singleton.ejb32.NewsSingletonRemote";
@BeforeClass
public static void obtainProxyReferences() throws NamingException{
Properties jndiProperties = new Properties();
jndiProperties.put("jboss.naming.client.ejb.context", true);
jndiProperties.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080");
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
namingContext = new InitialContext(jndiProperties);
}
@Test
public void testConverter() throws NamingException{
converteBeanRemote = (ConverterBeanRemote)namingContext.lookup(CONVERTER_REMOTE_JNDI_NAME);
TestCase.assertEquals(converteBeanRemote.celsiusToFahrenheit(30.0f), 86.0f);
TestCase.assertEquals(converteBeanRemote.fahrenheitToCelsius(86.0f), 30.0f);
}
@SuppressWarnings("unchecked")
@Test
public void testShoppingCart() throws NamingException{
shoppingCartRemote = (ShoppingCartRemote<String>)namingContext.lookup(SHOPPING_CART_REMOTE_JNDI_NAME);
System.out.println("Aggiunta elemento 1");
shoppingCartRemote.addItem("Item1");
System.out.println("Aggiunta elemento 2");
shoppingCartRemote.addItem("Item2");
System.out.println("Lista elementi:");
for(String item : shoppingCartRemote.getItems()){
System.out.println(item);
}
System.out.println("Rimozione elemento 1");
shoppingCartRemote.removeItem("Item1");
System.out.println("Lista elementi:");
for(String item : shoppingCartRemote.getItems()){
System.out.println(item);
}
shoppingCartRemote.releaseShoppingCart();
}
@SuppressWarnings("unchecked")
@Test
public void testSingleton() throws NamingException{
newsSingletonRemote = (NewsSingletonRemote<String>)namingContext.lookup(SINGLETON_REMOTE_JNDI_NAME);
System.out.println("Aggiunta news 1");
newsSingletonRemote.addNews("News1");
System.out.println("Aggiunta news 2");
newsSingletonRemote.addNews("News2");
System.out.println("News :");
for(String news : newsSingletonRemote.getNews()){
System.out.println("News:"+news);
}
System.out.println("Rimozione news 1");
newsSingletonRemote.removeNews("News1");
System.out.println("News :");
for(String news : newsSingletonRemote.getNews()){
System.out.println("News:"+news);
}
}
@AfterClass
public static void tearDownClass() throws NamingException {
namingContext.close();
}
}
Before rebooting, testConverter() test worked, but after that neither it!! Initially only testSingleton() and testShoppingCart was broken.
In the package it.html.progetto1.ejb30 I have the following classes (method tested successfully after reboot)
Converter.java
package it.html.progetto1.ejb30;
public interface Converter {
float celsiusToFahrenheit(float temperature);
float fahrenheitToCelsius(float temperature);
}
ConverterBean.java
package it.html.progetto1.ejb30;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
/**
* Session Bean implementation class ConverterBean
*/
@Stateless
@LocalBean
public class ConverterBean implements ConverterBeanRemote, ConverterBeanLocal {
/**
* Default constructor.
*/
public ConverterBean() {
// TODO Auto-generated constructor stub
}
@Override
public float celsiusToFahrenheit(float temperature) {
return temperature * 1.8f + 32;
}
@Override
public float fahrenheitToCelsius(float temperature) {
return (temperature - 32) / 1.8f;
}
}
ConverterBeanLocal.java
package it.html.progetto1.ejb30;
import javax.ejb.Local;
@Local
public interface ConverterBeanLocal extends Converter{
}
ConverterBeanRemote.java
package it.html.progetto1.ejb30;
import javax.ejb.Remote;
@Remote
public interface ConverterBeanRemote extends Converter{
}
in package it.html.progetto1.singleton.ejb32 singleton classes, starting of the problem (never worked on test):
NewsSingleton.java
package it.html.progetto1.singleton.ejb32;
import java.util.List;
public interface NewsSingleton<T> {
List<T> getNews();
void addNews(T news);
void removeNews(T news);
}
NewsSingletonBean.java
package it.html.progetto1.singleton.ejb32;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.ejb.AccessTimeout;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;
import javax.ejb.Startup;
// @Singleton marca la classe come Session Bean Singleton
@Singleton
// @Startup fa in modo che il bean venga allocato in fase di deploy dal modulo Ejb
@Startup
// Container-Managed-Concurrency è un'astrazione semplificata del meccanismo di locking
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class NewsSingletonBean implements NewsSingletonLocal<String>, NewsSingletonRemote<String> {
private List<String> newsList;
public NewsSingletonBean(){
newsList=new ArrayList<String>();
}
// locca in fase di lettura, molti thread possono leggere contemporaneamente (acceso contemporaneo)
@Lock(LockType.READ)
/*
* invece di avere un thread che, dopo aver invocato un metodo con lock Read, si trova in attesa perché
* il singleton è in lock da parte di un altro thread, possiamo specificare un limite per l’attesa (in questo caso 15 secondi).
* Allo scadere del timeout, se il lock non è stato rilasciato si verifica un’eccezione.
*/
@AccessTimeout(unit=TimeUnit.SECONDS, value=15)
public List<String> getNews(){
return newsList;
}
// locca in fase di scrittura, e quindi un solo thread alla volta scrive e gli altri sono bloccati
@Lock(LockType.WRITE)
public void addNews(String news){
newsList.add(news);
}
@Lock(LockType.WRITE)
public void removeNews(String news){
newsList.remove(news);
}
}
NewsSingletonLocal.java
package it.html.progetto1.singleton.ejb32;
import javax.ejb.Local;
@Local
public interface NewsSingletonLocal<T> extends NewsSingleton<T> {}
NewsSingletonRemote.java
package it.html.progetto1.singleton.ejb32;
import javax.ejb.Remote;
@Remote
public interface NewsSingletonRemote<T> extends NewsSingleton<T> {}
Trace:
javax.naming.NameNotFoundException: Progetto1Ear -- service jboss.naming.context.java.jboss.exported.Progetto1Ear
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:106)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
at org.wildfly.naming.client.remote.RemoteServerTransport.handleLookup(RemoteServerTransport.java:200)
at org.wildfly.naming.client.remote.RemoteServerTransport$1.handleMessage(RemoteServerTransport.java:120)
at org.jboss.remoting3.remote.RemoteConnectionChannel.lambda$handleMessageData$3(RemoteConnectionChannel.java:430)
at org.jboss.remoting3.EndpointImpl$TrackingExecutor.lambda$execute$0(EndpointImpl.java:991)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at java.lang.Thread.run(Unknown Source)
Lesson: check if there are exception about your server before! In fact console said thah there was two localBean with the same name (ConverterBean), thus mapped with the same one. Changing ConverterBean name (ex: CoverterBeanI) it works, all methods works.