9/5/08


ORACLE tips

FONT -- Lucida Console !!!
chcp 1251

RUSSIAN_CIS.CL8MSWIN1251
chcp 1251

для клиента виндовс NLS_LANG=AMERICAN_AMERICA.CL8MSWIN1251
для клиента линукс NLS_LANG=AMERICAN_AMERICA.CL8KOI8R

sqlplus sys/querty@xe AS SYSDBA

SELECT table_name FROM user_tables;

select to_char(to_date('19-SEP-2008','dd-mon-yyyy'),'day') from dual;
select user from dual;
select sysdate from dual;
select current_user from dual;

set ARRAYSIZE 1000;
set LINESIZE 1000;
set PAGESIZE 1000;


select level from dual connect by level < 10;
select level a from dual connect by 1 = 1;


ALTER SYSTEM SET TIMED_STATISTICS = TRUE;
ALTER SESSION SET SQL_TRACE = TRUE;

-- Created d:\oracle\product\10.2.0\admin\xe\udump\xe_ora_4916.trc

select test_connect_by.parent from persons inner join test_connect_by on persons.id = test_connect_by.child group by test_connect_by.parent;

select spid, osuser, s.program from v$process p, v$session s where p.addr=s.paddr order by 2;
alter system kill session(sid, serial#);

show parameters processes
show parameters sessions

alter system set sessions=250 scope=spfile;
alter system set processes=200 scope=spfile;

select count(*) from v$session
select count(*) from v$process

quit;

orakill xe 4072

8/22/08


Eclipse Plugins

Jigloo SWT/Swing GUI Builder
Java Persistence API (JPA) Tools
JadClipse
http://update.eclemma.org

7/21/08


Java and XML: XML binding

JAXB

XMLBeans

JiBX

7/15/08


Apache AXIS

Simple invoke standard Version web service via URLConnection:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

public class Main {

public static void main(String[] args) throws Exception {

HttpURLConnection httpurlconnection = null;
String HostUrl = "localhost";
String SoapActionUrl = "http://localhost:8080/axis/services/Version";

URL url = new URL(SoapActionUrl);
URLConnection urlconnection = url.openConnection();
httpurlconnection = (HttpURLConnection) urlconnection;

StringBuffer stringbuffer = new StringBuffer();

stringbuffer.append("<SOAP-ENV:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
stringbuffer.append("<SOAP-ENV:Body>");
stringbuffer.append("<getVersion>");
stringbuffer.append("</getVersion></SOAP-ENV:Body></SOAP-ENV:Envelope>");

byte abyte0[] = stringbuffer.toString().getBytes();
httpurlconnection.addRequestProperty("Host", HostUrl);
httpurlconnection.addRequestProperty("Content-Length", String.valueOf(abyte0.length));
httpurlconnection.addRequestProperty("Content-Type", "text/xml; charset=UTF-8");
httpurlconnection.addRequestProperty("SOAPAction", SoapActionUrl);
httpurlconnection.setInstanceFollowRedirects(true);

httpurlconnection.setRequestMethod("POST");
httpurlconnection.setDoOutput(true);
httpurlconnection.setDoInput(true);

OutputStream outputstream = httpurlconnection.getOutputStream();
outputstream.write(abyte0);
outputstream.close();

System.out.println(httpurlconnection.getResponseMessage());

InputStreamReader inputstreamreader = new InputStreamReader(httpurlconnection.getInputStream());
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
StringBuffer stringbuffer1 = new StringBuffer();
String s3;
while ((s3 = bufferedreader.readLine()) != null) {
stringbuffer1.append(s3);
System.out.println(s3);
}
bufferedreader.close();
httpurlconnection = null;
}
}

Result:

OK
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getVersionResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><getVersionReturn xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)</getVersionReturn></getVersionResponse></soapenv:Body></soapenv:Envelope>

Request

POST /axis/services/Version HTTP/1.1
Host: localhost
Content-Length: 253
Content-Type: text/xml; charset=UTF-8
SOAPAction: http://localhost:8080/axis/services/Version
User-Agent: Java/1.4.2
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><getVersion></getVersion></SOAP-ENV:Body></SOAP-ENV:Envelope>

Response

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Tue, 15 Jul 2008 11:41:14 GMT

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getVersionResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><getVersionReturn xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)</getVersionReturn></getVersionResponse></soapenv:Body></soapenv:Envelope>


Using AXIS classes:

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;

public class Main {
public static void main(String[] args) throws Exception {
String endpoint = "http://localhost:8080/axis/services/Version";
Call call = (Call) new Service().createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new QName("", "getVersion"));
String ret = (String) call.invoke(new Object[] { });
System.out.println(ret);
}
}

Result:

Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)

Request:

POST /axis/services/Version HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: localhost:8080
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 340

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getVersion soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></soapenv:Body></soapenv:Envelope>

Response:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Date: Tue, 15 Jul 2008 10:35:47 GMT
Connection: close

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getVersionResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><getVersionReturn xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)</getVersionReturn></getVersionResponse></soapenv:Body></soapenv:Envelope>

Java and XML: miscellaneous notes

- Java 1.4 includes the Crimson parser, though the Axis team prefer Xerces.
- If you are installing Tomcat, get the latest 4.1.x version, and the full distribution, not the LE version for Java 1.4, as that omits the Xerces XML parser.
- SOAP messages are XML messages. Messages consist of one or more SOAP elements inside an envelope, Headers and the SOAP Body. SOAP has two syntaxes for describing the data in these elements, which is a clear descendant of the XML RPC system, and XML Schema, which is the newer system.
- Axis implements the JAX-RPC API, one of the standard ways to program Java services.
- To add an XML parser, acquire the JAXP 1.1 XML compliant parser of your choice. We recommend Xerces jars from the xml-xerces distribution, though others mostly work.
- Axis is compiled in the JAR file axis.jar; it implements the JAX-RPC API declared in the JAR files jaxrpc.jar and saaj.jar.
- The examples in this guide use Xerces. This guide adds xml-apis.jar and xercesImpl.jar to the AXISCLASSPATH so that Axis can find the parser. (from Installing and deploying web applications using xml-axis).
- Axis stands for, it's Apache EXtensible Interaction System.
- JaxMe - an implementation of JAXB, the specification for Java/XML binding.
A SOAP message is an ordinary XML document containing the following elements:
* A required Envelope element that identifies the XML document as a SOAP message
* An optional Header element that contains header information
* A required Body element that contains call and response information
* An optional Fault element that provides information about errors that occurred while processing the message
-Axis is one of the best Java-based Web services engines. It's better architected and much faster than its Apache SOAP predecessor.
-XML infoset is an abstract model of all the information in an XML document or document fragment.
- Dynamic invocation interface (DII)

-Communication Patterns
With Web Services, you can essentially distinguish three different ways of communication:

* Remote procedure call: Client sends a SOAP request to the service provider and then waits for a SOAP response (synchronous communication).
* Messaging: Client sends a SOAP request and expects no SOAP response back (one-way communication)
* Asynchronous callback: A client calls the service with one of the above methods. Later, the two parties switch roles for a callback call. This pattern can be built from either of the first two.

- WSDL 1.1 distinguishes two different binding styles (referred to as soap:binding styles): RPC and Document.

7/9/08


Java and XML: validation XML

JAXP 1.3

