Sunday, September 27, 2015

Duplicate class while generating artifacts from XSD

Given the following XSDs:

Request.xsd
 <xsd:element name="HelloWorldReqType">
  <xsd:complexType>
   <xsd:sequence>
    <xsd:element id="name" name="name" maxOccurs="1" minOccurs="1"/>
    <xsd:element id="gender" name="gender" maxOccurs="1" minOccurs="1"/>
   </xsd:sequence>
  </xsd:complexType>
 </xsd:element>
Response.xsd
 <xsd:element name="HelloWorld_response">
  &lt xsd:complexType>
   <xsd:sequence>
    <xsd:element id="greetings" name="greetings" maxOccurs="1" minOccurs="1"/>
   </xsd:sequence>
  </xsd:complexType>
 </xsd:element>
I should not explicitly define the same set of request and response elements in WSDL while I have chosen to import them. This is what I did to the WSDL:
  <wsdl:types>
   <xsd:schema targetNamespace="http://www.example.org/HelloWorld/">
     <xsd:import namespace="http://www.example.org/HelloWorldReq" schemaLocation="../resources/HelloWorldReq.xsd"/>
     <xsd:import namespace="http://www.example.org/HelloWorldRes" schemaLocation="../resources/HelloWorldRes.xsd"/>
     <xsd:element name="helloWorld_request">
      <xsd:complexType>
       <xsd:sequence>
        <xsd:element name="name" type="xsd:string" maxOccurs="1" minOccurs="1"/>
        <xsd:element name="gender" type="xsd:string" maxOccurs="1" minOccurs="1"></xsd:element>
       </xsd:sequence>
      </xsd:complexType>
     </xsd:element>
     <xsd:element name="helloWorld_response">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="greetings" type="xsd:string" maxOccurs="1" minOccurs="1"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>    
    </xsd:schema>
  </wsdl:types>
Line 3 and 4 are the import statement that import the 2 XSDs into WSDL whereas starting from line 5, I define the same set of elements as in the XSDs. Well, this will receive an error complaining duplicate class while generating the JAVA artifact from XSD as shown below:
parsing WSDL...


[ERROR] A class/interface with the same name "org.huahsin.ws.HelloWorldResponse" is already in use. Use a class customization to resolve this conflict.
  line 23 of file:/home/kokhoe/workspace/wsAsync/resources/HelloWorld.wsdl

[ERROR] (Relevant to above error) another "HelloWorldResponse" is generated from here.
  line 8 of file:/home/kokhoe/workspace/wsAsync/resources/HelloWorldRes.xsd

[ERROR] Two declarations cause a collision in the ObjectFactory class.
  line 8 of file:/home/kokhoe/workspace/wsAsync/resources/HelloWorldRes.xsd

[ERROR] (Related to above error) This is the other declaration.   
  line 23 of file:/home/kokhoe/workspace/wsAsync/resources/HelloWorld.wsdl 
Thus experience from here was never be so greedy, choose either site when the element should define.

Thursday, September 24, 2015

Initialization list doesn't work for virtual constructor?

A virtual base class is always initialized before other derive class. This is a known behavior. I'm aware of it. But what's surprising me is that when I have an intermediate class pass parameter to the virtual base class constructor in their member initialization list, these initialization list will be ignored. The following piece could prove this statement.
class Parent {
public:
 Parent() : param(0) {
  cout << "Parent constructor" << endl;
 }

 Parent(int param) : param(param){
  cout << "Parent constructor(param)" << endl;
 }

 int getParam() { return param; }

private:
 int param;
};

class Base : virtual public Parent {
public:
 Base() : Parent(5373) {
  cout << "Base constructor" << endl;
 }
};

class Xtends : public Base {
public:
 Xtends() {
  cout << "Xtends constructor" << endl;
 }
};
When I execute the following piece, the param value would be 0:
   Xtends x;
   cout << "param: " << x.getParam() << endl;
Notice the Base class is an intermediate class. When I pass in the value of 5373 into Parent( int ) constructor, it simply ignores it. Next the Base class is no longer an intermediate class. Now when I execute the following code, the value of 5373 would be seen:
   Base b;
   cout << "param: " << b.getParam() << endl;

Tuesday, September 22, 2015

Insufficient memory to create a queue

I'm a poor kid. I can't afford to buy extra memory for my queue. Too bad. And too sad.

