There was some internal debate about Java coding conventions. For reference, here are the conventions of some well-known groups or projects:
... until the collector arrives ...
There was some internal debate about Java coding conventions. For reference, here are the conventions of some well-known groups or projects:
I was using a copy task to copy a particular file using <fileset file="${bea-xbean-jar}"/>, but the file consistently failed to be copied. The problem was that the variable bea-xbean-jar was defined in an external build.properties file, but the line contained a trailing space.
On the topic of null pointer exceptions, I tried to create a JWS web service that accepted a POJO argument that had a SOAPElement property. It compiled and deployed fine, but when I invoked the web service, I got the dreaded NPE:
java.lang.NullPointerException at test.TestServiceImpl.operation1(TestServiceImpl.java:17) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at
java.lang.reflect.Method.invoke(Method.java:585) at
weblogic.wsee.component.pojo.JavaClassComponent.invoke(JavaClassComponent.java:91) at
weblogic.wsee.ws.dispatch.server.ComponentHandler.handleRequest(ComponentHandler.java:68) at
weblogic.wsee.handler.HandlerIterator.handleRequest(HandlerIterator.java:127) at
weblogic.wsee.ws.dispatch.server.ServerDispatcher.dispatch(ServerDispatcher.java:84) at
weblogic.wsee.ws.WsSkel.invoke(WsSkel.java:60) at
weblogic.wsee.server.servlet.SoapProcessor.handlePost(SoapProcessor.java:66) at
weblogic.wsee.server.servlet.SoapProcessor.process(SoapProcessor.java:44) at
weblogic.wsee.server.servlet.BaseWSServlet$AuthorizedInvoke.run(BaseWSServlet.java:124) at
weblogic.wsee.server.servlet.BaseWSServlet.service(BaseWSServlet.java:53) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
If I declare the service with a SOAPElement as a direct parameter, it works as advertised.
I struggled with the sample web service provided with the XFire distribution. The problem was that I placed the XFire services configuration XML in the WAR's META-INF directory instead of within classes/META-INF. Incidentally, I discovered that in a servlet context getClass().getClassLoader().getResource() does not search the root context directory for resources -- it only searches the classes and lib subdirectories. To get a resource from the root, you must use getServletContext().getResource(). After this short detour, the XFire service worked.
I was unable to get the XFire test framework run the service. It throws a null pointer exception:
java.lang.NullPointerException
at org.codehaus.xfire.handler.LocateBindingHandler.invoke(LocateBindingHandler.java:41)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:97)
at org.codehaus.xfire.transport.DefaultEndpoint.onReceive(DefaultEndpoint.java:57)
at org.codehaus.xfire.transport.AbstractChannel.receive(AbstractChannel.java:38)
at org.codehaus.xfire.test.AbstractXFireTest.invokeService(AbstractXFireTest.java:116)
at org.codehaus.xfire.test.AbstractXFireTest.invokeService(AbstractXFireTest.java:91)
at mm_test.BookService_Test.testBookService(BookService_Test.java:18)
As I noted in a previous entry, the WebLogic JWSC task will not run unless the BEA JARs are in the classpath of the JVM that his hosting Ant. Here is a way to make that happen in the context of an Ant script:
<path id="bea-classpath">
<pathelement location="${bea-wls-home}/server/lib/weblogic.jar"/>
<pathelement location="${bea-wls-home}/server/lib/webservices.jar"/>
</path>
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask"
classpathref="bea-classpath"
/>
<target name="~jwsc">
<delete dir="build"/>
<mkdir dir="build"/>
<jwsc
srcdir="src"
destdir="build"
classpathref="bea-classpath"
verbose="true"
>
<jws file="test/TestServiceImpl.java"/>
</jwsc>
</target>
<target name="jwsc">
<java classname="org.apache.tools.ant.launch.Launcher" fork="true">
<classpath>
<pathelement path="${java.class.path}"/>
<path refid="bea-classpath"/>
</classpath>
<sysproperty key="ant.home" value="${ant.home}"/>
<arg value="-buildfile"/>
<arg value="${ant.file}"/>
<arg value="~jwsc"/>
</java>
</target>
I tried to create a web service that accepts an XMLBean as its sole input parameter and produces an XMLBean as its return value. JWSC was able to compile it, but when I invoked the service I got a SOAP fault reporting the stack trace:
com.bea.xml.XmlRuntimeException: java.lang.InstantiationException: com.bea.xml.XmlObject
at com.bea.staxb.runtime.internal.ClassLoadingUtils.newInstance(ClassLoadingUtils.java:137)
at com.bea.staxb.runtime.internal.ByNameRuntimeBindingType.createIntermediary(ByNameRuntimeBindingType.java:196)
at com.bea.staxb.runtime.internal.AttributeUnmarshaller.unmarshal(AttributeUnmarshaller.java:36)
I guess the deserializer is looking for a no-arg constructor for XmlObject. As of WLS 9.0, there is no longer a way to register a custom deserializer to overcome the absence of a no-arg constructor/bean pattern.
It would appear that others are having similar problems.
I tried to follow an example from the WLS9.1 web services documentation that uses the JWSC Ant task. I got the error message:
Deployment descriptor: tempdir\_9tdo9x\web.xml does not exist.
I found a message in the BEA forums that suggested using BEA's setDomainEnv command before running the Ant task. This worked, but complicates using a stock "headless" Ant build (e.g. running within Eclipse or CruiseControl). I had found a similar bug in WLS8.1's source2wsdd Ant task (the other WLS8.1 Ant tasks had no such dependencies).
I ran Ant with -debug and saw this:
Deployment descriptor: C:\DOCUME~1\MM\LOCALS~1\Temp\_9tdo9x\web.xml does not exist.
at org.apache.tools.ant.taskdefs.War.setWebxml(War.java:84)
at weblogic.wsee.tools.anttasks.JwscTask.jar(JwscTask.java:397)
at weblogic.wsee.tools.anttasks.JwscTask.pkg(JwscTask.java:331)
at weblogic.wsee.tools.anttasks.JwscTask.execute(JwscTask.java:166)
the option explode="true" on the jws subelement of the jwsc task, then the process seems to proceed a little bit further, but then dies for a completely different reason:
java.lang.AssertionError: java.lang.ClassNotFoundException: weblogic.j2ee.descriptor.ApplicationBeanImpl
at weblogic.descriptor.internal.DescriptorImpl.createRootBean(DescriptorImpl.java:357)
at weblogic.descriptor.DescriptorManager.createDescriptorRoot(DescriptorManager.java:328)
at weblogic.wsee.tools.jws.build.EarFile.getApplicationBean(EarFile.java:127)
at weblogic.wsee.tools.jws.build.EarFile.addWebModule(EarFile.java:61)
at weblogic.wsee.tools.anttasks.JwscTask.addToEar(JwscTask.java:230)
at weblogic.wsee.tools.anttasks.JwscTask.execute(JwscTask.java:167)
That last one looks like a typical Ant classloader problem since the named class actually *does* exist in weblogic.jar. I looked at the code for DescriptorImpl.createRootBean() and found that it was hard-coded to use the thread's class loader (instead of using its own class loader). In an Ant context, the implications of this are complex, resulting in the exhibited failure.
[I later found a workaround.]
I am still having troubles writing a web service for use in esi.execute. The requirements, and problems, are recounted in the following table.
Requirement | WLS 8.1 | WLS 9.1 |
---|---|---|
deployable on WLS | ok | ok |
can be built using Ant | ok | JWSC task has issues (see below) |
primary web service defined as a Java interface | finicky, but possible | ok |
supports XMLBeans as parameters/result (for compatibility with the ALDSP 2.0 stack) | yes, through custom serializers | The docs suggest that XMLBeans can be used, but are
deprecated. However, I can't get it to work (see below). The
docs also mention using a generic SOAPElement for untyped data, but this
would require two in-memory copies of the XML document (i.e. the
SOAPElement implementations, and our own implementation in XMLBeans or
whatever). WLS 9.1 no longer supports custom serializers. |
supports arguments that are partly strongly typed and partly untyped (i.e. "raw XML") | ||
supports streaming (a "nice-to-have") | yes, through custom serializers | no |
supports Java 1.5 | no | yes |
Whenever I am working in an Eclipse project that references one or more of the WebLogic JARs, the IDE performance is extremely poor. The IDEA seems to be consuming nearly 50% of the CPU in the background doing something -- scanning the huge weblogic.jar perhaps? Code completion is especially affected.
The best place to supplement the CLASSPATH used by the WebLogic server is to edit %WLS_HOME%/common/bin/commEnv.cmd (or .sh on Unix) -- at least if you want the change to apply to all WebLogic domains.
I found a note about running XFire on WebLogic 8.1. It says that XFire requires a newer version of the standard java QName class, and that this can only be accomplished by adding that class to the front of WebLogic's classpath. I wonder if this is the same problem that we were hitting with JDK 1.5?
Following this hint, I determined inspected the serialization versions of the various versions of the class javax.xml.namespace.QName:
I was surprised to see the XFire and BEA versions had the same version. However, using javap on the three files revealed that the XFire and 1.5 versions had a new method, getPrefix().
So... I created a JAR with just the 1.5 version and threw it in JRockITs jre/lib/endorsed directory. The WebLogic server failed to start up with an UnsupportedClassVersionError for version 49.0. Next, I got the 1.5 source for QName and compiled it with a 1.4 compiler, and then put this class in a jar in JRockITs endorsed directory. The server launched, and I was able to use a Java 1.5 client to access an AquaLogic DSP service. Presumably, XFire would work as well, but I haven't tried that yet.
I tried again to find an idiomatic way to create web services for BEA that:
So far, 1, 2, 3, 4, 5, and 6 seem in reach, but 7 remains elusive. 7 can be achieved by using BEA's proprietary .JWS format, but then some of the other goals are missed (especially 1).
Most of the time today was spent wrestling with, and finally identifying an apparent bug in WLS. See the BEA newsgroup posting:
http://forums.bea.com/bea/thread.jspa?threadID=200079921
Other BEA findings...
As of 9.1, BEA deprecates the use of XMLBeans in Web Services: http://e-docs.bea.com/wls/docs91/notes/new.html. Does that mean you can't use XMLBeans at all, or just that you shouldn't declare a type as a generic XmlObject?
How do you configure and recover initialization parameters for web services?
Whether generating a service from WSDL (using WSDL2Service) or from Java (using SERVICEGEN), the deployed WSDL does not generate unique SOAPActions for each operation. In fact, they are all blank. As a result, a client is not able to invoke any operation other than the first. Note that even when WSDL2Service is given a WSDL that *does* correctly specify SOAPActions, the deployed service still uses blank actions.
If you write a web service using BEA's proprietary JWS format, then correct SOAPActions are generated.
There are some BEA forum posts about this::
When using SERVICEGEN, make sure that the target EAR file does not exist prior to running the task. Otherwise, the task will update the existing EAR file, and may not actually replace the WebService class. In my case, I had added some methods, but since the class file was not updated, the methods did not appear. I got the error message:
at weblogic.webservice.server.WebServiceFactory.registerOperation(Lweblogic.management.descriptors.webservice.OperationMBean;Lweblogic.webservice.Port;Lweblogic.webservice.InvocationHandler;Ljava.util.Map;Lweblogic.xml.schema.binding.TypeMapping;Ljava.lang.String;Ljava.util.HashSet;ZV(WebServiceFactory.java:869)
Having discovered that there is a bug in SERVICEGEN where generated web service operations have blank SOAPActions, and that JWS files generated in the workshop do not exhibit this problem, I decided to see how the latter were being annotated. First I poked around in the generated EAR file looking for some kind of deployment descriptor. Nothing. In fact, all I could find was a class file, sitting in the .workshop directory in the JAR file (not even in WEB-INF!). I suspected that BEA was generating non-standard class properties in the class file, so I wrote a short program using BCEL to dump the properties. Lo and behold! There is non-standard property called com.bea.wlw.annotation.v2, that contains a WSDL fragment, some schema, and a bunch of binary (serialized?) stuff. The upshot is that only the BEA compiler can be used to generate these classes (or perhaps only the WebLogic workshop itself).
I found JScience, a set of Java libraries with functionality related to linear algebra. Of interest are the facilities for units of measurement, a monetary data type, and credible rational number types to replace Java's hokey BigInteger and BigDecimal types.
Trac
Wing pointed us to Trac, and open-source combined wiki and issue-tracking system with Subversion integration.
In JIRA, an administrator can edit the work logs of an issue by hitting a URL like this:
http://jira-context/secure/admin/editworklog.jsp
e.g.
In the console:
Many of these settings can be figured out by browsing the AD LDAP tree using an LDAP browser.
WebLogic 8.1 claims to support JAX-RPC 1.0, but I found that the implementation of the ServiceLifeCycle interface always passed null as the context, so you cannot recover the servlet context. Later investigation found that BEA's documentation noted this deficiency. I need the servlet context to recover the UserPrincipal object.
The WebLogic 9.0 documentation is evasive on the topic. The documentation emphasizes the new .JWS functionality which is not covered by any standard. It claims the JAX-RPC 1.1 but all the examples only deal with client side code. Indeed, all methods of generating web services other than through .JWS files are deprecated. The documentation also claims that Enterprise Web Services 1.0 is supported but, again, none of the examples or tools seem to agree with that statement.
This morning when I opened my Eclipse workspace, one of my RCP projects had problems with its build paths. On the 'libraries' property page, the entry that is normally called 'Plug-in Dependencies' was labelled 'org.eclipse.pde.core.requiredPlugins (unbound)' and the container was empty. After much experimenting, I discovered I could fix the problem by closing and re-opening the project, followed by a 'clean'.
My workbench showed errors on start-up:
Error 2006-01-12 08:07:48.184 An internal error occurred during: "Initializing Java tooling".
java.lang.NullPointerException
at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:229)
at org.eclipse.wst.common.internal.emf.resource.TranslatorResourceImpl.setID(TranslatorResourceImpl.java:310)
...[snip]...
Error 2006-01-12 08:07:48.169 Problems occurred when invoking code from plug-in: "org.eclipse.core.resources".
java.lang.ArrayIndexOutOfBoundsException: 4
at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:229)
at org.eclipse.emf.common.notify.impl.NotificationImpl.dispatch(NotificationImpl.java:931)
at org.eclipse.wst.common.componentcore.internal.impl.ComponentResourceImpl.setComponent(ComponentResourceImpl.java:216)
at org.eclipse.wst.common.componentcore.internal.impl.ResourceTreeNode.findMatchingVirtualPathsSet(ResourceTreeNode.java:210)
...[snip]...
Warning 2006-01-12 08:07:39.347 A workspace crash was detected. The previous session did not exit normally.
although as far as I can remember the previous session did exit normally.
I tried to use the Eclipse JST wizard to generate a web service. I kept getting the error:
java.lang.NoClassDefFoundError: javax/activation/DataSource
whenever during WSDL generation (or parsing). A Google search revealed that this is a very common problem -- see, for example, Eclipse Bugzilla 104993. I couldn't find a solution on the Web, but I discovered that if I added activation.jar from the JavaBean Activation Framework to my project build path, everything worked. I had to exit and re-enter Eclipse for the change to work. Also, I found that after I had run the wizard successfully once, it worked forever more (i.e. without having to add activation.jar to a project, and in following Eclipse sessions). Something is being cached somewhere.
If you use the Eclipse RCP binary instead of the RCP SDK, there are various problems in the development environment. Many of the plug-in property pages were truncated, displaying only the top few widgets (and cutting off the last widget shown). Also, the extensions panel was not showing the various extension attribute types under the 'New' context menu (e.g. category, view, and stickyView were not available for extensions of type org.eclipse.ui.views).