String schemaLang = "http://www.w3.org/2001/XMLSchema";
SchemaFactory factory = SchemaFactory.newInstance(schemaLang);
Schema schema = factory.newSchema(new StreamSource("sample.xsd"));
Validator validator = schema.newValidator();
validator.validate(new StreamSource("sample.xml"));

Java and XML: generating XML


DOM API:

import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;

public class Main {

 public static void main(String[] args) throws Exception {

  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  Document xmldoc = factory.newDocumentBuilder().getDOMImplementation().createDocument(null, "PhoneBook", null);

  Element root = xmldoc.getDocumentElement();
  Element e = xmldoc.createElementNS(null, "BookRecord");
  Node n = xmldoc.createTextNode("Value");
  e.appendChild(n);
  root.appendChild(e);

  Transformer serializer = TransformerFactory.newInstance().newTransformer();
  serializer.setOutputProperty(OutputKeys.INDENT,"yes");
  serializer.transform(new DOMSource(xmldoc), new StreamResult(new PrintWriter(System.out)));
 }
}


SAX API:

import java.io.PrintWriter;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.helpers.*;

public class Main {

 public static void main(String argv[]) throws Exception {

  SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
  TransformerHandler hd = tf.newTransformerHandler();
  hd.getTransformer().setOutputProperty(OutputKeys.INDENT,"yes");
  hd.setResult(new StreamResult(new PrintWriter( System.out)));

  hd.startDocument();
  hd.startElement("", "", "PhoneBook",new AttributesImpl());
  hd.startElement("", "","BookRecord", new AttributesImpl());
  hd.characters("Value".toCharArray(), 0, 5);
  hd.endElement("", "", "BookRecord");
  hd.endElement("", "", "PhoneBook");
  hd.endDocument();
 }
}


JDOM API:

package com;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class Main {

 public static void main(String argv[]) throws Exception {

  Document doc = new Document();
  Element e = new Element("PhoneBook");
  e.addContent(new Element("BookRecord").setText("Value"));
  doc.addContent(e);

  XMLOutputter outp = new XMLOutputter();
  Format f = Format.getPrettyFormat();
  //f.setIndent(" ");
  outp.setFormat(f);
  outp.output(doc, System.out);
 }
}


As result in all cases:

<?xml version="1.0" encoding="UTF-8"?>
<PhoneBook>
<BookRecord>Value</BookRecord>
</PhoneBook>



XML Serialization with java.beans.XMLEncoder class

import java.beans.XMLEncoder;

public class Main {

 public static void main(String[] args) throws Exception {
  XMLEncoder xenc = new XMLEncoder(System.out);
  xenc.writeObject("Some String");
  xenc.flush();
  xenc.close();
 }
}

Output:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_06" class="java.beans.XMLDecoder">
 <string>Some String</string>
</java>

Or more interesting:

import java.beans.XMLEncoder;

public class Main {

 public static void main(String[] args) throws Exception {

  Foo[] arr = {new Foo(), new Foo()};
  XMLEncoder encoder = new XMLEncoder(System.out);
  encoder.writeObject(arr);
  encoder.close();
  }

  public static class Foo {

  private int foo = 10 ;
  public int getFoo() {
   return foo;
  }

  public void setFoo(int foo) {
   this.foo = foo;
  }
 }
}


<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_06" class="java.beans.XMLDecoder">
 <array class="com.Main$Foo" length="2">
  <void index="0">
   <object class="com.Main$Foo"/>
  </void>
  <void index="1">
   <object class="com.Main$Foo"/>
  </void>
 </array>
</java>

As you can see - not so optimistic. For the things to be serialized propery, you need bean pattern getter methods, and sometimes even setters: so for simple java bean serialization will work fine.


XStream - a lightweight open source Java library for serializing Java objects to XML and back again.


import com.thoughtworks.xstream.XStream;

public class Main {

 public static void main(String[] args) throws Exception {

  XStream xstream = new XStream();
  xstream.alias("Foo", Foo.class);
  String xml = xstream.toXML(new Foo());
  System.out.println(xml);
 }

 public static class Foo {

  public int fooInt = 10 ;
  public String fooStr = "20";
  }
}


<Foo>
 <fooInt>10</fooInt>
 <fooStr>20</fooStr>
</Foo>

In case of List it behave too pretty good:

 List<Foo> list = new LinkedList<Foo>();
 list.add(new Foo());
 list.add(new Foo());
 String xml = xstream.toXML(list);

Result:

<linked-list>
 <Foo>
  <fooInt>10</fooInt>
  <fooStr>20</fooStr>
 </Foo>
 <Foo>
  <fooInt>10</fooInt>
  <fooStr>20</fooStr>
 </Foo>
</linked-list>

Java and XML: query over XML

There is not included API for XQuery in Java 5 or 6. There is not included XPath API in Java till 5. But in java 5 and higher there is facilities for addressing element or group of elements via XPath. Probably in Java 7 it will be realized (XQJ or JSR 225 - like JDBC). Any case SUN is not only vendor of such kind of API.

XPath with Saxon
SAXON is the XSLT and XQuery Processor. Most XSLT and XQuery functionality in Saxon will work without installing JAXP 1.3.

import net.sf.saxon.dom.DOMNodeList;
import net.sf.saxon.om.NamespaceConstant;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.xpath.XPathEvaluator;
import org.xml.sax.InputSource;
import javax.xml.namespace.NamespaceContext;
import javax.xml.transform.sax.SAXSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.FileInputStream;
import java.util.Iterator;
import net.sf.saxon.dom.ElementOverNodeInfo;

public class XPathExample implements NamespaceContext {

 public static void main (String args[]) throws Exception {
  System.setProperty("javax.xml.xpath.XPathFactory:"+NamespaceConstant.OBJECT_MODEL_SAXON, "net.sf.saxon.xpath.XPathFactoryImpl");
  XPathFactory xpf = XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON);
  XPath xpe = xpf.newXPath();
  InputSource is = new InputSource(new FileInputStream("D:/dev/Temp_java/src/com/PhoneBook.xml"));
  SAXSource ss = new SAXSource(is);
  NodeInfo doc = ((XPathEvaluator)xpe).setSource(ss);
  XPathExpression findLine = xpe.compile("/*[1]/*[1]");
  DOMNodeList matchedLines = (DOMNodeList)findLine.evaluate(doc, XPathConstants.NODESET) ;
  if (matchedLines != null) {
   for (int i = 0; i < matchedLines.getLength(); i++) {
    ElementOverNodeInfo info =((ElementOverNodeInfo)matchedLines.item(i));
    System.out.println(info.getTextContent());
   }
  }
 }

 public String getNamespaceURI(String prefix) {
  return null;
 }
 public String getPrefix(String namespaceURI) {
  return null;
 }
 public Iterator getPrefixes(String namespaceURI) {
  return null;
 }
}

Result:

0
Alex
Kuiv, Kominterna 28
aillusions@gmail.com
+380664392825


