22
Dec

Stop editing setDomainEnv. There's a better (and safer) way: setUserOverrides

For a long time people have been editing core WLS files like setDomainEnv.sh or .cmd and setSOADomainEnv.sh or .cmd to specify startup parameters (e. g. system properties) and configurations like heap memory size or garbage collection arguments.

Starting with Oracle WebLogic Server 12.1.2 and available also on Oracle WebLogic Server 12.1.3 what also applies to the whole 12c middleware family (SOA, OSB, BPM, MFT, and so on…), we now have the option of creating a file called setUserOverrides.cmd (on Windows) or setUserOverrides.sh (Linux/Unix) and keep such custom configurations and properties in this file. This allows for a centralized place to put custom configuration, making it easily findable and upgrade safe as the file is note created by default.

From the official WLS documentation: To enable you to customize server startup parameters that apply to all servers in a domain, you can create a file called setUserOverrides.cmd(Windows) or setUserOverrides.sh (UNIX) and configure it to, for example, add custom libraries to the WebLogic Server classpath, specify additional java command line options for running the servers, or specify additional environment variables. Any customizations you add to this file are preserved during domain upgrade operations, and are carried over to remote servers when using the pack and unpack commands.

Bellow we have a sample for the contents of this file specifying heap memory size and garbage collection parameters (the sample is for Windows, for Linux/Unix instead of set you'd use export):

set USER_MEM_ARGS=-Xms2048M -Xmx2048M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+UseParallelGC -XX:+UseParallelOldGC -verbose:gc -XX:+PrintGCDetails -XX:-PrintGCDateStamps -Xloggc:/temp/gc/wls_pre_sizing_jms.log

Using this approach makes the configuration available in a standard way, making it standard among different environments and installations and also protects your efforts during upgrades.


free b2evolution skin
26
May

Web Service clients running in a Java EE container - what can the container do for you when it acts as a web service client?

When your application is a Java EE application, for example, a Web application or an EJB application and you have to communicate with web services the application running inside the container act as a client.

Remember it can also be a client Java EE application and then run on the client container. By running on a client container, it can leverage lots of the things a Java EE application running on a server environment can like, for example, annotations.

Returning to the original subject, when the Java EE application acts as a client of a web service, you can use the @WebServiceRef to inject the reference to the Web Service client. By injecting the reference using annotations, you allow the container to take care of the client and you can leverage the container to make configurations and other stuff declaratively instead of doing that via code.

Bellow we have an example of the injection of a web service reference in a servlet and later usage of the service in the servlet’s code:

package br.com.amadei.blog.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.WebServiceRef;

import br.com.amadei.blog.ws.HelloWorldService;
import br.com.amadei.blog.ws.HelloWorldServiceService;

@WebServlet("/WsClientServlet")
public class WsClientServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@WebServiceRef(name = "HelloWorldService")
	private HelloWorldServiceService service;

	public WsClientServlet() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) 
                        throws ServletException, IOException {
		HelloWorldService port = service.getHelloWorldServicePort();

		PrintWriter out = response.getWriter();

		out.println("<h2>");
		out.println("Web Service response: "
				+ port.sayHello(request.getParameter("name")));
		out.println("</h2>");

	}

}

 

Take a closer look at the @WebServiceRef annotation in the code above. Pay attention that such annotation has an attribute name with a string defining it. This string defines the name of the service reference and this name is what we use to link the service reference annotation with its definition in a deployment descriptor.

As the sample application is a web application, the service reference is declared in the weblogic’s web descriptor: weblogic.xml, inside WEB-INF. Bellow we have a sample of this weblogic.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app ...>
    <wls:weblogic-version>12.1.2</wls:weblogic-version>
    <wls:context-root>HelloWorldWebServiceClient</wls:context-root>
    <wls:service-reference-description>
        <wls:service-ref-name>HelloWorldService</wls:service-ref-name>
        <wls:wsdl-url>http://host:port/HelloWorldWebService
           /HelloWorldServiceService?WSDL</wls:wsdl-url>
    </wls:service-reference-description>
</wls:weblogic-web-app>

 

