How to set priority of using class - java

I am creating web service. I have application tier and web tier. Both of this tier using jaxb to generate object factory from xsd. Generating class are in package: my.package.v1
Now I have another project which has dependency on these project.
In context I have specify object factory:
<bean id="objectFactory" class="my.package.v1.ObjectFactory" />
when I compile and deploy application everything is OK. But there is two Object factory and he can use just one of them. Which one application use and how I change it and use another one ?
UPDATE:
Is there options how to set in spring context which class to use ?
I want change this to set right class when I have two ObjectFactory
<bean id="objectFactory" class="my.package.v1.ObjectFactory" />

There can be conflicting results and depends on Contextual classloader. I would suggest to have them in separate packages to avoid namespace conflicts

Which one of the two implementations of my.package.v1.ObjectFactory that is actually used depends on the ClassLoader.
See this question for info on how ClassLoaders resolve this kind of issue.

Related

Class cast exception with MSSQL drivers [duplicate]

I have 2 different Java projects, one has 2 classes: dynamicbeans.DynamicBean2 and dynamic.Validator.
On the other project, I load both of these classes dynamically and store them on an Object
class Form {
Class beanClass;
Class validatorClass;
Validator validator;
}
I then go ahead and create a Validator object using validatorClass.newInstance() and store it on validator then I create a bean object as well using beanClass.newInstance() and add it to the session.
portletRequest.setAttribute("DynamicBean2", bean);
During the lifecycle of the Form project, I call validator.validate() which loads the previously created bean object from the session (I'm running Websphere Portal Server). When I try to cast this object back into a DynamicBean2 it fails with a ClassCastException.
When I pull the object back out of the session using
faces.getApplication().createValueBinding("#{DynamicBean2}").getValue(faces);
and check the class of it using .getClass() I get dynamicbeans.DynamicBean2. This is the class I want to cast it to however when I try I get the ClassCastException.
Any reason why I'm getting this?
I am not quite following your description of the program flow, but usually when you get ClassCastExceptions you cannot explain you have loaded the class with one classloader then try to cast it to the same class loaded by another classloader. This will not work - they are represented by two different Class objects inside the JVM and the cast will fail.
There is an article about classloading in WebSphere. I cannot say how it applies to your application, but there are a number of possible solutions. I can think of at least:
Change the context class loader manually. Requires that you can actually get a reference to an appropriate class loader, which may not be possible in your case.
Thread.currentThread().setContextClassLoader(...);
Make sure the class is loaded by a class loader higher in the hierarchy.
Serialize and deserialize the object. (Yuck!)
There is probably a more appropriate way for your particular situation though.
I was getting this problem after adding a dependency to spring-boot-devtools in my Springboot project. I removed the dependency and the problem went away. My best guess at this point is that spring-boot-devtools brings in a new classloader and that causes the issue of class casting problems between different classloaders in certain cases where the new classloader is not being used by some threads.
Reference: A dozer map exception related to Spring boot devtools
The class objects were loaded in different classloaders, therefore the instances created from in each of classes are seen as 'incompatible'. This is a common issue in a an environment where there are many different classloaders being used and objects are being passed around. These issues can easily arise in Java EE and portal environments.
Casting an instance of a class requires that the Class linked to the object being casted is the same as the one loaded by the current thread context classloader.
I got the A2AClassCastException problem when trying to create a List of objects from XML using Apache Commons Digester.
List<MyTemplate> templates = new ArrayList<MyTemplate>();
Digester digester = new Digester();
digester.addObjectCreate("/path/to/template", MyTemplate.class);
digester.addSetNext("/path/to/template", "add");
// Set more rules...
digester.parse(f); // f is a pre-defined File
for(MyTemplate t : templates) { // ClassCastException: Cannot cast mypackage.MyTemplate to mypackage.MyTemplate
// Do stuff
}
As stated above, the cause is that the digester doesn't use the same ClassLoader as the rest of the program. I ran this in JBoss, and it turned out that commons-digester.jar was not in JBoss's lib directory, but rather in a webapp's lib directory. Copying the jar into mywebapp/WEB-INF/lib also solved the problem. Another solution was to casll digester.setClassLoader(MyTemplate.class.getClassLoader()), but that feels like quite an ugly solution in this context.
Had the same my.package.MyClass cannot be cast to my.package.MyClass on WildFly 10.1 and, as I understand, I did the opposite to what #Emil Lundberg described in his answer.
I have added the module (which contains my.package.MyClass) to my.war/WEB-INF/jboss-deployment-structure.xml as a dependency
<dependencies>
...
<module name="my.package"/>
</dependencies>
and removed the corresponding jar from my.war/WEB-INF/lib, re-deployed the WAR and then the code worked as expected.
Thus, we made sure it solves the issue. Now, we need to make sure the issue won't come back, for example, when the updated version of WAR will be assembled and deployed.
For this, in the sources of those WAR, it is required to add <scope>provided</scope> for those jar in pom.xml, so that when my.war is re-assembled next time with the fix/enhancement code injected, it will not bundle this jar into my.war/WEB-INF/lib.
I had the same issue while using several JBoss instances on different machines. To bad I didn't stumble across this post earlier.
There were artifacts deployed on different machines, two of them declared class loaders with identical name.I changed one of the classloader names and everything worked fine => Beware of Copy&Paste!
Why doesn't the ClassCastException thrown mention the involved class loaders? - I think that would be very useful information.
Does anyone know if there will be anything like this available in the future? Needing to check the class loaders of 20-30 Artifacts is not that pleasant. Or is there something I missed in the exception text?
EDIT: I edited the META-INF/jboss-app.xml file and changed the name of the loader, the idea is to have a unique name. At work we use the artifact id(unique) combined with the version inserted by maven({$version}) during the build. Using dynamic fields is only optional but helps if you want to deploy different versions of the same application.
<jboss-app>
<loader-repository>
com.example:archive=unique-archive-name-{$version}
</loader-repository>
</jboss-app>
You can find some info here: https://community.jboss.org/wiki/ClassLoadingConfiguration
I had the same issue, and I finally found a workaround on java.net :
Copy all org.eclipse.persistence jar files from glassfish4/glassfish/modules to WEB-INF/lib. Then go in your glassfish-web.xml, and set class-delegate to false.
Worked for me !
I had a similar issue with JAXB and JBoss AS 7.1. The issue and solution are described here: javax.xml.bind.JAXBException: Class *** nor any of its super class is known to this context. The exception that was given was org.foo.bar.ValueSet cannot be cast to org.foo.bar.ValueSet
I had the same issue on a wildfly EJB, The EJB was returning a list of Objects and has an remote and a local interface. I used the Local interface by mistake what was working just fine up until the point you try to cast the objects in the list.
Local/Remote interface:
public interface DocumentStoreService {
#javax.ejb.Remote
interface Remote extends DocumentStoreService {
}
#javax.ejb.Local
interface Local extends DocumentStoreService {
}
The EJB bean:
#Stateless
public class DocumentStoreServiceImpl implements DocumentStoreService.Local, DocumentStoreService.Remote {
The correct spring wrapper around the EJB:
<bean id="documentStoreService" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="java:global/dpc/dpc-ejb/DocumentStoreServiceImpl!santam.apps.dpc.service.DocumentStoreService$Remote"/>
<property name="businessInterface" value="santam.apps.dpc.service.DocumentStoreService$Remote"/>
<property name="resourceRef" value="true" />
</bean>
Note the $Remote, You can change this to $Local and it will find the Local interface just fine, and also execute the methods without any issue (from a separate application on the same container), but the model objects are not marshaled and are from a different class loader if you use the local interface by mistake.
Another option:
Happened to me in weblogic, but I guess it can happen in other servers as well - if you do (just) "Publish" and therefor some of your classes are re-loaded. Instead do "Clean" so all the classes will re-loaded together.
I had same problem with an EJB lookup from another EJB.
I solved adding #Remote(MyInterface.class) to EJB class configuration

Bean and Dependency Injection configuration from Database Instead XML

Currently we have all service class configuration defined in Application-Context.xml file. Application context will be initialized during the application startup with all beans defined in the context file and spring handles dependency injection.
I am looking for a solution where it has to load particular service class during run time based on specific parameter from Database.
For example, there are two classes exist in code base such as FooService1.java and FooService2.java. Each class will have dependency with appropriate DAO class such as FooDAO1.java and FooDAO2.java.
Instead of defining these in applciation-context.xml file, a run time parameter will decide which service needs to be loaded and its corresponding DAO which needs to be injected. Basically what i am trying to achieve here is DB oriented Dependency Injection to keep all application context information in database instead of XML.
Tables would look like: SERVICE_BEANS, DAO_BEANS and some intermediate table to have dependency information.
I just saw JdbcBeanDefinitionReader class in spring. Can I use this to implement DB oriented DI? I don't see much example on this. Please let me know if anyone has any examples.
I think you can generate beans # runtime and register them to spring-context.
Refer to Registering beans(prototype) at runtime in Spring
Hope that helps !

spring xml configuration in two separate xml files?

I am trying to create a project with one spring configuration file. but inside the configuration file all beans are interfaces without any implementations. i would create one more project with all implementations. Also can i use abstract = true for all the beans(interfaces) of first project, so that user cannot use them.
Thanks!
I can't imagine a situation where you want to specify interfaces in the spring config file. So I think it is unnecessary for you as well. You can use abstract=true to create reusable or partial bean definitions.
You cannot specify interfaces in in your spring config, since they cannot be instantiated. What exactly are you trying to archive?

Common configuration in ejb jar xml

There is an ejb-jar xml file in our project which defines essentially the same ejb configuration over and over again for a number of different brands. They all share the same underlying code, the same external references etc., so could in fact all be mapped to the same single definition.
The argument is that in future if there is some distinction required between the brands, then the mechanism is in place to manage each pool and configuration separately. This I can accept.
I would however still like to condense this rapidly bloating file. A suggestion floated around was to use XSLT to transform a bespoke xml configuration, but this introduces another type of complexity that I'd like to avoid.
My question then is, does anyone know if the specification supports any means of inheriting some kind of parent or common configuration into the definition of an ejb?
There is no inheritance for EJB component definitions. Some suggestions:
If you're willing to use annotations, you could specify most of your component configuration in the bean class, and then reuse the same <ejb-class/> for multiple <session/>.
If you're using a JavaEE 6 server and you're just trying to cut down on refs, you could consider defining your refs in java:module/env, and then they will be visible to all beans in the module.

How do you make a multi-module spring configuration?

I have a multi-module (maven) spring build. All the modules publish some beans, and most also consume beans defined further down the dependency graph. Although most of it is annotation declared beans, almost every module also has one or two xml-declared beans.
Although we have a half-decent solution, but I am really wondering what is the correct/optimal way to organize the xml files in this scenario? Do you use import between the modules or is there some other way ? Do you put all the xml files in one place or spread them around according to the dependency graph? How does your solution handle partial spring contexts (typical integration tests) ?
I'd also like to have this organized in a way that lets me leverage my IDE's spring support optimally (IDEA and a few eclipse users).
We use wildcarded imports in the modules to allow other modules contribute beans to the module declaring the import:
<import resource="classpath*:com/acme/**/*-core-support.xml" />
Modularity
Modules that want to contribute to the "host" just have to place a correctly named files in src/main/resources/com/acme in this case to be picked up automagically. If you use classpath scanning (by <context:component-scan /> it will become even easier).
Another thing that helps in that regard is some small Spring extension that picks up beans of a given type and republishes them in ApplicationContext again. By doing something like this:
<plugin:list id="beanList" class="com.acme.MyCoolPluginInterface" />
<bean class="com.acme.MyPluginHost">
<property name="plugins" ref="beanList" />
</bean>
In combination with the wildcarded import this will:
Collect all beans found in the ApplicationContext that implement MyCoolPluginInterface and wrap them in a list registered as beanList in the ApplicationContext.
Allow the MyPluginHost to reference that list.
In fact, you now can simply extend your app by adding plugin modules to the classpath (aka dependency in Maven).
That tiny Spring extension is called Spring Plugin and published under Apache 2 licence. See http://github.com/SpringSource/spring-plugin for more info. There's also a more advanced sample project at Github, that shows how this works and improves modularity at GitHub. The app is sample code for my "Whoops! Where did my architecture go?" presentation which you can see the slides here or watch a recording here.
Different environments
Usually we configure our apps to run in the target environment (using JNDI lookups and stuff). Of course you would like to use the standard PropertyPlaceholderConfigurer mechanisms to externalize configuration that has to be touched by admins or will change through various environments.
For integration tests we usually have additional config files in src/main/test that get loaded additionally to the normal config files overriding the critical beans that tie the configuration to the environment. E.g. if you have a datasource in your normal config file
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource" />
you would override this in your test-context.xml by using
<bean id="dataSource" class="...DataSource" />
<!-- config -->
</bean>
and importing that after the original one in the test class
#ConfigurationContext(locations = {"app-context.xml", "test-context.xml"})
public FooBarIntegrationtest {
// ...
}
We simply create the application context from multiple XML config files based on usage.
For example, for testing without a server, the context is created by using all the config files in each service module.
When deployed, we access the services via Spring Remoting, and thus the client uses an application context that is initialized via an XML config which defines the proxy beans that enable remoting. Meanwhile the services are confgured by the same XML files as used by the test cases, but the application context is now loaded by either the DispatcherServlet or an EJB or MDB.
This setup allows us to tailor the Application Context for each scenario without having to duplicate any information in configuration files, which keeps maintenance much simpler. Also, there is no hard dependency between config files via imports, since that is handled at the layer above that actually creates the ApplicationContext.
Can't comment on the IDE support since we are not using it yet.

Categories

Resources