XPath with JAXP 1.3
JAXP is the Java API for XML Processing. In version SE 1.5 it included by default but there is version JAXP 1.3 for JDK 1.4 (by default has JAXP 1.1). To use this API in 1.4 property -Djava.endorsed.dirs=DIR_WITH_JAXP1.3_JARS should be set, or copy all of the jar files except jaxp-api.jar into /jre/lib/endorsed.

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Iterator;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class XPathDemo {

 public static void main(String[] args) throws Exception {

  String xmlFile = "D:/dev/Temp_java/src/com/PhoneBook.xml";
  String xpathExpression = "/*/pb:BookRecord/pb:id";

  XPathFactory xpf = XPathFactory.newInstance();
  XPath xpath = xpf.newXPath();

  NamespaceContextImpl namespaceContextImpl = new NamespaceContextImpl();
  namespaceContextImpl.bindPrefixToNamespaceURI("pb","http://www.epam.com/com/PhoneBook");

  xpath.setNamespaceContext(namespaceContextImpl);
  FileInputStream saxStream = new FileInputStream(xmlFile);
  NodeList saxNodeList = null;
  saxNodeList = (NodeList)xpath.evaluate(xpathExpression, new InputSource(saxStream), XPathConstants.NODESET);

  for (int i = 0; i < saxNodeList.getLength(); i++) {
   System.out.println(" name: " + saxNodeList.item(i).getNodeName()+", value: " + saxNodeList.item(i).getNodeValue());
  }
 }
}

class NamespaceContextImpl implements NamespaceContext {

 private HashMap prefixToNamespaceURI = new HashMap();
 private HashMap namespaceURIToPrefix = new HashMap();

 public void bindPrefixToNamespaceURI(String prefix, String namespaceURI) {
  prefixToNamespaceURI.put(prefix, namespaceURI);
  namespaceURIToPrefix.put(namespaceURI, prefix);
 }

 public String getNamespaceURI(String prefix) {
  if (prefixToNamespaceURI.containsKey(prefix))
   return (String)prefixToNamespaceURI.get(prefix);
  return XMLConstants.NULL_NS_URI;
 }

 public String getPrefix(String namespaceURI) {
  if (namespaceURIToPrefix.containsKey(namespaceURI))
   return (String)namespaceURIToPrefix.get(namespaceURI);
  return null;
 }

 public Iterator getPrefixes(String namespaceURI) {
  throw new UnsupportedOperationException("NamespaceContextImpl#getPrefixes(String namespaceURI) not implemented");
 }
}

And result:

name: pb:id, value: null
name: pb:id, value: null
name: pb:id, value: null


XPath with Jaxen
Jaxen is able to interact with DOM, Dom4j and JDOM.

import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.jaxen.dom.DOMXPath;
import org.jaxen.XPath;
import java.util.List;
import java.util.Iterator;

public class Main {

 public static void main(String argv[]) throws Exception {
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  factory.setNamespaceAware(true);

  Document doc = factory.newDocumentBuilder().parse("D:/dev/Temp_java/src/com/PhoneBook.xml");
  XPath xpath = new DOMXPath("//pb:id");
  xpath.addNamespace("pb", "http://www.epam.com/com/PhoneBook");
  xpath.addNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

  List results = xpath.selectNodes(doc);
  Iterator resultIter = results.iterator();

  while(resultIter.hasNext()){
   System.out.println( resultIter.next());
  }
 }
}

As result:

<pb:id>0</pb:id>
<pb:id>1</pb:id>
<pb:id>2</pb:id>


XPath with SAXPath
SAXPath has been merged into the Jaxen codebase and is no longer being maintained separately.

XPath with Xalan
Xalan-Java is an XSLT processor for transforming XML documents: http://xml.apache.org/xalan-j. Xalan includes the JAXP packages, implements the TrAX portion of that API (javax.xml.transform....), implements the XPath API of JAXP (javax.xml.xpath....), and includes xercesImpl.jar from Xerces-Java 2.9.0, which implements the parser portion of the API (javax.xml.parser....).

import java.io.FileInputStream;
import java.io.OutputStreamWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.InputSource;

public class ApplyXPath {

 public static void main(String[] args) throws Exception {

  String filename = "D:/dev/Temp_java/src/com/PhoneBook.xml";
  String xpath = "/*[1]/*[1]";

  InputSource in = new InputSource(new FileInputStream(filename));
  DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
  dfactory.setNamespaceAware(true);
  Document doc = dfactory.newDocumentBuilder().parse(in);
  Transformer serializer = TransformerFactory.newInstance().newTransformer();
  serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

  NodeIterator nl = XPathAPI.selectNodeIterator(doc, xpath);

  Node n;
  while ((n = nl.nextNode()) != null) {
   serializer.transform(new DOMSource(n), new StreamResult(new OutputStreamWriter(System.out)));
  }
 }
}

Result:

<pb:BookRecord xmlns:pb="http://www.epam.com/com/PhoneBook" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <pb:id>0</pb:id>
  <pb:name>Alex</pb:name>
  <pb:address>Kuiv, Kominterna 28</pb:address>
  <pb:email>aillusions@gmail.com</pb:email>
  <pb:phone>+380664392825</pb:phone>
 </pb:BookRecord>

Java and XML: transformation XML

We can process our xml with code:

import java.io.File;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class Main {

 public static void main(String argv[]) throws Exception {
  File xmlFile = new File("src/com/PhoneBook.xml");
  File xsltFile = new File("src/com/PhoneBook.xsl");
  TransformerFactory transFact = TransformerFactory.newInstance();
  Transformer trans = transFact.newTransformer(new StreamSource(xsltFile));
  trans.transform(new StreamSource(xmlFile), new StreamResult(System.out));
 }
}

And result:

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

Java and XML: parsing XML

SAX - simple API for XML processing:

SAXParser saxParser = SAXParserFactory.newInstance().newSAXPar\ser();
saxParser.parse(new ByteArrayInputStream("<aaa>bbb</aaa>".getBytes()), new DefaultHandler());

Above is simplest sample. Now I am going to show parsing with validation by SAX.
Let's create simple SAX parser handler:

class PhoneBookHandler extends DefaultHandler{
 public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
  System.out.println(localName);
  super.startElement(uri, localName, name, attributes);
 }
 public void error(SAXParseException e) throws SAXException {
  e.printStackTrace();
  super.error(e);
 }

And main code:

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.helpers.DefaultHandler;

public class Main {
 public static void main(String argv[]) throws Exception {
  SAXParserFactory pf = SAXParserFactory.newInstance();
  pf.setNamespaceAware(true);
  pf.setValidating(true);
  SAXParser p = pf.newSAXParser();
  p.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
  p.parse("D:/dev/Temp_java/src/com/PhoneBook.xml", new PhoneBookHandler());
 }
}

If you do not have schemaLocation in your xml file, you can define schema location in parser property:

p.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", new File("%PATH_TO_YOUR_XSD%/PhoneBook.xsd"));

schemaSource property in parser is more important than schemaLocation in xml instance.

DOM - document object model

import javax.xml.parsers.*;
...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse("D:/dev/Temp_java/src/com/xml.xml"); System.out.println(doc.getElementsByTagName("Record").item(0).getFirstChild().getNextSibling());

JDOM - java-oriented (not XML) representation of an XML document
JDOM is the Java-based solution for accessing, manipulating, and outputting XML data from Java code. It corresponds JSR-102 - API for easy and efficient reading, manipulation, and writing of XML documents and XML data.

SAXBuilder builder = new SAXBuilder();
Document doc = builder.build("D:/dev/Temp_java/src/com/PhoneBook.xml");
System.out.println(doc.getRootElement().getChildren().get(0).toString());