This descriptor already shows something very important about the power that comes with the usage of the application server + annotation + deployment descriptor: you are referencing the WSDL's URL via the XML descriptor, so if you have to change the endpoint to promote the application among different environments, you can do that using the deployment descriptor without touching code or resorting to custom solutions like custom configuration files, custom system properties and so on. To make things even simpler, you can use deployment plans to update such properties so you can do that without touching code:

<?xml version='1.0' encoding='UTF-8'?>
<deployment-plan ...>
  <application-name>HelloWorldWebServiceClient.war</application-name>
  <variable-definition>
    <variable>
      <name>ServiceReferenceDescription_HelloWorldService_WsdlUrl_140050201249438</name>
      <value>http://qaenv:7001/HelloWorld/HelloWorldServiceService?WSDL</value>
    </variable>
  </variable-definition>
  <module-override>
    <module-name>HelloWorldWebServiceClient.war</module-name>
    <module-type>war</module-type>
    <module-descriptor external="false">
      <root-element>weblogic-web-app</root-element>
      <uri>WEB-INF/weblogic.xml</uri>
      <variable-assignment>
        <name>
           ServiceReferenceDescription_HelloWorldService_WsdlUrl_140050201249438
        </name><xpath>/weblogic-web-app/service-reference-description
          /[service-ref-name="HelloWorldService"]/wsdl-url</xpath>
        <origin>planbased</origin>
      </variable-assignment>
    </module-descriptor>
  </module-override>
  <config-root>/app/config/deployments/HelloWorldWebServiceClient.war/plan</config-root>
</deployment-plan>

 

That’s it. I expect this post gave you an overview on how to leverage the application server capabilities, WebLogic’s in the case shown, to configure Web Services clients in a declarative manner and write less code.


free b2evolution skin
3
May

Applying WS Policies to JAX-WS Web Services in WebLogic Server

When developing a JAX-WS web service to be deployed to a WebLogic Server, you can apply WS-Policies to it. WLS ships with some pre-defined policies that you can specify without having to point to some physical policy file. They are already deployed by WLS.

On the other hand, you can define a policy file and apply this file to the Web Service if the ones already present in WLS does not work for you. In this case, you can create a file like the one bellow, to request username token authentication:

<?xml version="1.0"?>
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512">
 <sp:SupportingTokens>
  <wsp:Policy>
   <sp:UsernameToken
    sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512/IncludeToken/AlwaysToRecipient">
    <wsp:Policy>
     <sp:WssUsernameToken10 />
    </wsp:Policy>
   </sp:UsernameToken>
  </wsp:Policy>
 </sp:SupportingTokens>
</wsp:Policy>


After you have the policy file, in our case a very simple username token policy, you place it in WEB-INF/policies for Web applications or META-INF/policies for EJB JARs and shared libraries.

Now it’s just a matter of annotating the web service class. You annotate it with weblogic.jws.Policies and weblogic.jws.Policy annotations and specify as the policy uri the policy XML file name as we can see bellow:

package br.com.amadei.ws.secure;

import javax.jws.WebMethod;
import javax.jws.WebService;

import weblogic.jws.Policies;
import weblogic.jws.Policy;

@WebService
public class SecureWS {

	@WebMethod
	@Policies( { @Policy(uri = "policy:usernametoken.xml") } )  
	public String sayHello(String name) {
		return "Hello, " + name;
	}

}


After that, you just deploy the application and the policy is added to the Web Service’s WSDL and enforced at runtime.

For more information, plase check the official documentation here.


free b2evolution skin
12
Feb

The danger of importing multiple XSDs from the same namespace

When you define a Web Service interface with WSDLs and XSDs, you need to be careful on the structure of such elements, so I recommend you to avoid at all costs importing more than one XSD from the same namespace.

Importing multiple XSDs from the same namespace is not prohibited by the specification but it’s also not clear how parsers should handle them, so some parsers take only the first import into consideration while others take all of the imports. This is the worst situation ever as for some situations you will face errors and in others it will work.