After the root access issue has been resolved in WebSphere MQ Explorer, I am able to make a queue, but there is a prompt showing the following details to me:
****************************************
* Command: /opt/mqm/bin/crtmqm  Q1
****************************************
WebSphere MQ queue manager created.
Directory '/var/mqm/qmgrs/Q1' created.
The queue manager is associated with installation 'Installation1'.
AMQ6024: Insufficient resources are available to complete a system request.
exitvalue = 36 
I wasn't sure whether this is a general greeting or welcome message after a queue has been created? But I have verified the queue was there in the path /var/mqm/qmgr. To further verify this message isn't friendly to me, I issue another command sudo strmqm Q1, I got the same result:
$ sudo strmqm Q1
The system resource RLIMIT_NOFILE is set at an unusually low level for WebSphere MQ.
WebSphere MQ queue manager 'Q1' starting.
The queue manager is associated with installation 'Installation1'.
AMQ6024: Insufficient resources are available to complete a system request.
Clearly, this isn't a good thing. According to experts advice, there should be an error log locate at the path: /var/mqm/errors/. When I open the file located in that path, I see something like below:
+-----------------------------------------------------------------------------+
|                                                                             |
| WebSphere MQ First Failure Symptom Report                                   |
| =========================================                                   |
...
...
...
| Comment1          :- Failed to get memory segment: shmget(0x00000000,       |
|   73834496) [rc=-1 errno=22] Invalid argument                               |
| Comment2          :- Invalid argument                                       |
| Comment3          :- Configure kernel (for example, shmmax) to allow a      |
|   shared memory segment of at least 73834496 bytes                          |
|                                                                             |
+-----------------------------------------------------------------------------+
This reminds me there are additional settings for WebSphere MQ on Linux systems needs to be configured. According to the guide, there is minimum configuration are required for WebSphere MQ:
    kernel.shmmni = 4096
    kernel.shmall = 2097152
    kernel.shmmax = 268435456
    kernel.sem = 500 256000 250 1024
    fs.file-max = 524288
    kernel.pid-max = 120000
    kernel.threads-max = 48000
Among the settings, only shmmax and sem are not up to par. Below is what I have at current system:
$ cat /proc/sys/kernel/shmmax
33554432
$ cat /proc/sys/kernel/sem
250 32000 32 128
The following steps are what I did to fix this issue:
  1. Open the file /etc/sysctl.conf.
  2. Append the require configuration for shmmax and sem to the end of the file.
  3. Reload the configuration with the command sysctl -p.

Wednesday, September 2, 2015

Where is MQ_INSTALLATION_PATH?

Sometimes I do wonder where will be the installation path is? There is a shortcut for this, issue a command dspmqver, it shows me the detail information about WebSphere MQ. From there I can see InstPath showing where this tool is installed:
Name:        WebSphere MQ
Version:     8.0.0.2
Level:       p800-002-150303.DE
BuildType:   IKAP - (Production)
Platform:    WebSphere MQ for Linux (x86-64 platform)
Mode:        64-bit
O/S:         Linux 3.13.0-62-generic
InstName:    Installation1
InstDesc:    
Primary:     No
InstPath:    /opt/mqm
DataPath:    /var/mqm
MaxCmdLevel: 801
LicenseType: Developer
Or maybe I have overlooked, the documentation did mention where does the MQ_INSTALLATION_PATH is. Below is the text extract from the guide:
The location where WebSphere MQ is installed is known as the MQ_INSTALLATION_PATH. The default location for the WebSphere MQ product code is shown in the following table:

Platform Installation Location
Linux, HP-UX, and Solaris /opt/mqm
AIX® /usr/mqm
Windows 32-bit C:\Program Files\IBM\WebSphere MQ
Windows 64-bit C:\Program Files (x86)\IBM\WebSphere MQ 

On UNIX and Linux systems, working data is stored in /var/mqm, but you cannot change this location.

Tuesday, September 1, 2015

Tracing Apache HTTP server installation path with RPM

Things get complicated when everything was messed up in AIX. How could I know which Apache HTTP server version I have installed on my UNIX box? Initially I though it is as simple as typing this command, httpd -v, unfortunately the system returns me ksh: httpd: not found. Wonder why the system can’t allocate httpd command? Then I try the command such as locate httpd and whereis httpd to find out where the hell this package is being installed? But both gave me negative response.

I’ll not going to defeat so easily, I still have one last hope to trace back where httpd is installed. Since the httpd was installed through RPM, I think rpm should be able to trace back the installation path. To verify my assumption is correct, I would use rpm -qa to ensure httpd is installed through rpm. Next is to use rpm -ql httpd | grep httpd to list the entire installation path that contains httpd in it. Then I’ll know where exactly the httpd was installed.

Have fun with AIX.