StAX - Streaming API for XML
JSR 173 defines a pull streaming model, StAX (short for "Streaming API for XML"), for processing XML documents. In this model, unlike in SAX, the client can start, proceed, pause, and resume the parsing process. The client has complete control.
A StAX Implementation:
- Sun's Implementation - SJSXP
- BEA Reference Implementation
- WoodSToX XML Processor
- Oracle StAX Pull Parser Preview
- Codehaus StAX
Sun Java Streaming XML Parser - SJSXP - is an implementation of the StAX API. We need sjsxp.jar and jsr173_1.0_api.jar in class path

import java.io.FileInputStream;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;

public class Main {

 public static void main(String argv[]) throws Exception {
  FileInputStream fileInputStream = new FileInputStream("D:/dev/Temp_java/src/com/PhoneBook.xml");
  XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream);

  while (true) {
   int event = xmlStreamReader.next();
   if (event == XMLStreamConstants.END_DOCUMENT) {
    xmlStreamReader.close();
    break;
   }
   if (event == XMLStreamConstants.START_ELEMENT) {
    System.out.println(xmlStreamReader.getLocalName());
   }
  }
 }
}

Result:

PhoneBook
BookRecord
id
name
address
email
phone
BookRecord
id
name
address
email
phone
BookRecord
id
name
address
email
phone

Apache Axiom - AXis Object Model - the XML object model that uses StAX as its underlying XML parsing methodology.
XML infoset refers to the information included inside the XML, and for programmatic manipulation it is convenient to have a representation of this XML infoset in a language specific manner. For an object oriented language the obvious choice is a model made up of objects. DOM and JDOM are two such XML models. Axiom is too, but it uses "pull parsing" - a recent trend in XML processing. Axiom is based on StAX (JSR 173 ), which is the standard streaming pull parser API. Axiom needs JAXP 1.3 so java 5 should be used, or -Djava.endorsed.dirs=D:/env/xml/jaxp-1_3 should be set.

import java.io.FileInputStream;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;

public class Main {

 public static void main(String argv[]) throws Exception {
  String xmlFName = "D:/dev/Temp_java/src/com/PhoneBook.xml";

  XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader(new FileInputStream(xmlFName));
  StAXOMBuilder builder = new StAXOMBuilder(parser);
  OMElement documentElement = builder.getDocumentElement();
  System.out.println(documentElement.getChildElements().next());
 }
}

Xerces - Apache parsers that supports standard APIs - most popular SAX and DOM parser.
Xerces is a family of software packages for parsing and manipulating XML, it provides both XML parsing and generation.
Creating a DOM Parser:

import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;

public class Main {

 public static void main(String argv[]) throws Exception {
  String xmlFile = "D:/dev/Temp_java/src/com/PhoneBook.xml";
  DOMParser parser = new DOMParser();
  parser.parse(xmlFile);
  Document document = parser.getDocument();
  System.out.println(document.getChildNodes().item(0).getNodeName());
 }
}

Result:

pb:PhoneBook

Creating a SAX Parser:

import org.xml.sax.AttributeList;
import org.xml.sax.DocumentHandler;
import org.xml.sax.Locator;
import org.xml.sax.Parser;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.ParserFactory;

public class Main implements DocumentHandler {

 public static void main(String argv[]) throws Exception {
  String xmlFile = "D:/dev/Temp_java/src/com/PhoneBook.xml";
  String parserClass = "org.apache.xerces.parsers.SAXParser";
  Parser parser = ParserFactory.makeParser(parserClass);
  parser.setDocumentHandler(new Main());
  parser.parse(xmlFile);
 }

 public void characters(char[] ch, int start, int length) throws SAXException {}
 public void endDocument() throws SAXException {}
 public void endElement(String name) throws SAXException {}
 public void ignorableWhitespace(char[] ch, int start, int length){}
 public void processingInstruction(String target, String data)throws SAXException {}
 public void setDocumentLocator(Locator locator) {}
 public void startDocument() throws SAXException {}
 public void startElement(String name, AttributeList atts) throws SAXException {
  System.out.println(name);
 }
}

Result:

pb:PhoneBook
pb:BookRecord
pb:id
pb:name
pb:address
pb:email
pb:phone
pb:BookRecord
pb:id
pb:name
pb:address
pb:email
pb:phone
pb:BookRecord
pb:id
pb:name
pb:address
pb:email
pb:phone

Crimson XML – A faster SAX and DOM parser
...
Sparta XML – A fast and small SAX and DOM parser also includes an XPath subset
...
StelsXML is a JDBC type 4 driver that allows to perform SQL queries and other JDBC operations on XML files
...

7/2/08


Java and XML: intro

Let's consider PhoneBook.xml:

<?xml version="1.0"?>
<pb:PhoneBook xmlns:pb="http://www.epam.com/com/PhoneBook" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.epam.com/com/PhoneBook PhoneBook.xsd">
 <pb:BookRecord>
  <pb:id>0</pb:id>
  <pb:name>Alex</pb:name>
  <pb:address>Kuiv, Kominterna 28</pb:address>
  <pb:email>aillusions@gmail.com</pb:email>
  <pb:phone>+380664392111</pb:phone>
 </pb:BookRecord>
 <pb:BookRecord>
  <pb:id>1</pb:id>
  <pb:name>Zhanna</pb:name>
  <pb:address>Kuiv, Showkunenko 3</pb:address>
  <pb:email>estetka@mail.ru</pb:email>
  <pb:phone>+380666464111</pb:phone>
 </pb:BookRecord>
</pb:PhoneBook>

xsd file PhoneBook.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.epam.com/com/PhoneBook" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <xsd:element name="PhoneBook">
  <xsd:complexType>
   <xsd:sequence minOccurs="0" maxOccurs="unbounded">
    <xsd:element name="BookRecord">
     <xsd:complexType>
      <xsd:sequence minOccurs="0">
       <xsd:element type="xsd:int" name="id" />
       <xsd:element type="xsd:string" name="name" />
       <xsd:element type="xsd:string" name="address" />
       <xsd:element type="xsd:string" name="email" />
       <xsd:element type="xsd:string" name="phone" />
      </xsd:sequence>
     </xsd:complexType>
    </xsd:element>
   </xsd:sequence>
  </xsd:complexType>
 </xsd:element>
</xsd:schema>

xsl file PhoneBook.xsl:

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
  <strong>
   <xsl:text>Value</xsl:text>
  </strong>
 </xsl:template>
</xsl:stylesheet>

6/27/08


What new in j2se 1.5.0

- added in java.util.Arrays static toString() method
- added generics
- hot swap realised
- added StringBuilder. It is identical to StringBuffer except that it is not synchronized. In single-threaded programs StringBuilder is slightly faster.
- added XML validation package at javax.xml.validation and the XPath libraries at javax.xml.xpath
- added annotation

6/18/08


Programming Ideas

There are a lot of obstruction on the way of new programmer. If he or she is newbie and does not have access to real development process it means he or she does not have access to best practice and up-to-date knowledges about technologies, tools, approaches etc. But most substantial issue is lack interesting and useful task for practice and develop skills. So I have one proposal as choice to resolve that problem: be imitator.
Yeah. Just try to copy existing well knowing functionality or application. It is not new idea, I know, but it is not so obvious to use this method in every day. I have seen movie about some painter who trained to draw by copy another's picture. Let's contrive some examples:
- Calc
- Excel
- Lingvo
- TotalCommander
- Bizarre
- BlogSpot
- Eclipse
- gmail
- forum
- CMS
- game ..
Or only functionality:
- Java collection implementation
- Java ORM implementation
- java.lang.String implementation

