I have a business interface being implemented by two EJBs.
UserManagementService
#Remote
public interface UserManagementService {
// ...
}
UserManagementServiceJpaImpl
#Stateless(name="userManagementServiceJpaImpl")
public class UserManagementServiceJpaImpl implements UserManagementService {
#EJB(beanName="userManagementDaoJpaImpl")
private UserManagementDao userManagementDao;
// ...
}
UserManagementServiceMockImpl
#Stateless(name="userManagementServiceMockImpl")
public class UserManagementServiceMockImpl implements UserManagementService {
#EJB(beanName="userManagementDaoMockImpl")
private UserManagementDao userManagementDao;
// ...
}
When I deploy the application to Glassfish 3.1 I get the following error:
java.lang.RuntimeException: Error while binding JNDI name com.transbinary.imdb.service.UserManagementService for EJB : userManagementServiceMockImpl
at com.sun.ejb.containers.BaseContainer.initializeHome(BaseContainer.java:1550)
at com.sun.ejb.containers.StatelessSessionContainer.initializeHome(StatelessSessionContainer.java:202)
at com.sun.ejb.containers.ContainerFactoryImpl.createContainer(ContainerFactoryImpl.java:167)
at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:234)
at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:290)
at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:101)
at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:186)
at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:249)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:460)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:370)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1067)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1247)
at org.glassfish.deployment.autodeploy.AutoOperation.run(AutoOperation.java:145)
at org.glassfish.deployment.autodeploy.AutoDeployer.deploy(AutoDeployer.java:577)
at org.glassfish.deployment.autodeploy.AutoDeployer.deployAll(AutoDeployer.java:463)
at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:395)
at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:380)
at org.glassfish.deployment.autodeploy.AutoDeployService$1.run(AutoDeployService.java:213)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
Caused by: javax.naming.NameAlreadyBoundException: Use rebind to override
at com.sun.enterprise.naming.impl.TransientContext.doBindOrRebind(TransientContext.java:333)
at com.sun.enterprise.naming.impl.TransientContext.bind(TransientContext.java:268)
at com.sun.enterprise.naming.impl.SerialContextProviderImpl.bind(SerialContextProviderImpl.java:98)
at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.bind(LocalSerialContextProviderImpl.java:99)
at com.sun.enterprise.naming.impl.SerialContext.bind(SerialContext.java:672)
at com.sun.enterprise.naming.impl.SerialContext.bind(SerialContext.java:689)
at javax.naming.InitialContext.bind(InitialContext.java:404)
at javax.naming.InitialContext.bind(InitialContext.java:404)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.publishObject(GlassfishNamingManagerImpl.java:208)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.publishObject(GlassfishNamingManagerImpl.java:189)
at com.sun.ejb.containers.BaseContainer$JndiInfo.publish(BaseContainer.java:5608)
at com.sun.ejb.containers.BaseContainer.initializeHome(BaseContainer.java:1535)
... 23 more
Could someone help me understand why am I getting this error and how to resolve it?
By default GlassFish Server specific default JNDI names are applied automatically for backward compatibility. So com.transbinary.imdb.service.UserManagementService is the the default JNDI name for both the implementations of UserManagementService interface. Which was why I was gettting javax.naming.NameAlreadyBoundException exception.
But because the EJB 3.1 specification defines portable EJB JNDI names, there is less need for GlassFish Server specific JNDI names.
To disable GlassFish Server specific JNDI names for an EJB module, set the value of disable-nonportable-jndi-names element to true. The default is false.
It solved the problem.
Resource: http://wikis.oracle.com/display/GlassFish/Developer+Handoff+to+QA+for+EJB-8+%28Option+to+disable+GlassFish-specific+JNDI%29
GlassFish restart. (It worked for me.)
I got this same exception.
In my case I changed my code from #Stateless(mappedName = "whatever") to instead be #Stateless(name = "whatever") and it solved my issue
Make use of rebind instead of bind and it should work
In my case, i was using JBoss5.1GA and i had two EJBs implementing a common local Business Interface...
I Follow the idea suggested by #Christo Smal, and it work for me.... Another Observation: I was deploying an ear which contains the two EJBs at two differents EJB jars; e.g:
Ear File:
* Jar File1: Containing EJB1
* Jar File2: Containing EJB2
* lib/dummy.jar: Library containing the Business Local interface
Related
I have a Spring project (not using Spring Boot, if that's relevant) that I'm trying to connect to a local database using the Postgres JDBC driver. (The local database is actually Yugabyte, but that should be fully compatible with the Postgres driver.)
When starting the application, I get this error message:
java.lang.IllegalArgumentException: An AbstractMessageProducingMessageHandler may only be referenced once (org.springframework.integration.config.SplitterFactoryBean#0) - use scope="prototype"
at org.springframework.util.Assert.isTrue(Assert.java:118)
at org.springframework.integration.config.AbstractStandardMessageHandlerFactoryBean.checkReuse(AbstractStandardMessageHandlerFactoryBean.java:168)
at org.springframework.integration.config.AbstractStandardMessageHandlerFactoryBean.createHandler(AbstractStandardMessageHandlerFactoryBean.java:137)
at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.createHandlerInternal(AbstractSimpleMessageHandlerFactoryBean.java:186)
at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.getObject(AbstractSimpleMessageHandlerFactoryBean.java:174)
at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.getObject(AbstractSimpleMessageHandlerFactoryBean.java:59)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:171)
... 52 more
I can't place this error at all. There is one similar question on Stack Overflow, but there the asker seems to actually know what they're doing and how this is related to spring integration. I, however, am not aware at all that I'm trying to 'reuse' anything. The referenced question also doesn't seem to be related to database configuration.
My setup/configuration is a bit involved, so I'll try to quote the parts that seem relevant.
I have a dao layer project that has the following gradle dependencies (among others):
implementation("org.springframework:spring-context:5.2.2.RELEASE")
implementation("org.springframework:spring-jdbc:5.2.2.RELEASE")
implementation("org.jooq:jooq-kotlin:3.14.11")
runtimeOnly("org.postgresql:postgresql:42.2.19.jre7")
In the same project, I have some configuration (in Kotlin):
#Configuration
open class Config {
#Bean
open fun jdbcTemplate(dataSource: DataSource): JdbcTemplate = JdbcTemplate(dataSource)
#Bean
open fun dslContext(): DSLContext = DefaultDSLContext(SQLDialect.POSTGRES)
#Configuration
#Profile("!unittest")
open inner class NonTestConfig {
#Bean
open fun dataSource(): DataSource {
return DriverManagerDataSource().apply {
// Hardcoded properties to be replaced by values from property file
setDriverClassName("org.postgresql.Driver")
url = "jdbc:postgresql://localhost:5433/demo"
username = "yugabyte"
password = "yugabyte"
}
}
}
}
(Notes: the DSLContext bean is used for JOOQL, included for completeness' sake. The inner class config is there because there is also a separate unit testing config for an embedded database - that one works fine!)
Now, the above project is used in my top-level project that contains the actual application. It's a maven runtime dependency there. I import the config class in this project's XML configuration, using this method:
<context:annotation-config />
<bean class="my.package.Config" />
Then trying to start the application produces the error message.
I figured out what the problem was, but I still don't know how it relates to a <splitter>.
The problem was that the Config class, apart from the database stuff, also included a bean to encrypt data. It turned out that this bean was also defined in another library used by the top-level project. Fixing this duplicate bean problem made the error go away.
I discovered this in a roundabout way: I included the dao project and its configuration in a different top-level project that uses Spring Boot. This led to a clear error message about the encryptor bean having two definitions.
If anyone can explain why the error message is so cryptic in the non-Boot case, that would be a nice complementary answer.
We have stateless session bean (EJB 3.0) that has a method which accepts varargs(variable arguments) as inputs. Method signature is as below:-
public String operation1(String arg1,List...arg4);
This EJB is deployed on Weblogic 10.3.2 running on a "Java6" JRE.
When this EJB method is invoked from a Java6 standalone client, the call is successful.
When I change the JRE from Java6 to Java7(without changing any other client code),the call fails with an unmarshal exception(Stack trace below).
javax.ejb.EJBException: Could not unmarshal method ID; nested exception is:
java.rmi.UnmarshalException: Method not found: 'operation1(Ljava.lang.String;Ljava.util.List...;)'; nested exception is: java.rmi.UnmarshalException: Method not found: 'operation1(Ljava.lang.String;Ljava.util.List...;)'
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.unwrapRemoteException(RemoteBusinessIntfProxy.java:109)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:91)
at com.sun.proxy.$Proxy5.operation1(Unknown Source)
at com.MyEJBStandaloneClient.testOperation1(MyEJBStandaloneClient.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
EJB Code
#Stateless(mappedName = "MyBean")
public class MyBean implements MyBeanRemote{
public String operation1(String arg1,List...arg4) {
System.out.println("Input1 is:-"+arg1);
return "newString";
}
}
Remote class
#Remote
public interface MyBeanRemote {
public String operation1(String arg1,List... arg4);
}
The non-varargs methods(if any are added), within the same EJB are invoked successfully from Java7 clients & it is only the varargs methods in the EJB that have this problem.
Note that the same call works fine even with Java7 if the method signature on the Remote interface class is changed to the following
public String operation1(String arg1,List[] arg4);
But is there any way to make it work without changing the method signature?
Are there any known issues around this?
Thanks.
The problem you described is the consequence of an old bug from WebLogic.
In fact, EJB methods using varargs are ignored when it generates its stub classes.
The deep reason is that WebLogic EJB compiler incorrectly tries to append a transient modifier to the varargs argument.
Obviously, it results in an error, and so, the method stub is not generated.
At that time BEA created a path, CR327275, for WebLogic 10.0.MP1 to correct the issue. Unfortunately, this patch was apparently NOT included in WebLogic 10.3 release...
Feedbacks on this point are not that easy to find, but the Seam community made some. Here they are:
http://in.relation.to/Bloggers/Weblogic10SeamAndEJB3#H-Option1ApplyTheTtCR327275ttPatchBut
https://docs.jboss.org/seam/2.1.2/reference/en-US/html/weblogic.html
So, to solve your issue:
either, as you guessed, you have to change the method signature
or you contact WebLogic to get and install the former patch.
Regards,
Thomas
From our Grails/Groovy app we need to use a service from a legacy Java service class, the constructor of which has a parameter of type org.springframework.core.io.Resource, e.g.
public ServiceClass(Resource someResource)
We need to inject an instance of the service class into a Groovy class of our app using Spring DSL, with the Resource referring to an XML file within our /src/main/resources. I tried to create the Spring config for this purpose, but so far I couldn't find a working solution. The relevant part of the config file looks like this
beans = {
xmlns aop:"http://www.springframework.org/schema/aop",
sec:"http://www.springframework.org/schema/security",
context:"http://www.springframework.org/schema/context"
serviceClass(com.somepackage.ServiceClass) {
//here we need to refer to the constructor arg XML file some way
}
}
I have tried multiple syntaxes found in various tutorials, e.g. closure for beanDefinition.constructorArgs, but unfortunately without success so far. Although neither the app compilation (grails:war) nor the startup (grails:run-app) indicates any problems with the bean wiring, when the app is actually loaded into the browser, we receive a NPE stating that our Groovy class into which the service class is injected, is a null object. So it seems that the bean wiring was not successful after all. Any help is appreciated
After fixing various issues with the project setup itself and multiple cleanups/recompiles, it seems that the following two approaches are both OK
serviceClass(com.somepackage.ServiceClass, '/WEB-INF/constructor-arg-xml-file.xml') {}
and
serviceClass(com.somepackage.ServiceClass) { bean ->
bean.constructorArgs = [
'/WEB-INF/constructor-arg-xml-file.xml'
]
}
Neil Bartlett's article http://njbartlett.name/2010/07/19/factory-components-in-ds.html shows the way to set config for bundles without using managed service or managed factory.
Search for examples of actually setting the config for this method either point to felix file install or to examples using managed service.
In answer to the question OSGi Declarative Services vs. ManagedService for configuring service? Neil Bartlett states "Note that DS never actually creates a ManagedService or ManagedServiceFactory for your component. It works by listening to Config Admin with a ConfigurationListener. However the internal details are unimportant... simply create configs with PID/factoryPID matching the component.name and it "just works"
I think the technique involves placing a pid entry in the config dictionary but I have no idea how this would be used with config admin.
A guide or simple example of how to set the configuration using this method would be very helpful.
I know it is some time since the question was asked, but I ran into the same problem when trying to create a ManagedServiceFactory-like Component with Declarative Services. So I want to share my solution. Maybe others find it useful. My problem was like this:
I have defined a component (annotated with #Component). On each configuration I add using felix file-install, I want an instance of that component created with the given configuration and activated immediately.
First I tried messing with the properties factory and configurationPid of #Component, but all that is not needed and even returns wrong results (felix annotation processor in the maven plugin seems to have a bug when handling configurationPid).
The solution I came up with:
package com.example.my;
#Component(
name = MyExampleComponent.FACTORY_PID,
configurationPolicy = ConfigurationPolicy.REQUIRE,
property = {"abc=", "exampleProp="}
)
public class MyExampleComponent {
public static final String FACTORY_PID = "com.example.my.component";
#Activate
protected void activate(BundleContext context, Map<String,Object> map) {
// ...
}
}
Then I created a config file for felix file-install named com.example.my.component-test1.cfg:
abc = Hello World
exampleProp = 123
When deployed this automatically creates a folder structure in the configuration folder like com/example/my/component containing the files:
factory.config
contents:
factory.pid="com.example.my.component"
factory.pidList=[ \
"com.example.my.component.525ca4fb-2d43-46f3-b912-8765f639c46f", \
]
.
525ca4fb-2d43-46f3-b912-8765f639c46f.config
contents:
abc="Hello World"
exampleProp="123"
felix.fileinstall.filename="file:/..._.cfg"
service.factoryPid="com.example.my.component"
service.pid="com.example.my.component.525ca4fb-2d43-46f3-b912-8765f639c46f"
The 525ca4fb-2d43-46f3-b912-8765f639c46f seems to be some randomly generated ID (possibly UUID).
I'm trying to migrate from JPA to JTA and use bitronix transaction manager. I'm getting below error message when try to run unit tests. According to bitronix documentation this is normal b/c my spring context configuration is trying to load the resources twice (once in base class and then in the test class, see code below), I have tried the same with atomikos and I got similar result.
Caused by:
java.lang.IllegalArgumentException:
resource with uniqueName 'xyzDb'
has already been registered
My base class
#ContextConfiguration(locations = {"classpath:com/xyz/baseContext.xml"})
#Transactional
public abstract class AbstractTestSupport extends Assert implements ApplicationContextAware
{
In some unit tests I have to extend the test support and add a context config file like below. so it loads context once for base class and another time for child class and fails
Child class
#ContextConfiguration(locations = {"classpath:com/xyz/testContext.xml"})
public class UnitTest extends AbstractTestSupport
{
After the test I'm shutting down context, so next test works fine as long as it doesn't extend the base class with another context config file.
#AfterClass
public static void onTearDownAfterClass() throws Exception
{
applicationContext.shutdownApplicationContext();
assertFalse("Spring application context is still active after shutdown. ", applicationContext.isActive());
}
I want to keep context config files in the child classes and make this work like that, any ideas greatly appreciated....
The error message basically means you created the connection pool with unique name 'xyzDb' (remember there is a uniqueName property you need to set on BTM's pools?) for the second time at the time the exception is thrown. You cannot do that: each connection pool must have a unique name and must be closed before another one with an identical name can be created.
I suppose there is some overlap between your two context files causing this or maybe the connections pools aren't always closed like they should. Unfortunately you published too little information to get a definitive answer.