We have a number of web service client applications which interface between our main customer facing application and backend web services. These web service application generate their own JAXWS stub code to directly interface with the web services and implementation code to provide a clean interface between the JAXWS code and any application that wishes to use it. We've had some small problems with these over the last few weeks but most of them have been resolved.
When it was time to integrate these into the customer facing application we encountered numerous problems, mainly focused around JDK1.5 and 1.6 incompatibility. These have been resolved now, however we have hit another problem which we have no resolution for. The web service clients use AOP to set common things like header credentials, exception handling and throttling:
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* MyService.*(..))" />
<aop:aspect id="throttling" ref="throttlingAdvisor">
<aop:around pointcut-ref="pointcut" method="doThrottle" />
</aop:aspect>
<aop:aspect id="errorHandling" ref="errorHandlingAdvisor">
<aop:around pointcut-ref="pointcut" method="handleExceptions" />
Each aspect refers to a POJO bean, these beans include the method stated in the configuration with the method parameter type of org.aspectj.lang.ProceedingJoinPoint, this is used to extract the arguments of the method I'm intercepting.
We have one of these for each of the web service clients (in an applicationContext-webservicename.xml). This xml file is included in the packaged JAR which is included in the customer facing application and imported into the main applicationContext.xml loaded by the web.xml of the customer facing application.
We have a number of unit tests for these web clients, they all pass proving there's nothing wrong with them individually. When all the services are included in the customer facing applications we get a java.lang.NoClassDefFoundError: ProceedingJoinPoint exception when it starts up (we're using tomcat 5.5 with JDK1.5.0_17).
I looked up the JavaDoc for java.lang.NoClassDefFoundError just in case it had a special meaning, looks like the JVM thinks the class does not exist. I then looked for the jar which contains the classes it's claiming it cannot find (aspectjrt-1.5.4.jar and aspectjweaver-1.5.4.jar), there is a duplication of these classes so I tried removing each jar in turn to see what would happen, exactly the same error.
Am I missing a required dependency? Is there a common cause to this problem (I've searched for this yesterday not finding much)? Any help would be most appreciated.
After all this time we managed to find the solution to this problem, we use Bamboo to build our projects when a SVN commit is detected. Although the bamboo environment was set up to match our development machines when it built a dependent project it produced this weird problem.
We're still not sure why it did this, however in the meantime we're manually building and deploying this particular project.
My advice to anyone experiencing a similar problem, just isolate yourself from internal maven repos and rebuild all your projects locally.
Thanks for everyone's help.
Could be a class loader issue. Where are the AspectJ JARs? If you have them in your WEB-INF/lib now, perhaps you could try copying them to the Tomcat common/lib and see if that helps.
It could be that the app server class loader needs them on startup, but the application class loader hasn't gotten them from WEB-INF because it's lower in the class loader hierarchy.
Only add aspectjrt.jar to the server/lib folder, NOT the aspectjweaver.jar. Duplicate classes can also lead to confusion. The runtime jar (the "rt" stands for runtime) is supposed for the runtime. The weaver jar is used for compile/weave time. Are you using LTW or CTW?
Related
I've made a trivial RESTful service on a JBoss server that just says "hello" when it receives any request. This part works and it is already deployed.
To go further with my project I need to log. The other applications on the server use log4j configured by a log4j.xml placed on a specific folder on the server.
For an offline project I'm used to have a runnable main method that in this case I would use to execute DOMConfigurator.configure(filepath) (where filepath is the log4j.xml) and I will be expecting to log with those settings.
However, since this is a deployed service (and since I'm not skilled enough to figure it myself) how would I so such a thing?
The question in my opinion could be interpreted in two ways:
How do I run some code "for sure" when I deploy something (in similar way to a main method) ? Do i need something like spring-boot?
How do I setup log4j on a deployed service on JBoss?
(I don't know if one question excludes the other...)
Thanks for the help!
1) If you want to run some code "for sure" you can create #PostConstruct method in one of your beans. Both Spring and EJB support it.
2)As for log4J configuration it should be enough to put it in classpath and add corresponding dependencies, no explicit configuration of path should be needed.
I work on a web application that calls multiple web service clients from within its code.
Each web service has some common namespaces, however I am currently mapping these namespaces to different packages when I generate each client
e.g.
Web Service 1's namespace1 -> com.company.webservice.client1.service
Web Service 2's namespace1 -> com.company.webservice.client2.service
Where namespace1 refers to the same namespace URL.
Using Wsdl2Java's namespace2package option:
// Web Service Client 1's namespace parameter
--namespace2package http://www.multispeak.org/Version_3.0=com.company.webservice.client1.service
// Web Service Client 2's namespace parameter
--namespace2package http://www.multispeak.org/Version_3.0=com.company.webservice.client2.service
I can generate web service client code for these services without issue and I can call each client fine on their own, so long as only one of the generated client jars is on the classpath for the given web service call. However, if I place both web service client jars on the classpath, only one of the web service clients will work (the one where its respective client jar is first on the class path).
The other web service client fails when trying to call it, with the following exception:
java.lang.ClassCastException: com.company.webservice.client1.service.impl.GetAllMetersResponseDocumentImpl cannot be cast to com.company.webservice.client2.service.GetAllMetersResponseDocument
I've obfuscated some of the actual values above.
So, the issue seems to be regarding how Axis2/XMLBeans looks up the appropriate class to match the given XML to parse from.
I can change the namespace mappings so that they match each other and it works fine after that. However, the downside to that is that I have multiple web service client jars containing the same generated code in the same package structure, whereby these classes will only be instantiated from the models from the first client jar it finds on the classpath.
Is there a way of doing this so that I can keep the different namespaces for each web service client jar?
Or am I simply going to be forced to have each namespace mapped to the same package for every client that uses that namespace?
Hopefully the issue makes sense, but if I need to provide anything else that would assist, please let me know and I will expand this question with further details, but hopefully someone with knowledge of Axis2/XMLBeans/web service client generation using Wsdl2Java should be able to answer this without much further info.
UPDATE 1:
I finally gave in and just made all of the namespace mappings point to the same package rather than bespoke per web service client and took the hit of having multiple copies of the same class in various JARs on the classpath. Not as elegant as I would have liked, but at least it works.
If anyone can come up with a better solution that allows me to use bespoke copies in each client instead, please do let me know.
UPDATE 2:
This approach equally does not work as the two web services, despite using the same namespace, produce different versions of the namespace's models which now causes compile time errors dependent on classpath order. So... Back to square one...
I have the feeling you have two versions of the GetAllMetersResponseDocument in each jar. What is happening is that it is loading the interface from the opposite jar file which ends up in Class cast exception. I may be wrong.
This is the reason why it works when you have one of the jars loaded.
There is also this option where you can have Classloader isolation, resulting in two different classloaders for the two jars you can again end up with two objects of the same type that can not be casted to each other.
UDATE
I actualy just checked if axis2 has classloader isolation defined by default and it does. https://axis.apache.org/axis2/java/core/faq.html read Class Loading
Issues
I believe also reading service and module isolation from this article will help you.
https://www.developer.com/open/article.php/10930_3589126_2/Avoiding-Mistakes-Made-Using-Axis2.htm
I'm trying to create a portlet with liferay 6.2 and using spring. If I create a bean without using constructor-arg or factory-method then everything works fine. But if I use either of these then I get exceptions when the portlet is deployed.
an example:
the exception I'm getting is:
01:28:21,884 ERROR [ContextLoader:323] Context initialization failed
java.lang.IncompatibleClassChangeError: class org.springframework.core.LocalVariableTableParameterNameDiscoverer$ParameterNameDiscoveringVisitor has interface org.springframework.asm.ClassVisitor as super class
I realize that this can be caused by having 2 versions of ams, but im using the spring jars that come with liferay.
You give an option yourself - duplicate classes. But without knowing how you build and what you're doing, there's hardly anything to do apart from asking you to make extra extra extra sure that you don't have duplicate resources on the classpath:
Check your deployed web application (once it's deployed to your application server) and its WEB-INF/lib folder for such duplicates. They might come in only during the buildprocess, e.g. they might not be in your IDE's workspace. Or Liferay might inject them (due to declared dependencies) during deployment.
You'll have to figure out how (and in which phase) those resources get there, then eliminate that option (e.g. through proper maven scope, e.g. "provided")
Hi I am currently using the JodaTime library in my NetBeans restful web services on GlassFish Server using Jackson libraries.
I get a java.lang.NoClassDefFoundError for org/joda/time/ReadablePartial when I try to create an instance of a class that uses the JodaTime library in one of the Resource files.
E.g:
In the studentResource file:
Controller c = new Controller();
Where the Controller class imports and uses JodaTime libraries
I have checked that the libraries I needed are in the project.
In fact, if I run a separate project outside of the restful web services, everything runs smoothly. Is there an additional classpath issue that I have to address?
In case someone stumbles upon the same problem using Spring:
This problem comes up if you are trying to map JSON to a Java object using Jackson either via #RequestBody annotation on controller parameter or manually deserializing using an ObjectMapper().readValue(json, Class.class). Everything works fine on local machine but when deploying application to GlassFish deserialization fails.
Keeg's workaround to copy Joda-Time.jar to glassfish/modules and restarting fixes the issue.
There seems to be a bug open on Jira about this issue:
https://java.net/jira/browse/GLASSFISH-20808
Just in case someone else stumbles upon this problem, we had a similar issue with the combination of Glassfish 3.1.1, Jersey and use of Joda time. Stacktraces like this:
Caused by: java.lang.ClassNotFoundException: org.joda.time.ReadableInstant not found by jackson-mapper-asl [128]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1460)
etc.
The workaround I just found was dumping a copy of our joda-time jar into glassfish/modules. Not exactly pretty, but...
Ok I found the solution. Apparently all I needed to do was to move the jar file up in the list of libraries/jar files. I do that in the library tab in the project's properties. More specifically, the jar file has to be moved above the REST libraries.
I am writing an application that invokes an Oracle web service. The web service client code was provided me.
This application uses a custom subclass of URLClassLoader to load jars at run-time. Running the unit tests from my local machine works fine, however when I deploy the application on the server and run it, I get the following error. Other classes/jars are loading fine through the custom ClassLoader.
Not sure why this is happening? Maybe FactoryFinder is using a separate ClassLoader instance? Any help is appreciated. Thanks!
javax.xml.rpc.ServiceException: Provider oracle.j2ee.ws.client.ServiceFactoryImpl not found
at javax.xml.rpc.FactoryFinder.newInstance(FactoryFinder.java:44)
at javax.xml.rpc.FactoryFinder.find(FactoryFinder.java:137)
at javax.xml.rpc.ServiceFactory.newInstance(ServiceFactory.java:69)
at com.mycomp.myapp.oracle.client.TSClient.<init>(TSClient.java:34)
at com.mycomp.myapp.oracle.LaborHours.update(LaborHours.java:92)
at com.mycomp.myapp.oracle.OracleConnection.updateMetrics(OracleConnection.java:73)
at com.mycomp.myapp.Project.crawl(Project.java:150)
at com.mycomp.myapp.Main.main(Main.java:302)
This is the conclusion I came up with.
ServiceFactory uses it's own class loading mechanism (which apparently is a different instance than my custom class loader).
I had to use this hack http://forums.sun.com/thread.jspa?threadID=300557 to add the jars to the system class loader's class path.