And also some notes:

//---------------
System.out.println( new SimpleDateFormat("yyyy-MMM-dd hh:mm:ss").format(new Date()));
System.out.println( new SimpleDateFormat("yyyy-MMM-dd (E) hh:mm:ss [z]", Locale.ENGLISH).parse("2008-Jun-27 (Fri) 01:18:46 [EEST]"));
//---------------
new StringBuilder("qwerty").reverse().toString();
//---------------
public enum Status {
Open("O"), Closed("C"), Reopened("R");
final String code;
Status(String code) {
this.code = code;
}
}
//---------------

6/3/08


Web Service Development

JAX-RPC is a Java community effort to eliminate problems with Web service implementations and provide a well-known application programming interface (API) on both the client and the server side. JAX-RPC provides an easy to develop programming model for development of SOAP based Web services.

So in details: JAX-RPC (java API for XML based RPC) is the API specification for J2EE 1.4 and presented as RFC 101. SUN (in WSDP) and Apache (in AXIS) have its own implementation that API. JAX-RPC defines API for creating SEI (service end point) and client endpoint. JAX-RPC enables a Web service endpoint to be developed using either a Java Servlet or Enterprise JavaBeans (EJB) component model (JSR 109). A Web service endpoint is deployed on either the Web container or EJB container based on the corresponding component model.
(I mean JAX-RPC 1.1.)
The latest version of JAX-RPC is 2.0. But it has new name: JAX-WS 2.0 - JSR-224. JAX-WS programming model is JavaEE5 compliant.
EJB3 stateless session bean - JAX-WS.
EJB-2.1 stateless session bean - JAX-RPC.

A JAX-RPC client can use stubs-based, dynamic proxy or dynamic invocation interface (DII) programming models to invoke a heterogeneous Web service endpoint. JAX-RPC uses SAAJ API for SOAP message handlers.

Using wscompile from WSDP toolkit made by SUN:

wscompile.bat -classpath build/classes -gen:server -f:rpcliteral config.xml -d build/classes -nd WebContent/WEB-INF/wsdl -mapping WebContent/WEB-INF/mapping.xml

-d directory to put generated and compiled classes
-nd directory to put "non classes" generated stuff (wsdl etc.)

5/28/08


Remote debugging

JBoss:

set JAVA_OP TS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 %JAVA_OPTS%

WebLogic:

@REM insert this line
set debugFlag=true
@REM before:
if "%debugFlag%"=="true" (
set JAVA_DEBUG=-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=%DEBUG_PORT%,server=y,suspend=n -Djava.compiler=NONE
set JAVA_OPTIONS=%JAVA_OPTIONS% %enableHotswapFlag% -ea -da:com.bea... -da:javelin... -da:weblogic... -ea:com.bea.wli... -ea:com.bea.broker... -ea:com.bea.sbconsole...
) else (
set JAVA_OPTIONS=%JAVA_OPTIONS% %enableHotswapFlag% -da
)

Dynamo 6.3:

startDynamo.bat drp1 -m sfx -debug -debugPort 8787

Tomcat:

Set environment variables JPDA_ADDRESS=8000 and JPDA_TRANSPORT=dt_socket and then start tomcat using catalina jpda start

5/26/08


Java Binary / XML Serialization

XMLEncoder under Java 5 did not cope with serialization task:

import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import com.thoughtworks.xstream.XStream;

public class Main {

public static void main(String[] args) throws FileNotFoundException {
HashMap hm = new HashMap();
hm.put("string1", new ForSer("string1", 10));
hm.put("string2", new ForSer("string2", 101));
hm.put("string3", new ForSer("string3", 1011));
hm.put("string4", new ForSer("string4", 10111));
// FileOutputStream fos = new FileOutputStream("d:/foo.xml");
// XMLEncoder xenc = new XMLEncoder(fos);
// xenc.writeObject(hm);
// xenc.flush();
// xenc.close();
XStream xstream = new XStream();
System.out.println(xstream.toXML(hm));

//Binary:
ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos) ;
oos.writeObject(new ForSer("string", 111));
byte[] bar = baos.toByteArray();
System.out.println(new String(bar));
}
static class ForSer implements Serializable {
private static final long serialVersionUID = 1L;
private String str;
private int count;

public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public ForSer(String str, int count) {
super();
this.str = str;
this.count = count;
}
}
}

5/5/08


JSP Mix

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
< title> Insert title here </title >
<link href="css/index.css" rel="stylesheet" type="text/css">
</head>
<body>
Hello <br /> My darling.
<%-- SCRIPTING ELEMENTS START --%>
<% //scriplet
out.println("-= ## =-");
JspWriter jw = out;
response.getWriter().write("*-*-*-*-*");
%>
<%= //expression
new Integer(50).toString()
%>
<%! //declaration
/*
public void init(){
}
public void destroy(){
}*/
public void jspInit(){
Servlet s = (Servlet)this;
JspPage jp =(JspPage)this;
HttpJspPage hjp = (HttpJspPage)this;
System.out.println("jspInit()");
}
public void jspDestroy(){
System.out.println("jspDestroy()");
}
%>
<%-- SCRIPTING ELEMENTS END --%>
<!-- HTML Comment -- >
<%-- JSP Comment --% >
<jsp:useBean id="myBean" scope="application" class="java.lang.String"></jsp:useBean>

</body>
</html>

EL (Expression Language) was introduces in JSP 2.0!

Some interesting jsp code to generate colored effects:
<% for(int i=0; i< 4095; i++){%>
<div style="
background-color: #<%=Integer.toHexString(0x1000|i).substring(1)%>;
height:1px;"></div>
<%}%>

Form with drop-down list that save its state:

<form action="index.jsp" method="get">
<select size="1" <%-- multiple="multiple" --%> name="join">
<option <%= request.getParameter("join") == null ? "selected" : "" %> ></option>
<option <%= request.getParameter("join") != null && request.getParameter("join").equals("right") ? "selected" : "" %> value="right">right</option>
<option <%= request.getParameter("join") != null && request.getParameter("join").equals("left") ? "selected" : "" %> value="left">left</option>
<option <%= request.getParameter("join") != null && request.getParameter("join").equals("full") ? "selected" : "" %> value="full">full</option>
</select>
<input type="submit" value="sub">
</form>

4/10/08


Java just for fun

fun 1:

0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 = 0.9999999999999999

fun 2:

0.0175 * 100000 = 1750.0000000000002

fun 3:

System.out.println(new Float(1/0.).isInfinite());
System.out.println(new Float(0/0.).isNaN());

fun 4:

Integer a = 10;
Integer b = 10;
System.out.println(a == b);
//true
Integer a = 10000;
Integer b = 10000;
System.out.println(a == b);
//false

LOL



System.out.println( 9.86 + 60.88); // --> 70.74000000000001

3/26/08


J2EE Security with WebLogic 9.2.1 Part 3. Web Services


J2EE Security with WebLogic 9.2.1 Part 2. EJB


Let's consider enterprise bean (EJB 2.1 with WebLogic annotations):

