I want to deploy the same .war file to two different virtual hosts on the same Tomcat 6 instance. However, I am running into a problem with the Spring framework and registering a bean. Here is the error I am seeing...
org.springframework.jmx.export.UnableToRegisterMBeanException:
Unable to register MBean
[com.dti.servlets.Configuration#3a1834]
with key 'EAM:name=webConfig'; nested
exception is
javax.management.InstanceAlreadyExistsException:
EAM:name=webConfig
I am pretty sure that I need to define my contexts for each virtual host but I am not having any luck. The only fix I have found that works is to change the name of the bean key. Any other suggestions would be great.
The problem is that the name of the bean must be unique per JVM. Since you're deploying the same war twice, you have two solutions:
change the registration behaviour of the Spring JMX exporter (see the documentation)
define your own ObjectNamingStrategy to dynamically change the name of the beans at startup (you would end up with names like app1.mybean and app2.mybean)
Related
I have implemented caching in my Spring application and when I run it locally everything works fine. I have infinispan.xml configuration in resources and the following configuration:
spring.cache.type=infinispan
spring.cache.infinispan.config=classpath:infinispan.xml
Now I would like to deploy it to WildFly 10 and to use built in cache. I have defined my cache container with jndi-name=infinispan/CONTAINER.
I tried setting spring.cache.infinispan.config to:
infinispan/CONTAINER
java:/infinispan/CONTAINER
java:jboss/infinispan/CONTAINER
But I allways get the following error:
java.lang.IllegalArgumentException: Cache configuration does not exist
What should I do make this work?
As far as I know, this is not possible at the moment.
You will need to extend SpringEmbeddedCacheManagerFactoryBean and override #createBackingEmbeddedCacheManager() method. Then use JndiTemplate to grab a reference to EmbeddedCacheManager deployed in WildFly (similarly to this thread).
I also created ISPN-7208 to allow specifying JNDI references for Cache Managers.
I am going through 'Chapter 20 - Managing Spring bean with JMX' from the book 'Spring In Action' 4th Edition by Craig Walls. There is one paragraph in this chapter on page 527.
From whence the MBean server?
As configured, MBeanExporter assumes that it’s running in an application server (such as Tomcat) or some other context that provides an MBean server. But if your Spring application will be running standalone or in a container that doesn’t provide an MBean server, you’ll want to configure an MBean server in the Spring context.
In XML configuration, the <context:mbean-server> element can handle that for you. In Java configuration, you’ll need to take a more direct approach and configure a bean of type MBeanServerFactoryBean() (which is what does for you in XML).
I have couple of questions on the above paragraph.
Does it mean that when we are running the application on server like Tomcat, <context:mbean-server> declaration is no longer required?
If above statement is true, who takes care of locating the MBean server when we are running on server like Tomcat or any other application server?
Thanks in advance!
That information is a little out of date...
or some other context that provides an MBean server.
Starting with Java 5 (if I recall correctly), the JVM has a built in MBeanServer. Prior to that, you had to be running in an App server, or provide some other MBeanServer such as mx4j.
Regardless, you still need the server bean declaration; it tells Spring which server to use (the underlying MBeanServerFactoryBean's locateExistingServerIfPossible is set to true by the XML namespace parser. If that flag is false, the factory bean would create an additional MBeanServer.
I'm trying to figure out where is the definition of the above resources stored. My application does not have and never had such resource defined. So I'm actually sure this is some kind of server reference but the question is where such stuff could be defined. It looks for me like some kind of cached references existing somewhere on the server and used when the same names are tried.
People advice workarounds like creating resources manually or using java:app/ prefix.
However I'd like to go tot the bottom of the problem and resolve the source of the problem instead.
The contain entity manager config could be the first thing to check but where is it?
What config file should I examine, modify or remove.
Here is the beginning of the error message:
Severe: Exception while preparing the app : Invalid resource : jdbc/CustomerDEV1__nontx
com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Invalid resource : jdbc/CustomerDEV1__nontx
To get rid of it, you´ll need to remove the persistence.xml cached by the IDE. For example (using Netbeans 8 under Windows 8.1):
C:\Users\jMarcel\AppData\Local\NetBeans\Cache\8.0\index\s71\java\14\classes\META-INF\persistence.xml
Hint: in WindowsExplorer, set your directory to C:\Users\yourUser**AppData\Local\NetBeans** and perform a search for the persistence.xml file.
I hope you are not letting the server know what type of resource you are looking up in the JNDI tree and confusing it. You look for JDBC resource in within application. Please note that if you use java:app/ then it means
The java:app namespace is used to look up local enterprise beans packaged within the same application. That is, the enterprise bean is packaged within an EAR file containing multiple Java EE modules. JNDI addresses using the java:app namespace are of the following form:
You have to use java:comp/env/jdbc/CustomerDEV1__nontx for JDBC Datasource. java:comp/env/jdbc denotes it is a JDBC resource in the Java components environment
In java EE, the way you get an EJB from a remote server is by looking it up in JNDI. The specification defines the JNDI name for a given bean type.
However, this seems to be only if you want to get a bean off your local computer. I want to get the bean off a remote server, like most users would. How do I specify the server URL? Do I pass a map to the InitialContext constructor?
Note: There is another question that is pretty much the same, but that has become out of date since the definition of portable JNDI names by the specification.
I want to get the bean off a remote server
Yes, you need specify the IP/port where the remote server (JNDI service) is running/listening.
How do I specify the server URL?
You have to set the propertie: java.naming.provider.url and make it available to the InitialConetxt.
This can be done in different ways:
to use a jndi.properties file
to use system properties
passing the value in a Hashtable when you create a new instance of
InitialContext object.
The concrete value of this and others necessary properties to instantiate the InitialConetct are vendor dependen.
An example for JBoss could be:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://yourServer:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
Keep in mind that there is no way that you can get the EJB's stub from a remote server if you don´t indicate the url.
By "Remote" I mean the client and the server are running in different JVM.
You do JNDI lookups of remote EJBs using exactly the same code as you would use when running server-side:
Context context = new InitialContext(); // No properties needed
MyEJB myEjbInstance = (MyEJB) context.lookup("ejb/MyEJB");
Or, of course, you can inject it:
#EJB
private MyEJB myEjbInstance;
To make the naming context work, you must run your application as a Java EE application client. An application client is exactly like a regular standalone Java program, with a standard main method; the only difference is that it needs to be run in a different manner. That manner is not specified in the Java EE Spec, so each application server has its own way of doing it.
GlassFish, for example, requires an application client to include some special jars in the classpath, and set a couple system properties. Specifically, you must include lib/gf-installer.jar and all the jars referenced by its manifest in your classpath, and you must set the org.omg.CORBA.ORBInitialHost and org.omg.CORBA.ORBInitialPort system properties.
I'm facing a problem with Spring dependency injection. I have an application that once deployed checks if it's previously configured, if not then it launches configuration manager and asks the user for db host, port, admin login and pass etc.
Now I can't find a way to inject those configured values. I assume that I would have to use lazy init beans but when i add the annotation #Lazy, Spring is still trying to inject them at the runtime and I'm getting an error since the host and port are not yet configured.
What am I missing :/?
You need a lookup method, a feature accessible only through XML configuration. There is an almost ancient JIRA issue still open on this, still unresolved.
Please do check this comment on the mentioned issue, it describes a workaround that may be an option for you.