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)