import java.util.Calendar;
import javax.ejb.SessionBean;
import weblogic.ejb.GenericSessionBean;
import weblogic.ejbgen.RemoteMethod;
import weblogic.ejbgen.Session;
import weblogic.ejbgen.JndiName;
import weblogic.ejbgen.FileGeneration;
import weblogic.ejbgen.Constants;
import weblogic.ejbgen.RoleMappings;
import weblogic.ejbgen.RoleMapping;

@Session(ejbName = "MyBean")
@RoleMappings(value={@RoleMapping(principals = "alex", roleName = "admin")})
@JndiName(remote = "ejb.MyBeanRemoteHome")
@FileGeneration(remoteClass = Constants.Bool.TRUE, remoteHome = Constants.Bool.TRUE, localClass = Constants.Bool.FALSE, localHome = Constants.Bool.FALSE)

public class MyBean extends GenericSessionBean implements SessionBean {
private static final long serialVersionUID = 1L;

public void ejbCreate() { }

@RemoteMethod(roles="admin")
public String getDate() {
System.out.println(getSessionContext().getCallerPrincipal().getName());
return "Date from ejb is: " + Calendar.getInstance().getTime().toString();
}
}


Also user alex should be created in Web Logic Server console for default realm. Let's try to invoke that bean from next code:

Hashtable env = new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "weblogic");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");

Context ct = new InitialContext(env);
Object homeObject = ct.lookup("ejb.MyBeanRemoteHome");
MyBeanRemoteHome home = (MyBeanRemoteHome) PortableRemoteObject.narrow( homeObject, MyBeanRemoteHome.class);
System.out.println(home.create().getDate());


The result is: java.rmi.AccessException: [EJB:010160]Security Violation: User: 'weblogic' has insufficient permission to access EJB...

(Also we can use next code to retrieve Initial Context:
weblogic.jndi.Environment env = new Environment();
env.setProviderUrl("t3://localhost:7001");
env.setInitialContextFactory("weblogic.jndi.WLInitialContextFactory");
env.setSecurityPrincipal("alex");
env.setSecurityCredentials( "weblogic");
javax.naming.InitialContext ct = new InitialContext(env.getInitialContext().getEnvironment());)

Let's replace env.put(Context.SECURITY_PRINCIPAL, "weblogic") to env.put(Context.SECURITY_PRINCIPAL, "alex"). The result is Ok.

Let's do:

//env.put(Context.SECURITY_PRINCIPAL, "alex");
//env.put(Context.SECURITY_CREDENTIALS, "weblogic");

The result is: Security Violation: User: 'anonymous' has insufficient permission to access EJB..

Let's use JAAS:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.PrivilegedAction;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.security.auth.login.*;
import com.MyBeanRemoteHome;
import weblogic.security.Security;

public class Main {
public static void main(String[] args) throws Exception {
LoginContext loginContext = null;
loginContext = new LoginContext("Sample", new SampleCallbackHandler("alex", "weblogic", "t3://localhost:7001"));
loginContext.login();
Security.runAs(loginContext.getSubject(), new EjbInvocation());
return;
}

public static class EjbInvocation implements PrivilegedAction {
public Object run() {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ct = new InitialContext(env);
Object homeObject = ct.lookup("ejb.MyBeanRemoteHome");
MyBeanRemoteHome home = (MyBeanRemoteHome) PortableRemoteObject.narrow( homeObject, MyBeanRemoteHome.class);
System.out.println(home.create().getDate());
return null;
}
}
}


Now it's okay too.

Next part of research is accessing EJB from secured servlet described in previous post. Servlet and EJB belong to one Realm. Servlet just contain code in service method:

Hashtable env = new Hashtable();
env.putContext.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
Object homeObject = new InitialContext(env).lookup("ejb.MyBeanRemoteHome");
MyBeanRemoteHome home = (MyBeanRemoteHome) PortableRemoteObject.narrow(homeObject, MyBeanRemoteHome.class);
home.create().getDate();

So access to that sarvlet can be done only by authenticated user. Let's try to access as weblogic user. Result is: Security Violation: User: 'weblogic' has insufficient permission to access EJB:..
Nice! Next login as alex user. Result is Ok (ejb method returned string successfuly). Great. Servlet accesseb EJB with account of user that has been invoking the servlet.

J2EE Security with WebLogic 9.2.1 Part 1. Web


First of all let us look into web application sequrity. Suppose we have some .war file with servlet com.MyServlet and web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Investigation_web</display-name>
<servlet>
<description></description>
<display-name>MyServlet</display-name>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.MyServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<security-role>
<description>This is the boss</description>
<role-name>manager</role-name>

</security-role>

<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>

<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication Area</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login.jsp</form-error-page>
</form-login-config>
</login-config>

</web-app>

Also weblogic.xml contains:

<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wls="http://www.bea.com/ns/weblogic/90" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
<wls:context-root>Investigation_web</wls:context-root>
<wls:security-role-assignment>
<wls:role-name>manager</wls:role-name>
<wls:principal-name>alex</wls:principal-name>
</wls:security-role-assignment>
</wls:weblogic-web-app>


And in WebLogic Server console of our Domain we created user alex in default Realm. And finally there is login.jsp:

<form method="POST" action="j_security_check">
Username: <input type="text" value="weblogic" name="j_username"><br />
Password: <input type="password" value="weblogic" name="j_password"><br />
<br />
<input type="submit" value="Login">
<input type="reset" value="Reset">

</form>

So if user try to access MyServlet or any other resource that meets <url-pattern>/*</url-pattern> he will be redirected into login page. Also if use <auth-method>BASIC</auth-method> then no jsp login page is needed instead will be used popup window from your browser.
It is clear but what if we will try to acess URL in java standalone application's code? First of all I consider possibility of using HttpURLConnection as described in previous post of my blog. In that case we can fulfil:
1-request to login page and accept cookie;
2-post form with parameter names that we can find in login page HTML source (usual: username and password) with cookie;
3-request desired resource with cookie.

But it not seems the solution is simple. There is also Authenticator class to do similar job:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.PasswordAuthentication;
import java.net.URL;

public class Main {


public static void main(String[] args) throws IOException {
Authenticator.setDefault(new SimpleAuthenticator("alex", "password"));
URL myUrl = new URL("http://localhost:7001/Investigation_web/MyServlet");
HttpURLConnection yc = (HttpURLConnection)myUrl.openConnection();
yc.setDoInput(true);
yc.setDoOutput(true);
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}


public static class SimpleAuthenticator extends Authenticator {
private String username;
private String password;
public SimpleAuthenticator(String username, String password) {
this.username = username;
this.password = password; }
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
}
}


But it approach useful only in case of BASIC auth-method. It is called "authenticate using the digest method". Might be we can use JAAS functionality? Pay attention that to run this code on Java 1.5 you have to add file sample_jaas.config that contains:

/** Login Configuration for the JAAS Sample Application **/
Sample { weblogic.security.auth.login.UsernamePasswordLoginModule required debug=false;};


and add line to java.security:

login.config.url.1=file:${java.home}/lib/security/sample_jaas.config

all those in directory: JAVA_HOME\jre\lib\security.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.PrivilegedAction;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.security.auth.login.*;
import com.MyBeanRemoteHome;
import weblogic.security.Security;