As an example, take the following WSDL:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:tns="http://www.example.org/NewWSDLFile/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="NewWSDLFile"
	xmlns:schema="http://www.example.org/schema"
	targetNamespace="http://www.example.org/NewWSDLFile/">

	<wsdl:types>
		<xsd:schema targetNamespace="http://www.example.org/NewWSDLFile/">

			<xsd:import schemaLocation="Schema1.xsd" namespace="http://www.example.org/schema"/>
			<xsd:import schemaLocation="Schema2.xsd" namespace="http://www.example.org/schema"/>
			
			<xsd:element name="NewOperation">
				<xsd:complexType>
					<xsd:sequence>
						<xsd:element name="in" type="schema:MyType1" />
					</xsd:sequence>
				</xsd:complexType>
			</xsd:element>
			<xsd:element name="NewOperationResponse">
				<xsd:complexType>
					<xsd:sequence>
						<xsd:element name="out" type="schema:MyType2" />
					</xsd:sequence>
				</xsd:complexType>
			</xsd:element>
		</xsd:schema>
	</wsdl:types>

	<wsdl:message name="NewOperationRequest">
		<wsdl:part element="tns:NewOperation" name="parameters" />
	</wsdl:message>

	<wsdl:message name="NewOperationResponse">
		<wsdl:part element="tns:NewOperationResponse" name="parameters" />
	</wsdl:message>

	<wsdl:portType name="NewWSDLFile">
		<wsdl:operation name="NewOperation">
			<wsdl:input message="tns:NewOperationRequest" />
			<wsdl:output message="tns:NewOperationResponse" />
		</wsdl:operation>
	</wsdl:portType>

	<wsdl:binding name="NewWSDLFileSOAP" type="tns:NewWSDLFile">
		<soap:binding style="document"
			transport="http://schemas.xmlsoap.org/soap/http" />
		<wsdl:operation name="NewOperation">
			<soap:operation soapAction="http://www.example.org/NewWSDLFile/NewOperation" />
			<wsdl:input>
				<soap:body use="literal" />
			</wsdl:input>
			<wsdl:output>
				<soap:body use="literal" />
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>

	<wsdl:service name="NewWSDLFile">
		<wsdl:port binding="tns:NewWSDLFileSOAP" name="NewWSDLFileSOAP">
			<soap:address location="http://www.example.org/" />
		</wsdl:port>
	</wsdl:service>

</wsdl:definitions>


If you validate this WSDL in Eclipse, it validates OK, however if you try to create Java classes to it using wsimport command, it presents some warnings indicating it can't find some of the types. Actually you see that the problems are found on the types of the second XSD imported, showing it was silently ignored by the parser. Bellow we see the warnings:


[WARNING] src-resolve: Cannot resolve the name 'schema:MyType2' to a(n) 'type definition' component.
line 24 of file:/D:/temp/NewWSDLFile.wsdl#types?schema1

[WARNING] src-resolve: Cannot resolve the name 'schema:MyType2' to a(n) 'type definition' component.
line 24 of file:/D:/temp/NewWSDLFile.wsdl#types?schema1

For other parsers it will not be just a warning, but an error that will make it impossible to consume the web service. For example, if you try to validate this WSDL via WS-I basic profile validation tool, it fails indicating it can’t find the types of the second XSDs.

So, all that said, avoid having multiple XSDs from the same namespace imported by another WSDL or XSD or you're going to have some hard times.


free b2evolution skin
29
Dec

What happened to Eclipse’s Generate XML from XSD Schema menu?

Eclipse and Oracle Enterprise Pack for Eclipse have a very helpful option to generate XML from a XSD as we can see bellow:

 

Sometimes, however, this menu just does not appear for a XSD file and this is due to the fact that the XSD file does not have the XML prolog, like the one bellow:

<?xml version="1.0" encoding="UTF-8"?>

 

Adding the prolog back to the XSD file, makes Eclipse treat the file as an XSD again and the Generate > XML File… menu will be back.

When you need to generate a XML from a XSD and the menu isn’t there, it can become an awful situation and this tip will help you to have the menu back.


free b2evolution skin

:: Next >>