public class Main {

public static void main(String[] args) throws Exception {
LoginContext loginContext = null;
loginContext = new LoginContext("Sample", new SampleCallbackHandler("alex", "weblogic", "t3://localhost:7001"));
loginContext.login();
Security.runAs(loginContext.getSubject(), new WebInvocation());
return;
}
public static class WebInvocation implements PrivilegedAction {
public Object run() {
URL myUrl;
try {
myUrl = new URL("http://localhost:7001/Investigation_web/MyServlet");
HttpURLConnection yc = null;
yc = (HttpURLConnection) myUrl.openConnection();
yc.setDoInput(true);
yc.setDoOutput(true);
BufferedReader in = new BufferedReader(new InputStreamReader(yc
.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}


No.. result is the same - we recieve redirect to login page in case of FORM auth-method and "Response: 401: Unauthorized" for BASIC. What about authenticate with certificates? For now nothing ). There is also question about why code to logout user:

request.getSession().invalidate();

does not work in case of BASIC authentication..

Next let's look into using URLConnection from some secured servlet to it themselves. Result of such invoking is the same as from standalone client: so in case of FORM authentication method request redirected to login page and in case of BASIC authentication method Response: '401: Unauthorized'. So the fact that invoking of some URL is doing from already authenticated code does not matter at all. The code have to tranfer cookie explicitly or use another method to authetication (Authenticator class and probably others). What about using url appending instead cookie? For now nothing again)

3/25/08


Servlets invoking by java standalone (form posting)


Sometimes we have to do access to URL resource or in particular invoke some servlet (via HTTP protocol). There is some different approaches to invocation via HTTP protocol: through GET or through POST. GET request is pretty simple to realize. Just put next code:

String url = http://localhost/AppWeb/myServlet?param1=val1&param2=val2";
URLConnection uc = new URL(url).openConnection();
uc.setDoOutput(true);
uc.setDoInput(true);
//TO DO #1 some code put here to sign request as POST
InputStream istr = uc.getInputStream();
//TO DO #2 something do with respond (istr)


Differences (rather similarities) between URLConnection and HttpURLConnection can be shown in next lines:

URL url = new URL(urlString);
URLConnection connection = url.openConnection();
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection)connection;
}

Servlet (myServlet) will accept request from first source as GET method. In "TO DO #2" just do something with servlet's respond. In case of HttpURLConnection it is possible to retrieve response code and message: httpConnection.getResponseCode(); or httpConnection.getResponseMessage() .
It is possible to put next code instead "TO DO #1" to convert that request into POST request:

BufferedWriter wr = new BufferedWriter(new PrintWriter(uc.getOutputStream()));
wr.write("param3=val3&"); //PAY ATTENTION. SYMBOL > & < param4="val4">
Just we fulfil some writing into body of our connection, connection become POST request. There are some difficulties with file adding to POST request from java application and treatment those files in servlets. Firstly, for simple html form posting with file fild, form has to be multipart/form-data (enctype) and there is method setRequestProperty(key, value) in our URLConnection to set these property in java code like by html tags:

<form enctype="multipart/form-data" action="DownWithAPI" method="POST">
<input type="file" name="filetoupload" />
<input type="submit" value="Go" />
</form>


Secondly we need not write some parameters manualy. Instead we can use some simple API (one java file): ClientHttpRequest 1.4 or ClientHttpRequest 1.0. Using is pretty simple too:

String url = http://localhost/AppWeb/myServlet?param1=val1&param2=val2";
ClientHttpRequest client = new ClientHttpRequest(url);
client.setParameter("file", new File("d:/dome.txt"));
client.setParameter("param5", "value5");
client.post().read();


Now look into more difficult part of work - treatment our request on server side (in servlet). Pay attention that servlet deals with post request in doPost method. Transmitted parameters in both case can be retrieved via HttpServletRequest parameter (in doGet or doPost) in manner:

String dataFromClient = request.getParameter("param1");

But in case of multipart/form-data that approach is not useful. Instead we need to parse request.getInputStream() as multipart container. To do this I suggest to use API again: form-data Reader in manner:

Map map = MultipartFormReader.read(request);
String value1= map.get("SomeParamName1").toString();
byte[] file =((DataSource) map.get("fileParam1")).getBinaryContent();
String value2 = map.get("SomeParamName1").toString();

All keys can be retrieved via:

Map map = MultipartFormReader.read(request);
Iterator it = map.keySet().iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}


And also I will talk about downloading with servlet functionality. Method below can clarify this situation:

private void doDownload(HttpServletRequest req, HttpServletResponse resp, String original_filename, InputStream istr){
ServletOutputStream op = resp.getOutputStream();
resp.setContentType("application/octet-stream");
resp.setHeader("Content-Disposition", "attachment; filename=\"" + original_filename + "\"");
byte[] b = new byte[8164];
int len = 0;
int fullLen = 0;
while ((len = istr.read(b, 0, 8164)) != -1){
op.write(b, 0, len);
fullLen = fullLen + len;
}
resp.setContentLength(fullLen);
istr.close();
op.flush();
op.close();
}


Just put him some InputStream (from file for example or byte array stream). After and before invoking of that method do not invoke any response.getWriter().write(" "); because it will be Exception throwing.

There are some interesting issue in working with java.net.URLConnection or
HttpURLConnection. For example it is posible to set some usefull properties:

String url = http://localhost:8080/MyJavaServer_web/Down;
HttpURLConnection hconn = (HttpURLConnection) new URL(url).openConnection();


hconn.setDoInput(true);
hconn.setDoOutput(true);

hconn.setRequestMethod("POST");

hconn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Q312461)");

conn.setRequestProperty("Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
conn.setRequestProperty("Accept-Language","de-de,de;q=0.8,en-us;q=0.5,en;q=0.3");
conn.setRequestProperty( "Accept-Encoding","gzip,deflate");
conn.setRequestProperty( "Accept-Charset","ISO-8859-1,utf-8;q=0.7,*;q=0.7");
conn.setRequestProperty( "Keep-Alive","300");
conn.setRequestProperty( "Proxy-Connection","keep-alive");
conn.setRequestProperty( "Cache-Control","max-age=0");

conn.setConnectTimeout(5000);

wr.flush();


After flushing servlet Down will accept POST request from .. Mozilla.
There is also posibility to set up cookie in the reques:

String cookie = null;
hconn.setRequestProperty("Cookie", cookie);

As you can see "Cookie" in transmitted while web request as plain string. Those string can be retrieved after first request to the server in code:

cookie = hconn.getHeaderField("Set-Cookie");

Pay attention that if server accepts request with "Cookie" property it will not fulfil "Set-Cookie" in response and hconn.getHeaderField("Set-Cookie") will be null.
For using proxy put next code before invoking openConnection() for URL:

Properties systemProperties = System.getProperties();
systemProperties.setProperty("http.proxyHost",proxy);
systemProperties.setProperty("http.proxyPort",port); //And optionally:
System.setProperty("http.proxyUser", "");
System.setProperty("http.proxyPassword", "");

And finally for authentication create simple class:

public class SimpleAuthenticator extends Authenticator{
private String username;
private String password;
public SimpleAuthenticator(String username,String password) {
this.username = username;
this.password = password;
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication( username,password.toCharArray());
}
}

And before creating new URL (URL myUrl= new URL(url);) invoke:

Authenticator.setDefault(new SimpleAuthenticator(username, password));

The end.

3/13/08


Linux forever or dead-end road


I installed Linux Ubuntu 10.4 about two weeks ago.
Firs impressions was very positive. I have some experience with Linux in the past. But it did not meter for now :). I was not able to do any thing except invoke some pre installed application, especially game.
I had some success after two days with help of my friend KirGiz. I have got pretty good speed of system loading, have installed midnight commander :), arena 3 and even new version of JDK and Eclipe Europa (Thanks to Stas also). It was greate. Also I have installed my ATI video card and XGL engine. I did not gain success with "cube desktop" but other nice visual effects was presented. By the the time I bored with all those beauty and even thought that Ubuntu was not good place for me. But.
I returned to research my laptop's Linux couple of days ago. It was related to recent c++ programming under the DOS in Borland c++ 3. When only keyboard was used. First af all I switched off my Gnome XConsole (with rcconf) and find myself in Linux command line interface. After couple of hours I find real beauty and real satisfaction. It was so suddenly that I am fall in love with this OS. I even used lynx. It was very strange experience but cool also. Only command prompt and you. Without any visual unusuall most of time widgets. Only couple of terminals. It is inconvenient for first time but regular operation will be very fast in due course.
There are much programms for console mode, for example audio player. I hope I will find some Java IDE for terminal.
Some usefull commands:
- gedit // Text Editor (GUI)
- dav // Text Editor (console)
- lynx // Web Browser (console) G - addres; O - config; Q - quit; / - page source; [Del] - list of visited addresses.
- rcconf // boot options
- touch Par1 //creates empty file with name as Par1. e.g. /fastboot or /forcefsck
Some interesting locations:
- /etc/fstab

Titanic just wanted to be submarine

Open source or warranty of support?

I met with some problem with WebLogic 9.2 last week.

I am using WebLogic 9.2 sp1 + AquaLogic 2.6 last time. I have created EJB (2.1 right from WLW) with some methods that throws Exceptions. I have tried to create transport typed business service (BS) for my EJB. When I looked into WSDL for that BS I did not find soap faults description for my methods. I sent request to BEA and got response with clarification and patch Id for resolve that problem :)
I installed that patch with Smart Update and it seemed was all okay then. I found SOAP fault block in my WSDL. But.
I tried to fulfil simple code on the patched serverside:

Hashtable h = new Hashtable();
h.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL, "t3://localhost:7002");
h.put(Context.SECURITY_PRINCIPAL, "weblogic");
h.put(Context.SECURITY_CREDENTIALS, "weblogic");
InitialContext inc = new InitialContext(h);

Pay attention that I looked up Initial Context in web application running on the "9.2 SP1 WebLogic Server with patched ALSB" to "8.1 "WebLogic Server"!

I have got Exception:

java.lang.AssertionError: java.lang.ClassNotFoundException: weblogic.jndi.internal.ServerNamingNode_920_WLStubat weblogic.jndi.WLInitialContextFactoryDelegate.newRootNamingNodeStub(WLInitialContextFactoryDelegate.java:587)at weblogic.jndi.WLInitialContextFactoryDelegate.newRemoteContext(WLInitialContextFactoryDelegate.java:559)
....

I had question: "Why Class Loader tries to find ServerNamingNode_920_WLStubat instead of ServerNamingNode_921_WLStubat". I started investigate that problem couple of days ago. I know reason now. But I have spent about a week for that problem :(

First of all I found line in my %WLS_HOME%\common\bin\commEnv.cmd
set PATCH_CLASSPATH=%WLS_HOME%\profiles\default\sys_manifest_classpath\weblogic_patch.jar

Pay attention that PATCH_CLASSPATH got the first place in domain claspath!
That was Jar was installed with patch. By going through chain from that Jar (by manifest Class-Path:... ) I found another Jar. It contains manifest file:

Manifest-Version: 1.0
Created-By: 1.5.0_03 (Sun Microsystems Inc.)
Implementation-Title: AquaLogic Service Bus 2.6 Patch for CR311833
Implementation-Version: 9.2
Implementation-Vendor: BEA Systems

Next I decompiled some chain of weblogic.jar classes (first was WLInitialContextFactoryDelegate) with JAD and have strange result:

------------------------------------------

WLInitialContextFactoryDelegate:
private NamingNode newRootNamingNodeStub(RemoteReference remotereference, int i)
{

...
Class class1 = Class.forName(RootNamingNode.STUB_NAME);

...
}


------------------------------------------

RootNamingNode:
STUB_NAME = ServerHelper.getStubClassName((weblogic.jndi.internal.ServerNamingNode.class).getName());

------------------------------------------

ServerHelper:
public static String getStubClassName(String s)
{
return s + WLS_STUB_VERSION;
}

....
public static final String WLS_STUB_VERSION = "_" + PeerInfo.getPeerInfo().getMajor() + PeerInfo.getPeerInfo().getMinor() + PeerInfo.getPeerInfo().getServicePack() + "_WLStub";

------------------------------------------

PeerInfo:
public static PeerInfo getPeerInfo()
{
return singleton;
}


...

VersionInfo versioninfo = VersionInfo.theOne();
singleton = new PeerInfo(versioninfo.getMajor(), versioninfo.getMinor(), versioninfo.getServicePack(), versioninfo.getRollingPatch(), versioninfo.hasTemporaryPatch(), versioninfo.getPackages());


------------------------------------------

VersionInfo:
public static VersionInfo theOne()
{
return Maker.THE_ONE;
}


...

public final int getServicePack()
{
return servicePack;
}
...
public VersionInfo(boolean flag) throws VersioningError
{

...
packages = getLocalWLPackages();
...

implVendor = packages[0].getImplementationVendor();
implTitle = packages[0].getImplementationTitle();
implVersion = packages[0].getImplementationVersion();
major = packages[0].getMajor();
minor = packages[0].getMinor();
servicePack = packages[0].getServicePack();
...
}


------------------------------------------

Maker:
static final VersionInfo THE_ONE = VersionInfo.access$000() ? new VersionInfo(true) : new VersionInfo(9, 2, 1, 0);

------------------------------------------

There are another constructors in the VersionInfo class but it is clear that for some reason in case of my web application constructor VersionInfo(true) was invoked in runtime.

So as you can see WebLogic gets its version information from ... manifest of the Jar file that placed first in the CLASSPATH!!!! As you remember first Jar file is my patche's Jar with:
Implementation-Version: 9.2
It does not contain version of SP. So WebLogic after patch of AquaLogic does not know about its SP version!
Now I can change order of my Jar in the server CLASSPATH or ... change line:
Implementation-Version: 9.2
to
Implementation-Version: 9.2.1
Both cases are work. I have tested.

The engineer form BEA support said me about those code:

"Well yes, that's true, but you see that the problem is coming from the patch that you install the first time, I guess if the patch was the correct one of the WLS installation , every thing will work fine, but since the patch was not well installed let say, it's logic that nothing will work, for me."

Nevertheless I have one question: why BEA WebLogic AS that able to do anything (almost anything) and costs so much money retrieve version info about itself by using logic:

...

packages = getLocalWLPackages(); //All WebLogic AquaLogic packages in CP

servicePack = packages[0].getServicePack(); //First off all

...

It seems like Titanic 9.2 is the ship until it have gotten some screws from submarine. Just it happens the same time it considered whole itself as submarine :). There is no reason to explain result of that misunderstanding. LOL.


http://forums.bea.com/thread.jspa?threadID=5700000130

http://forums.bea.com/forum.jspa?forumID=2057