Sergeonclear

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Monday, December 31, 2007

Hibernate second level cache

Posted on 4:21 AM by Unknown

Second level cache(2LC) of hibernate boosts the performance of websites.
One needs to be careful to handle the cache refresh.
By default hibernate 3 comes with EHcache for session level
cache(primary cache).
EhCache can also be used for secondary level cache.


Setup of 2LC using EHcache:

1. Setup the session factory with the below details:
hibernate.cache.provider_class as org.hibernate.cache.EhCacheProvider
hibernate.cache.use_query_cache as true

Optionally cache statistics can be enabled by using below

hibernate.generate_statistics as true
hibernate.cache.use_structured_entries as true


2. In the hbm files just under the class element put the below:
cache region="com.xmp.web2.model.Article" usage="read-only"

--in the above, the region is used to identify as cache key.

3. For query cache, set the Query as cacheable programatically.

Query queryObj = session.createQuery(query);
queryObj.setCacheable(true);

-- This will cache all the query result, thus reducing DB hits.

4. To refresh a query programatically, do the below:
-- sessionFactory.evict(Article.class, id); //this will remove from the cache the article object instance with the primary key id. Note that the id is serializable and the type should be the same as defined in hbm.

5. To optionally print the statistics, enable statistic monitoring as told in step 1 and use the below:

static void printCacheStatistics(String regionName) {
Statistics statistics = sessionFactory.getStatistics();
SecondLevelCacheStatistics secondLevelCacheStatistics = statistics.getSecondLevelCacheStatistics(regionName);
System.out.println("2nd level CACHE Statistics :"+secondLevelCacheStatistics.toString());
}

To check cache statistics use the JSP as below:
<%@ page language="java" import="org.springframework.web.context.*,org.springframework.web.context.support.*,org.hibernate.*,org.hibernate.stat.*"%>

<%
String cacheRegion="com.xmp.web2.model.Article";

WebApplicationContext ctx =
WebApplicationContextUtils.getRequiredWebApplicationContext(
this.getServletContext());
SessionFactory sessionFactory = (SessionFactory) ctx.getBean("sessionFactory");
out.print(sessionFactory);
Statistics statistics = sessionFactory.getStatistics();
SecondLevelCacheStatistics secondLevelCacheStatistics = statistics.getSecondLevelCacheStatistics(cacheRegion);
out.print("<br/>");
out.println("Query cache hit count :"+statistics.getQueryCacheHitCount());
out.print("<br/>");
out.print("<br/>");
out.println("2nd level CACHE Statistics :" + secondLevelCacheStatistics.toString());

%>

Reference:
http://doc.javanb.com/hibernate-reference-3-2-4-ga-en/performance.html
http://www.hibernate.org/hib_docs/v3/reference/en/html/performance.html#performance-cache

An excellent write-up on 2ndLC http://tech.puredanger.com/2009/07/10/hibernate-query-cache/
Read More
Posted in hibernate second level cache, linux), LinuxPerformance Tuning(apache, Spring + Hibernate Usefuls BaseDAOHibernate, tomcat | No comments

Monday, December 17, 2007

All about UK Visa.

Posted on 10:25 PM by Unknown

HSMP is a 2 step process as of now.I applied for HSMP visa through a consultant y-axis in Bangalore, India.
They provided good service for getting step 1done(HSMP acceptance). The second part(Entry clearance)
was hopeless service by y-axis. I feel like chewing that consultant who processed it.

They are very keen about proof's (original documents) which has to be genuine and no scope for any errors.

Eg: Say you have your salary credited through cheques, then in the bank statement
you wont have the mention that your XYZ company paid you the salary. So you need
to get a letter for the same from bank or company stating you got the salary from
XYZ company. As long as you prove yourself with the documents the chances of
rejection is very low. Also all your salary slips should be attested by the
corresponding authority.

H1 vs HSMP:
  • The chances of getting visa depends on your documentation which serves as the proof of you skills. Not entirely on luck like in H1.
  • It is not like H1 visa (phaltu lottery system and only done once a year ). HSMP's points calculator is best and you can calculate before hand if you are eligible for it or not. Also you can apply any time of the year as long as you have your documents right. UK guys are smart at applying rules i guess.

As I said before, it is a 2 step process-
  1. Get HSMP acceptance from UK consulate by sending your documents, 400 pounds and details to UK. It took me 3 weeks for getting the HSMP accepted. Actually gathering all the documents for proof of salary, bank stmts, medium of instruction letter etc. took me 1 month. On a whole you should get this first part done in 2-3 months.
2. Once u get HSMP acceptance from UK office, apply for Entry clearance in chennai or
mumbai. I applied through local VFS in bangalore(VFS sent it to chennai).Paid Rs.17,000
at VFS office fee for EC. It is already 3 weeks since I applied. Yet to get a response. HSMP
visa Entry clearance application status can be checked from here
I have got the first part done(got HSMP acceptance letter), the second one is also done. 
Overall the entire process took me 6 months as of now. I could have saved some 2 months had I got all the documents ready. By and large
4-6 months.

Right now I am in UK. More to blog soon.


UK HSMP visa useful Links:
  1. hsmphelp.blogspot.com/
  2. Check the blog ec-hsmp.blogspot.com HSMP blog .On the right you can find various useful section's. This blog is one of the best. No need to go to visa consultant and shell out so much fortune.
  3. http://www.workpermit.com/uk/hsmp_calculator.htm --> HSMP point calculator. This may change in first quarter of 2008. Watch out.
  4. Job assistance in Uk 00 44 114 207 6020 -Aman http://www.vertex-solutions.co.uk/technical-recruitment/immigrationservices.asp Tel (UK): 08456 448 441
http://forums.gumtree.com/about2685-25.html
  1. Direct Dial: (+44) 144 222 1320
  2. Buy tickets for UK to/from india at
    1. http://www.ticketstoindia.co.uk/result_new.aspx
  3. For currency, time, phone number conversion check
    1. http://www.timeanddate.com

FAQ
What is the cheap and best place to stay in london. What is the price of apartments?

Eastham is cheap with lot of asians but not so safe. For a bachelor it will cost around 300 pounds for a shared acco of 3 people.
Around 450 for 2 people. Thats a rough estimate...Depends on the owner.

How much cash should one carry for travel and job search?
Around 300 pounds for flight + travel.. You might spend 600 pounds a month overall staying here.
If u r traveling for job search you will need some more like 100 pounds more.
So that might cost you 2- 3 lak rs for 2-3 months to come here and stay ,search a job.... Its ur best try and luck how
soon u get the job.
Suggest some possible ways to get a job by seating here in india?
Sitting in India and trying a job is not a good idea. Chances are i can say only 10%. If u want to get work form India , chances are u end up with an Indian company who has UK requirement.... Also many consultants here dont call indian numbers. You need to prepare yourself with finances so that u survive in UK for atleast 2-3 months without a job(that might cost you 2- 3 lak rs).


Read More
Posted in All about UK Visa HSMP VS H1 hsmp assistance | No comments

Wednesday, December 12, 2007

LinuxPerformance Tuning(apache,tomcat,linux) and related

Posted on 11:21 PM by Unknown
Web profiling
-- HTTPAnalyzer --
-- YSlow --CSS,Javascript report , time/size measurement for individual component is good.
-- FireBug -- Net performance, for a quick analysis.
--Open STA
Tomcat profiling
-- JProfiler
-- Hot spots ,JDBC queries(J2ee components), object instance count are useful.

--Database connection pooling with optimal values.
Connection leakage in DBCP can be easily detected by settin logAbandoned=true in resource configuration (server.xml). This is a very nice feature and throws up the exact location of the code which is not closing the connection. These connection issues normally come up during load testing.Also the jndi resource configuration for DBCP should have ideal settings. The one used for our project is below:

[GlobalNamingResources]
[Resource
name="jdbc/cmpPubPool"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:oci:@[TNSNAME]"
removeAbandoned="true"
logAbandoned="true"
maxActive="2"
maxIdle="2"
initialSize="2"
maxWait="-1"
username="[USER_NAME]"
password="[USER_PASSWORD]"
validationQuery=”select 1 from dual” /]
[/GlobalNamingResources]


JVM Tuning
Modify the heap size in JAVA_OPTS.


Apache tuning
prefork or worker module can be used.
prefork is non thread based.
Worker module is multi threaded and may yield a better performance.

Linux
--$top -- to check CPU status

top


Top has probably hundreds of keys to do whatever you want. A few are most useful for me.


The > key sorts by the next column (%MEM) instead of the default (%CPU). < sorts by the previous column.


Hit c
to toggle the display of command line arguments. Useful for me when I
have a lot of processes that otherwise just show up as “java”





Typing A
brings up the alternate display, showing processes sorted by different
fields with different columns. One section shows a nice memory-centric
view, for example.
Hitting z turns on colors. Z brings you to a color selection screen where you can pick colors you want. B turns on bold for some fields.
Hit W to save all your configuration changes to ~/.toprc where it will be loaded next time.
Type k allows you to kill a process without exiting top.

-- kill -3 <TOMCAT_PID> will log the threads running/inactive details useful for troubleshooting performance issues.
On windows use CTRL +Break.

Hardware
-Linux memory size can be checked using
cat /proc/meminfo --Gives RAM size
free -m -- Gives RAM size in MB (-k for kb)
df -H -- Human readable format of hard disk size


Useful links
http://jha.rajeev.googlepages.com/web2push



Powered by ScribeFire.

Read More
Posted in linux), LinuxPerformance Tuning(apache, tomcat | No comments

Monday, November 19, 2007

Spring + Hibernate Usefuls

Posted on 3:40 AM by Unknown

The below custom BaseDAOHibernate class should reduce most of the common DAO related coding. The search and searchAdvanced will be used to wrap the select query related method calls.


package com.xmp.web2.dao;


public class BaseDAOHibernate extends HibernateDaoSupport implements DAO {

private static final Log LOGGER = LogFactory.getLog(BaseDAOHibernate.class);

protected DataSource dataSource;

public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

public void saveObject(final Object object) {
getHibernateTemplate().saveOrUpdate(object);
}

public Object getObject(final Class clazz, final Serializable id) {
Object object = getHibernateTemplate().get(clazz, id);

return object;
}

public List getObjects(final Class clazz) {
return getHibernateTemplate().loadAll(clazz);
}

public void removeObject(final Class clazz, final Serializable id) {
getHibernateTemplate().delete(getObject(clazz, id));
}

public List findObject(final Class clazz, final String columnName, final String articleID) {
return getHibernateTemplate().find("from " + clazz.getName() + " tableAlias where tableAlias." + columnName + " in ( " + articleID + " )");
}

/**
* Accepts a HQL and ordered map of parameters.
*
* @param query
* @param parameters
* @return
*/
public List search(String query, LinkedHashMap parameters) throws xmpWebException {
boolean keepSessionOpen=false;
return search(query, parameters, keepSessionOpen);
}

/**
* Accepts a HQL and ordered map of parameters.
* The caller of this method should explicitly close the session.
* @param query
* @param parameters
* @parm keepSessionOpen -boolean to instruct if the session should be closed or not.
* @return
*/
protected List search(String query, LinkedHashMap parameters, boolean keepSessionOpen) throws xmpWebException {
List objList = null;
Session session = null;
try {
if (LOGGER.isInfoEnabled()) {
LOGGER.info(new StringBuilder().append("Searching ( query = ").append(query).append(" ,parameters =").append(parameters).append(")").toString());
}
session = getHibernateTemplate().getSessionFactory().openSession();
Query queryObj = session.createQuery(query);
queryObj.setCacheable(true);

if (parameters != null) {
for (Iterator iter = parameters.keySet().iterator(); iter.hasNext();) {
String key = (String) iter.next();
Object value = parameters.get(key);
queryObj.setParameter(key, value);
}
}
objList = queryObj.list();

} catch (Exception e) {
String msg = new StringBuilder("Search failed ( query = ").append("Searching ( query = ").append(query).append(" ,parameters =").append(parameters).append(")").toString();
LOGGER.error(msg, e);
throw new xmpWebException(msg, e);
} finally {
if (!keepSessionOpen) {
if (session != null && session.isOpen())
session.close();
}
}
return objList;
}

/**
* Accepts a HQL and ordered map of parameters. Useful with pagination as it
* accepts pageNo and pagesize.
*
* @param query
* @param parameters
* @param pageNo - The starting page number
* @param pageSize - The max record size.
* @return
*/
protected List searchAdvanced(final String query, final LinkedHashMap parameters, final int pageNo, final int pageSize) throws xmpWebException {

boolean keepSessionOpen = false;
return searchAdvanced(query, parameters, pageNo, pageSize, keepSessionOpen);
}
/**
* Accepts a HQL and ordered map of parameters. Useful with pagination as it
* accepts pageNo and pagesize.
*
* @param query
* @param parameters
* @param pageNo - The starting page number
* @param pageSize - The max record size.
* @param keepSessionOpen - boolean to identify if session needs to be kept open or not.
* @return
*/
protected List searchAdvanced(final String query, final LinkedHashMap parameters, final int pageNo, final int pageSize, boolean keepSessionOpen) throws xmpWebException {
if (LOGGER.isInfoEnabled()) {
LOGGER.info(new StringBuilder("Searching with ( query = ").append(query).append(" ,parameters =").append(parameters).append(" ,pageNo =").append(pageNo).append(" ,pageSize= ").append(
pageSize).append(" )").toString());
}
Session session = null;
try {
session = getHibernateTemplate().getSessionFactory().openSession();
Query queryObject = session.createQuery(query);
// queryObj.setCacheable(true);
if (parameters != null) {
for (Iterator iter = parameters.keySet().iterator(); iter.hasNext();) {
String key = (String) iter.next();
Object value = parameters.get(key);
queryObject.setParameter(key, value);
}
}
queryObject.setMaxResults((pageSize < msg =" new" query = ").append(query).append(" parameters =").append(parameters).append(" pageno =").append(pageNo).append(" pagesize= ").append( pageSize).append(">


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

The above should solve most of the basic coding effort in DAO layer which we do 90% of the time.


Spring+Hibernate Junit testing:
Spring framework provides a nifty base class (AbstractTransactionalDataSourceSpringContextTests) that provides automatic transaction rollback, exposing a JDBC template to interact with the DB and auto wiring of beans.


Lets take a simple DAO class that save a User object to the database:


public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
public void save(User user) {
getHibernateTemplate().save(user);
}
}

Now in order to test this you would write a test class as below extending from AbstractTransactionalDataSourceSpringContextTests class.



public class UserDaoTest extends AbstractTransactionalDataSourceSpringContextTests {
private UserDao userDao;
private SessionFactory sessionFactory = null;

protected String[] getConfigLocations() {
return new String[]{"test-spring-config.xml"};
}

public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}

public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}

/**
* Test the save method
*
*/
public void testSave(){
String query = "select count(*) from user where first_name = 'Firstname'";
int count = jdbcTemplate.queryForInt(query);
assertEquals("A user already exists in the DB", 0, count);

User user = new User();
user.setFirstName("Firstname");

userDao.saveUser(user);

// flush the session so we can get the record using JDBC template
SessionFactoryUtils.getSession(sessionFactory, false).flush();

count = jdbcTemplate.queryForInt(query);
assertEquals("User was not found in the DB", 1, count);
}
}

The test class has to implement the protected String[] getConfigLocations() method from the base class and return a String array of Spring config files which will be used to initialize the Spring context.

UserDao and SessionFactory properties are defined with the setter methods and the base class will take care of injecting them automatically from the Spring context. Auto wiring will not work if there are multiple objects implementing the same interface. In such a case you can remove the setter method and retrieve the object using the exposed applicationContext as below.

   /**
* Overridden method from base class which gets called automatically
*/
protected void onSetUpBeforeTransaction() throws Exception {
super.onSetUpBeforeTransaction();
userDao = (UserDao) applicationContext.getBean("userDao");
}

The base class also exposes a JDBC template object (jdbcTemplate) that can be used to query data or setup test data in the database. Note that you need to have a data source and a transaction manager defined in your Spring config in order to use the AbstractTransactionalDataSourceSpringContextTests base class. The data source defined in the config file will be bound to the exposed JDBC template.

In the testSave method first we verify there is no record in the User table where first name equals to 'Firstname' using the jdbc template object. Then we call the save method on the UserDao passing it a User object.

Now we simple verify there is a record in the table where first name equals to 'Firstname'. Before running the query we flush the current Hibernate session to make sure jdbcTemplate can see the newly added record.

Thats it and when the testSave method exits the current transaction will be rolled back and the record inserted to the User table will not be saved. This is great as your test database will always be at a know state at the start and end of a test method.

The spring config file will like below (test-spring-config.xml) :





<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean name="userDao" class="com.dao.UserDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="mappingResources">
<list>
<value>hibernates/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
</props>
</property>
</bean>


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL" />
<property name="username" value="test" />
<property name="password" value="test" />
</bean>


<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>

</beans>


Useful stuff:
HQL many to many query for retreival
from UserTask ut where :journal in elements(ut.journals)


Read More
Posted in Spring + Hibernate Usefuls BaseDAOHibernate | No comments

Wednesday, November 14, 2007

Single Sign on - OpenSSO

Posted on 11:54 PM by Unknown
Single Sign on using OpenSSO.

OpenSSO was earlier called as access manager.
OpenFM is openSSO + federation (Cross domain support?)

It was a herculian effort to get it going with openfm/OpenSSO.

  1. Access Manager(opensso/openfm) configuration:
Mainly it seems to be having bugs in the user interface of the webapp it provides.
  • First thing I came across when deploying the openfm.war on linux was as below:

  • -First time when we go to http://localhost:8080/openfm and try to
    configure the openfm, it gives a error with no stack trace nothing . It
    misleads you with a path to log file which you can find in their(sso
    developers) dreams.GRRRR.
  • Had to search around
    in Red hat linux Enterprise edition 5. Later figured that it creates a
    folder with name @BASEDIR@ under tomcat/bin/... Who can imagine a
    cryptic folder for logging sso errors that too under tomcat/bin/...
    Wasted almost 1.5 days on that ....
  • In another version of linux, the above didn't work out. It was in tomcat logs catalina.out. Lucky!!
  • The
    problem usually tends to be due to wrong JDK. The Sun JCE comes as
    default with Sun JDK but not with IBM JDK. The Sun JCE is used for
    encryption of password by open SSO.

  • Another important thing. First time you setup access manager you should
    be careful. Next time, if you try setting it up(by deploying new
    openfm.war) , it complains. Under windows u can simply delete the
    access manager folder created during installation (default is C:\Doc and settings\user name\)...
  • Under linux it should be somewhere under /home/ by default. Search using locate access manager. The custom path would be the one which you setup openSSO using Configurator.jsp.
  • If
    you mess up access manager by configuring authentication chain or data
    store, the work around is use the default module=DataStore as URL parameter eg: http://localhost:8080/openfm/UI/Login?module=DataStore
Then you can login as amAdmin
  • By
    default the openfm ships with set of authentication plugin like JDBC,
    LDAP based , etc .Our requirement needed to compare the user entered
    auth password with MD5 encrypted password. Hence had to build a custom
    authentication plugin. Luckily sun provide service provider
    interface(SPI).Implementing this was a major effort as there is hardly
    any documentation or forum talking about it.Took a short cut by
    extending the sun provided com.sun.identity.authentication.modules.jdbc.JDBC.java
    and over riding transform() method. It works smooth

To add a custom authentication plugin, follow the below steps:
  1. Move the custom

    authentication jar which you wrote (opensso_xmp_plug_v1.0.1.jar) into
    the ~/openfm/WEB-INF/lib folder.All the related property files should
    be on class path.


  1. Copy the custom
    Authentication JDBC configuration file. amAuthxmpJDBC.xml into ~/openfm/WEB-INF/classes
    folder.Refer amAuthJDBC.xml in the same folder for creating a similar one for your custom auth module.

  1. Register the module in
    serviceNames.properties abailable under openfm/WEB-INF/classes to have
    amAuthXMPJDBC.xml. (Add amAuthxmpJDBC.xml at the end)

  1. Copy XMPJDBC.xml into ~/openfm/config/auth/default
  2. Restart tomcat.
  3. Login to Access Manager, Goto
    Configuration
    -- Authentication --Core
  4. Enter com.xmp.security.plugin.XMPJDBC as New Value and click on Add to configure
    the new service.
  5. Go to Access Control and
    select the realm (opensso). Click on Authentication &gt; Module Instances
    and Add the previously configured XMPJDBC module to the authentication
    chain as shown below: Save the information.
  6. Now the Login of opensso will use xmpJDBC module as default for
    authentication. If you want to login with the amAdmin user,
    module=DataStore need to be added to login URL (like
    http://localhost/openfm?module=DataStore)
  7. Login with a valid userId and password (sample xello@xello.com/xello)
    The user is taken to the successful login page.

NOTE:
  • Once a user is logged in successfully, the access manager by default
    looks for the user's profile through Id repo. This is the default
    behaviour. This can be over ridden by setting the property in
    realm(opensso) -- Authentication -- Advanced (look profile) to ignored.

  • Using custom com.sun.identity.agents.filter.SSOTaskHandler class, we can
    insert a session attribute which is used by the SSO agent/application
    for auto login (discussed later , for now agent is like a client to
    open sso). The sample code is below:
public class SSOTaskHandler extends AmFilterTaskHandler implements ISSOTaskHandler
{...
public AmFilterResult process(AmFilterRequestContext amfilterrequestcontext) throws AgentException
{

.........
amfilterrequestcontext.getHttpServletRequest().getSession().setAttribute("SSO_VALIDATION_RESULT",ssovalidationresult);
.............
}
........
}



TODO: J2EE agent
The agent J2ee 007 would be hiding in the web application root web.xml(as AmAgentFilter) to provide secured access. ;)
AMAgent.properties is where the whole good behaviors of the badly behaving J2ee agent is configured. This is generated by amadmin tool and updated later. Check it below for only the important parameters to manually update
----------------------------------------------------------------------------------------------------------

#
# CDSSO PROCESSING PROPERTIES
com.sun.identity.agents.config.cdsso.enable = true
com.sun.identity.agents.config.cdsso.redirect.uri = /agentapp/sunwCDSSORedirectURI
com.sun.identity.agents.config.cdsso.cdcservlet.url[0] = http://172.20.41.39:6060/openfm/cdcservlet
com.sun.identity.agents.config.cdsso.clock.skew = 0
com.sun.identity.agents.config.cdsso.trusted.id.provider[0] = http://172.20.41.39:6060/openfm/cdcservlet

#
# LOGOUT PROCESSING PROPERTIES
com.sun.identity.agents.config.logout.application.handler[] =
com.sun.identity.agents.config.logout.uri[DefaultWebApp] =/web/xmpXMS/logout
com.sun.identity.agents.config.logout.request.param[] =
com.sun.identity.agents.config.logout.introspect.enabled = false
com.sun.identity.agents.config.logout.entry.uri[DefaultWebApp] =/web/xmpXMS/home
#
# NOT-ENFORCED URI PROCESSING PROPERTIES
# - notenforced.uri: A LIST of URIs for which protection is not enforced
# by the Agent.
# - notenforced.uri.invert: A flag that specifies if the list of URIs
# specified by the property notenforced.uri should be inverted. When
# set to true, it indicates that the URIs specified should be enforced
# and all other URIs should be not enforced by the Agent. Entries in
# this list can have wild card character '*'.
# Example of notenforced.uri:
# com.sun.identity.agents.config.notenforced.uri[0]=*.gif
# com.sun.identity.agents.config.notenforced.uri[1]=/public/*
# com.sun.identity.agents.config.notenforced.uri[2]=/images/*
#
com.sun.identity.agents.config.notenforced.uri[0] =
com.sun.identity.agents.config.notenforced.uri.invert = false
com.sun.identity.agents.config.notenforced.uri.cache.enable = true
com.sun.identity.agents.config.notenforced.uri.cache.size = 1000

#
# DEBUG SERVICE PROPERTIES
# - com.iplanet.services.debug.level: Specifies the debug level to be used.
# The value is one of: off, error, warning, message. ******** Funny thing, debug is missing but it actually is very useful for developers********
com.iplanet.services.debug.level=debug
--------------------------------------------------------------------------------------------------------------

TODO: Web Agent







Powered by ScribeFire.

Read More
Posted in Single Sign on - OpenSSO with Liferay | No comments

Wednesday, October 31, 2007

The art of debugging

Posted on 2:08 AM by Unknown


Software debugging is used to troubleshoot a problem in code.

So what is the best way of debugging?
1. Run through the log statements
2. Start a debug session in your favourite IDE. The session can be remote(for a web app) or local.
3. Narrow down to the problem by reducing the dependencies. Is it because of the framework or your own code, to know that reduce the code and test piece by piece.

Option 2, Debugger is the best arsenal for troubleshooting issues in code. Mixing 1,2 and 3 would be the ultimate way to fix the worst problem.
For details of remote debugging in eclipse please refer to my earlier posts.

In eclipse I find the below things very useful in debugging session:
1. Breakpoints:
1.Put a breakpoint in eclipse. You can also edit the breakpoint properties by right clicking on the breakpoints properties. Here you can put a condition and put S.o.p for quickly identifying the problem
2. Exception breakpoint is a cool feature which will catch the exception which you specify. This will help you find the control flow(especially with nasty Null pointer exceptions). You can specify this by clicking on the "Add Java Exceptions" breakpoint of breakpoints view.

2.If you're running in debug code, you can actually just edit
the method and re-invoke it. None of this resetting variables on the
fly; just save the new method and do 'drop to stack' to get it to
re-run the code.
You can't do this if you're not running your application in eclipse, but are rather joined to it as a remore debugger.

3. Variables can be reset in debugging session through expressions or variables view.

4. Short cuts:
CTRL+SHIFT +I -- to check a variable after selection.
F5, F6, F8

Useful links
Jacoozi - Remote Debugging with Eclipse



Read More
Posted in debugging eclipse tips, The art of debugging | No comments

Monday, October 29, 2007

JNDI test JSP page

Posted on 12:23 AM by Unknown

<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" import="javax.naming.*" %>
<% InitialContext initialContext = new InitialContext();
Object obj=initialContext.lookup("java:comp/env/jdbc/xmpPubPool");
out.print(obj);
%>
Read More
Posted in JNDI test JSP page | No comments

Thursday, October 25, 2007

Useful Eclipse Plugins + shortcut keys

Posted on 10:19 PM by Unknown
Here is a list of plugins and their usefulness:

  • MyEclipse -- Is a heavy wieght champion among plugins.Has lot of good features that makes it good as well as bulky. It sucks lot of memory.

Swing Tools

  • jigloo -- Very good, clean and free Swing code generator. Makes swing development like VB.

Code Analysis:
  • pmd

Javascript:

  • jsEclipse
  • Teniga_Javascript_Editor

Miscellaneous
  • Mylyn --- Connects to task repository and eases task managemnt.Also standalone support
  • JadClipse --Uses Jad to decompile class

  • jautodoc -- Very useful for quick API documentation.

  • junitBuilder -- Generate Junit automatically for classes..Saves time
  • moreunit - a must have for junit. http://moreunit.sourceforge.net/org.moreunit.updatesite/

  • phpeclipse -- Good for PHP developers.

  • VelocityWebEdit -- Cool velocity template validation and edit tool

  • patternbox -- very useful for building regular expressions quickly.

  • xmlbuddy -- neat small and simple xml editing tool.

  • subclipse --SVN plugin
  • NTail - tail for eclipse http://www.certiv.net/

  • Eclipse HttpClient -- is a Rich HttpClient Plugin with stunning user
    interface and build on top of the famous Apache HttpClient
  • Jar class finder - give a class , it will find the jar where it belongs to.
http://www.alphaworks.ibm.com/tech/jarclassfinder/download
MDA tools/plugins ---These have the ability to generate j2ee code automatically based on model driven architecture
  • andromda

AJAX Plugins

  • aptana

DB Modelling


  • Clay modelling tool DB_Modelling_jp.azzurri.clay

Short Cut keys :
CTRL+E for switching editors.Ctrl + F6 to navigate between the open editors,

CTRL+ F11 for executing last command.
Refactoring
ALT +SHIFT+R --rename variable
ALT + SHIFT + M -- extract method


Indentation

CTRL + I -- correct indentation individually.
CTRL + SHIFT + F -- whole page format.

Creation:
CTRL+ N. I found it much easier to press ALT + E (extend) to add extended class
and ALT + A (add interface) to add interfaces in the new class wizard.
My class will then come out with empty overridden methods and correct
imports.

Search
CTRL+Shift+G, which searches the workspace for references to the selected method or variable. 5 stars.

Agility
F3
Go to a type declaration
CTRL + SHIFT + UP(DOWN) -- move up or down to the next member
CTRL+T on an interface name...This list the implementation of the interface. Very useful. 5 stars
CTRL+. and CTRL+, Move to one problem (i.e.: error, warning) to the next (or previous).

Ctrl-F6 is a great way to jump around between open
editors.
CTRL+F7 to switch views...Verrrry useful
CTRL+F8 to switch perspectives.

Ctrl-O in a class definition brings up Quick Outline.
Start typing a member name and hit return once it’s unambiguous.
Combined with Open Type this is a lightning fast way to go to any
method in any class.ctrl-o ctrl-o to show inherited members too!

Less typing

I think of Quick Fix as a tool for writing code,
not something that just corrects accidental errors. Instead of trying
to type perfect code and using Quick Fix only when you make a mistake,
try intentionally leaving out code, then using Quick Fix to add it in.
For example, call a function that isn’t defined, passing in all
the arguments you want to to take. Use Ctrl-1, Enter to create an empty
version of the function with all the right parameter types. I also like
Quick Fix for creating casts. I assign an expression to a variable
without a cast, then use Quick Fix to add it in.


Instead of declaring a variable and then assiging the value of an expression to it, try just writing the expression, then use Quick Assist – Assign to Field
(Ctrl-2 L) to generate the declaration. The variable name will be
highlighted and the drop down gives you several reasonable alternatives
to use for the variable name. Tab again to get to the type to choose an
alternative. For example if you had new ArrayList<String&gt;() and used Assign to Field you might choose List<String&gt; from the list of type alternatives.

More here : http://eclipse.dzone.com/news/effective-eclipse-shortcut-key

More here : http://rayfd.wordpress.com/2007/05/20/10-eclipse-navigation-shortcuts-every-java-programmer-should-know/

Powered by ScribeFire.

Read More
Posted in Useful Eclipse Plugins eclipse shortcuts keys | No comments

Monday, October 22, 2007

linux tips

Posted on 2:22 AM by Unknown

Tomcat Remote debugging in linux
Put the below in catalina.sh

JPDA_TRANSPORT=dt_socket
JPDA_ADDRESS=5005
$./catalina.sh jpda start
Startup script with logging:
Create a file with the following and change the mode to executable under $catalina_home/bin
./startup.sh;tail -f ../logs/catalina.out

For shutdown create as below:
./shutdown.sh;tail -f ../logs/catalina.out

Restart script for linux:

./shutdown.sh
echo "shutdown.sh executed"
echo "Sleeping for 5 seconds after shutdown"
sleep 5
./startup.sh
echo "starting up"
echo "Sleeping for 1 second"
tail -f ../logs/catalina.out


Jar usage
$cd portal-impl
$jar xvf portal-impl.jar :extracts the jar file into portal-impl dir.
$jar cvf portal-impl-patched.jar portal-impl/ :make jar file from portal-impl dir contents the jar will be having portal-impl as the root dir.

To change ownership:
$chown tomcat:tomcat FILE_NAME

To change group:
$chgrp tomcat FILE_NAME

To Switch user:
$su USER_NAME

Clear all unwanted .SVN files
find . -name ".svn"-exec rm -rf {} \;

Read More
Posted in Tomcat on linux tips commands | No comments

Friday, October 12, 2007

JProfiler - A J2ee profiling tool

Posted on 5:16 AM by Unknown
This is one of the best profiling tools i have seen.
They give a 10 day free evaluation with all feature's enabled.

Setting up the Jprofiler was a little tedious until I came to know how it works.
I was expecting that the Jprofiler would put some custom code in tomcat(like profiler4j) but actually it runs the tomcat in it's own session.

On windows, setup the application with downloaded exe.
Go to New -- Start center -- New Server integraion and you are done.
The app server gets started and log console is available through Jprofiler itself.

Another nice feature of jProfiler is remote connectivity. We can connect to server running in linux from windows.
To do that, install jProfiler on linux as below
rpm -i http://download.ej-technologies.com/jprofiler/jprofiler_linux_5_0_1.rpm
Get the catalina.sh(for tomcat) and give to the start center wizard. Copy back this(jprofiler_startup.sh) to tomcat on linux. Now start the server using jprofiler_startup.sh.

Connect from windows GUI and you are ready for profiling..


The real thing :
Profiling can be done for memory or CPU load. The hot spots are the best ones to quickly find out the problem areas.
Also J2ee components can be easily profiled for JDBC calls, JMS calls,etc.





Powered by ScribeFire.


Read More
Posted in JProfiler setup jprofiler on linux | No comments

Thursday, October 4, 2007

Apache 2.x setup Quick guide for Linux

Posted on 9:20 PM by Unknown

I am herewith trying to log all the issues faced during apache web server setup.
Download apache from http://httpd.apache.org/download.cgi

There you can find either a source or binary.

Normally it is good to compile the source to a OS platform. But it is little extra effort. Setting up using a apache binary is faster but may not be reliable.

Here are basic and advanced steps for apache setup:

To setup , follow these very basic steps to setup apache in it's default location
Extract the apache bundle

1. tar xvf apache.x.tar
2. cd apache.x
3. ./configure
4. make
5. make install
6. cd ./apache/bin
7. ./httpd -k start[stop] # run's on port 80 which is default

Open browser..Go to http://localhost/ #....This should open a page ...It Works!!

To make an advanced setup like configuring additional modules, setup destination,etc , do the following:

1. tar xvf apache.x.tar
2. cd apache.x
3. ./configure --prefix=/path/to/apache --enable-[auth]=shared
4. make
5. make install
6. cd ./apache/bin
7. ./httpd -k start[stop]


Go to ./apache/conf/httpd.conf to change the port or any other setting. Will blog later on httpd.conf .

To have apache use a custom httpd.conf on startup do this :
./httpd -k start -f /custom/conf/httpd-custom.conf

To chek if apache supports DSO, run
./httpd -l # this lists all the modules setup in apache

I have listed a set of modules which were enabled for apache 2.0.59 to run a website on production:

--enable-authn_file=shared --enable-authn_anon=shared --enable-authz_host=shared --enable-log_config=shared --enable-logio=shared --enable-expires=shared --enable-headers=shared --enable-setenvif=shared --enable-mime=shared --enable-status=shared --enable-vhost_alias=shared --enable-dir=shared --enable-alias=shared --enable-rewrite=shared --enable-access=shared --enable-auth=shared --enable-userdir=shared --enable-autoindex=shared --enable-negotiation=shared

There are thousands of directives to be configured in httpd.conf .Refer http://httpd.apache.org/docs/2.2/mod/directives.html for apache 2.2

To change the server port by changing in ./apache/conf/httpd.conf the Listen 80 directive

Virtual host directive : A single apache server can have multiple virtual hosts and can server different sites.

To set this, open ./apache/conf/httpd.conf and enter the directive as below:


<VirtualHost 172.20.41.39:80>
ServerName xyz.com
ServerAlias www.v2.xyz.com v2.xyz.com www.eetonline.com www.xyz.com eetonline.com

DocumentRoot /web/docs/electronics/v3.xyz.com
DirectoryIndex index.html index.htm
ErrorDocument 403 /nopagefound.jhtml
Redirect /uk/motorola http://www.xyznet.com/

<Location "/globalSpec"> # to specifiy the mounted directory to be used
ExpiresActive on
ExpiresDefault "access"
Header append Cache-Control "no-cache"
Header append Expires "Thu, 4 Jan 1990 10:00:01 GMT"
Header append Last-Modified "Tue, Jan 27 2099 23:59:59 GMT"
Header append Pragma "no-cache"
Options FollowSymLinks MultiViews
satisfy any
Order deny,allow
Deny from all
AuthType Basic
AuthName "xyz login"
AuthUserFile /web/admin/apache/etc/auth/xyz.com-globalSpec
require valid-user
</Location>
<VirtualHost>




Read More
Posted in Apache 2.x setup Quick guide for Linux | No comments

Saturday, September 29, 2007

Chess

Posted on 9:34 AM by Unknown
Blind folded Chess
I browsed a few sites for how to start off with blind folded chess.
Infact the chess player need not be blind folded. He just needs not to see the board.

The mind is the board, the scratch pad for tactics and thinking.

Start with basic's ..Try moving pawns in your mind, then knights, then rook, bishop and then queen.


Crafty is a nice little program to play blind folded chess. [www . craftychess . com]
This follows algebraic notation and has only a command line interface. It clearly shows how the program is taking decisions.

Really playing blind folded expands your mind tremendously.
More to come as I explore this Blind folded!!


Good chess links:
http://susanpolgar.blogspot.com/ -- GM susan polgar's blog.
http://www.rajaravisekhar.com/


Powered by ScribeFire.

Read More
Posted in Blind folded chess | No comments

Wednesday, August 29, 2007

Spring portlet mvc and spring servlet mvc validation

Posted on 11:10 PM by Unknown
Spring mvc is easy to get along with, unless we get the basic flow right. We end up wasting lot of time figuring out the flow of control/binding of errors for validation/etc.

Spring portlet mvc validation
  1. extend AbstractCommandController or SimpleFormController
  2. In case of AbstractCommandController implement the method handleRenderView(req,res,command,errors)
  3. Important thing to note is that you should return the ModelAndView as new ModelAndView(jspPage, errors..getModel());

  • Note the method handleRenderView() is called even if validation fails. Hence we have to return back the command object having errors using errors.getModel().

Spring servlet mvc validation
  • Implemented a simple form controller.
class ManageProfileController extend SimpleFormController
{
public ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception
{
Map modelMap = new HashMap();
return new ModelAndView(forwardJSP, modelMap);
}
}

  • The configuration in *-servlet.xml is as below (assume dispatcher servlet is configured already)

<bean id="manageProfileController" class="com.TEST.web2.portlet.controller.common.ManageProfileController">        
<property name="registrationService" ref="registrationService"/>
<property name="formView"><value>common/manageprofile</value></property>
<property name="commandClass"><value>com.TEST.web2.model.DpsUser</value></property>
<property name="validator" ><ref bean="userValidator"/></property>
<property name="successView"><value>common/manageprofile</value></property>

</bean>

  • On validation error, in servlet mvc, the onSubmit() is not called and the command object is available with errors.

  • To extract the errors in JSP use:


<spring:bind path="command.confirmPassword">

<c:out value="${status.expression}"/> <input name=confirmPassword type="password" style="width:200px; " onKeyUp="document.getElementById('cpw').value=this.value" value="<c:out value="${status.value}"/>">
<font > <c:out value="${status.errorMessage}"/> </font>

</spring:bind>
Read More
Posted in Spring portlet mvc and spring servlet mvc validation | No comments

Wednesday, August 22, 2007

Castor --The XML Marshaller

Posted on 8:48 PM by Unknown
Forget writing XML parser...Castor will take care of parsing. It generates the java
classes to work with XML.

To use castor,
-- put the below lib's in classpath
-- ./lib/castor-0.9.9.jar
./lib/castor-0.9.9-srcgen-ant-task.jar
./lib/castor-0.9.9-xml.jar
xercesImpl.jar;
commons-logging.jar

-- Run java org.exolab.castor.builder.SourceGenerator -i test.xsd -dest dtnFolder
--optionally specify the package name if required.

-- To convert from DTD to XSD use
java org.exolab.castor.xml.dtd.Converter dtdFileName newXSDFileName

To use the generated code:

  • To run the unmarshal the castor lib should be in class path and follow the sample code herewith.

// Create a Reader to the file to unmarshal from
reader = new FileReader("test.xml");

// Marshal the person object
Person person = (Person)Unmarshaller.unmarshal(Person.class, reader);

  • To marshal an instance of the person class you simply call the Marshaller as follows:
// Create a new Person
Person person = new Person("Ryan 'Mad Dog' Madden");
person.setDateOfBirth(new Date(1955, 8, 15));

// Create a File to marshal to
writer = new FileWriter("test.xml");

// Marshal the person object
Marshaller.marshal(person, writer);


Follow the document of castor for details.





Read More
Posted in Castor castor convert dtd to xsd | No comments

Wednesday, August 1, 2007

LINUX usefuls

Posted on 1:16 AM by Unknown

html'&gt;linux basic commands:
ls
ls -a -- lists all files (hidden as well .)
ls -l -- list with permission and details

ln -s A B -- create soft link btw two file/folders

ps -- see current process
ps -e -- see background process as well
ps -H -- list process hierarchy
ps -f -- ?
pstree
top - see all proc's at one shot
pmap [PID] : list all the resource held by this proc.
cat /proc/[PID]/maps :

kill -3 [PID] -to get the status of threads
$ killall httpd -kill all the procs with name httpd

grep -- useful for search. Very powerful if we combine with other commands
eg: ps -ef | grep liferay == will return all the liferay process

fg -- bring the process to foreground
bg -- send the process to background
CTRL Z -- send the process to background..Can bring it to foreground using fg.
CTRL C -- close a program.

tail myfile.txt -n 100 -- list the last 100 lines in
the file

mail -s "picture of me surfing" sylvia@home.com &lt; surfing.jpeg --- To mail a file
tail -f catalina.out --display the contents in real time
head -15 myfile.txt - Would display the first
fifteen lines of myfile.txt.

diff -r -N folder1/ folder2/ ---find difference b/n folders.. -N do display diff content.


cat test.txt --display content of file test.txt

cat t.txt t2.txt &gt; t3.txt -- merge t.txt+t2.txt= t3.txt

difference b/n folder
du -hs liferay1/webapps/* liferay2/webapps/*


touch file.txt -- quickly create a empty file

VI editor commands
i -- insert mode
r -- replace mode
/ -- search
:%s/fred/joe/igc : general substitute command(replace)
w -- write
wq --write and quit
q-- quit
:#20 - moving to a line 20
Ctrl u --page up
Ctrl d -- page down
:set number -- to set the number
~ Toggle case of the character under the cursor, or all visually-selected characters.
q: You can bring up the command line history while in Normal mode.
:42G -- ways to go to a particular line (line 42 for example)
Multiple Files Management

vim test xyz


:bn -- next file

:bp -- next file

:wn -- write file and move to next (SUPER)

Screen
Ref: http://www.kuro5hin.org/story/2004/3/9/16838/14935

Screen is best described as a terminal multiplexer.
Using it, you can run any number of console-based
applications--interactive command shells,logging, curses-based
applications,
text editors, etc.--within a single terminal.Also can reattach again to
the screen even after logout.Excellent isn't it. Should have had a
separate blog :0). Any way the quick reference below:



$screen --Start screen just by typing screen at your favorite command shell prompt

Ctrl a c --create another screen

ctrl a
ctrl A --switch screen

ctrl a n -- switch next screen

ctrl a p -- switch prev screen

ctrl a A -- Give a name to the current screen.

ctrl a " -- to get a full-screen list of windows

ctrl a K --You can also kill misbehaving programs

$screen -r --will reattach the screen to the current session which.

Networking commands:

ping

netstat -- active connections
netstat -r --shows routing table


ifconfig (like ipconfig in windows)
ifconfig eht0 down -- shutdown lan card (to renew ip u can do this)
ifconfig eht0 up --startup lan card

iptraf
nmap -- port sniff
dig

NATing
/etc/hosts file
It is used to map simple human readable names with ip address.
Eg:
127.0.0.1 localhost.localdomain localhost
127.0.0.1 access.idp1.com

Installation
rpm -i foo-v123.rpm ---install a package
rpm -i http://oss.oracle.com/kernel-2.4.20-18.10.1.i686.rpm
rpm -e foo
rpm -qi foo -- To query a RPM package and display info
more details refer http://www.idevelopment.info/data/Unix/Linux/LINUX_RPMCommands.shtml

Autoexec.bat in linux
vi /root/.bashrc # the user is root here.
---Do whatever needs to be done on login in the .bashrc
To load the properties without relogging in use : source /root/.bashrc

Secured remote copy:
scp &lt;target1&gt; &lt;target2&gt;
eg: scp test.zip sandeepm@xHost:/export/home/sandeep -- copies the test.zip to the target2 from target 1.
scp sandeepm@xHost:/export/home/sandeep/test22.zip . -- copies the test22.zip from target2 to target1 .


Use grep recursively

You can search recursively i.e. read all files under each directory for a string “192.168.1.5″

cd /etc

$ grep -R "192.168.1.5" *

Use grep to search words only


When you search for boo, grep will match fooboo, boo123, etc. You
can force grep to select only those lines containing matches that form
whole words i.e. match only boo word:

$ grep -w "boo" /path/to/file


Grep invert match


You can use -v option to print inverts the match; that is, it
matches only those lines that do not contain the given word. For
example print all line that do not contain the word bar:

$ grep -v bar /path/to/file

Count line when words has been matched


grep can report the number of times that the pattern has been matched for each file using -c (count) option:

$ grep -c 'word' /path/to/file

To get the DB conn list
$ netstat|grep -c app610

Shell script
The below will run a command for configurable no of times.
chmod +x test
usage : ./test [NO_TIMES] [COMMAND]

for (( i = 0 ; i &lt; $1; i++ ))
do
echo "Executing $2";
$2;
sleep 1;
done

More scripts here http://www.usd.edu/~sweidner/lsst/



One of the best methods to capture a Unix terminal session is to use the `script` command.



In this example we start a script session, run a couple of commands,
and then use the `exit` command to stop capturing the terminal session:



$ script
Script started, output file is typescript
$ pwd
/home/will
$ ps
PID TT STAT TIME COMMAND
11909 p0 Ss 0:00.05 -bash (bash)
25622 p0 S+ 0:00.01 script
25623 p1 Ss 0:00.01 /usr/local/bin/bash -i
25624 p1 R+ 0:00.00 ps
$ exit

Ref:
http://vim.wikia.com/wiki/Best_Vim_Tips




Read More
Posted in LINUX usefuls | No comments

Thursday, July 26, 2007

SVN/ Subversion Tips and traps

Posted on 10:29 PM by Unknown

SVN could be tricky and waste a hell lot of time.

Case Issue :
Normally we run SVN server in linux. Our dev env will be in windows NT. Windows doest differentiate lower and upper case file names, while linux does. So when we try to do a SVN update, it gives wierd errors like Lock not released, while the problem is with Case.
This takes hours to sort out.


Merge branch to trunk
Often in a multi developer environment, it is required to maintain seperate branches so that the development is
not dependent on another developer. The developer takes a branch , works on his module and once done and tested,
merges it back to trunk.

Using tortoise svn, this can be achieved as follows:
1. right click on the root folder of your svn dump. Click merge .
2. Choose the revision from to for the branch (use show log to aid in choosing revision).
3. Make a diff. Do a dry run. Finally hit merge when satisfied.
4. Now the branch on ur local disk has the merged content. This can be commited to the trunk normally using commit.



More to come here.
Read More
Posted in SVN/ Subversion Tips and traps | No comments

Thursday, July 19, 2007

apache commons configurator usage

Posted on 10:52 PM by Unknown
commons configurator usage:
Download the below jars from apache site:
commons-collections-3.2.jar application/octet-stream
commons-configuration-1.4.jar application/octet-stream
commons-lang-2.3.jar application/octet-stream

Usage of org.apache.commons.configuration class for dynamic property file reading is below:


static PropertiesConfiguration config = null;
public void init(FilterConfig filterConfig) throws ServletException
{

try
{
config = new PropertiesConfiguration(filterConfig.getInitParameter("ROBOT_FILE"));
FileChangedReloadingStrategy reloadingStrategy = new FileChangedReloadingStrategy();
reloadingStrategy.setRefreshDelay(1000 * 60 * 5);// 5 mins

config.setReloadingStrategy(reloadingStrategy);
List patternsList = (List) config.getProperty("patterns");

} catch (ConfigurationException e)
{
log.error(e);
}

}


By default the char seperator is "," and the list is automatically created.
Cool isnt it.


commons digester usage:


QuizResultsTO result = null;
try
{
digester.addObjectCreate("quiz", "com.biomedcentral.business.imagelibrary.model.quiz.QuizResultsTO");
digester.addCallMethod("quiz/title", "setQuizTitle", 0);
result = (QuizResultsTO) digester.parse(file);
} catch (Exception e)
{
logger.error("Quiz configuration file not parseable", e);
throw new TechnicalException(e);
}

return result.getQuizTitle();
Read More
Posted in apache commons configurator usage | No comments

setting datasource lookup from tomcat JNDI using spring

Posted on 4:37 AM by Unknown



1. -JNDI configuration is as below:

1. Shutdown liferay/tomcat

2. Modify applicationContext-hibernate.xml as below :

Replace
- <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

<property name="jndiName" value="jdbc/dmpPubPool" />

<property name="resourceRef" value="true" />

</bean>

Instead of

- <bean id="dataSource"

class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="url"><value>${hibernate.connection.url}</value></property>

<property name="driverClassName"><value>${hibernate.connection.driver_class}</value></property>

<property name="username"><value>${hibernate.connection.username}</value></property>

<property name="password"><value>${hibernate.connection.password}</value></property>

</bean>



Modify the JNDI path jdbc/dmpPubPool suitable for CMS.



3. Add the context.xml(attached) into /META-INF/ folder of CMS webapp . Modify the JNDI path jdbc/dmpPubPool suitable for CMS.

This file has

<Context reloadable="true">

<ResourceLink name="jdbc/dmpPubPool" type="javax.sql.DataSource" global="jdbc/dmpPubPool"/>

<ResourceLink name="jdbc/adServerPool" type="javax.sql.DataSource" global="jdbc/adServerPool"/>

</Context>

4. Update the server.xml of your liferay available under <liferay>/conf as below



<GlobalNamingResources>

<Resource

name="jdbc/dmpPubPool"

auth="Container"

type="javax.sql.DataSource"

driverClassName="oracle.jdbc.driver.OracleDriver"

url="jdbc:oracle:thin:@172.20.41.40:1521:xyz"

removeAbandoned="true"

maxActive="75"

maxIdle="30"

maxWait="-1"

username="****"

password="***"

validationQuery="select 1 from dual"

/>

…..>



Copy ojdbc.jar available under cms/web-inf/lib into <LRay>\common\lib\ext

Modify the url and other settings as per your application.



5. Remove all the org.springframework.jdbc.datasource.DriverManagerDataSource and use javax.sql.DataSource;

6. Deploy CMS app and Startup liferay

7. Test if the db connection is fine.



The ant script might not copy the META-INF/context.xml file. Modify the ant script for CMS with

<target name="build" depends="compile">

<war>

…..

<!--Copy the META-inf library files -->

<zipfileset dir="${srcdir}/webapp/META-INF" prefix="META-INF/" />

….

……


Read More
Posted in spring jndi datasource lookup | No comments

Saturday, July 14, 2007

External Javascript from Java Servlets

Posted on 8:18 PM by Unknown

Copied from http://myappsecurity.blogspot.com/2007/01 Like to thank anurag for the content.
/breaking-same-origin-barrier-of.html
External Javascript from Java Servlets

One of the lesser known sides of external JavaScript is the ability to reference a server side program(CGI, PHP or Servlets) instead of the familiar .js file. It is kinda interesting since a client side script interacting with a server side program is not considered safe and is usually not allowed from within the browser but apparently a script can be dynamically generated and loaded, if referenced in src attribute of the script tag, while the html page is being loaded. Using the src attribute of the script tag, we can call an external javascript, we can also call a server side program to dynamically generate a javascript. For example

script type="text/javascript" src="myservlet"

Where "myservlet" is the server side program and could be an absolute path like “http://www.myserver.com/myservlet” or a relative path like “myservlet” instead of the usual .js file. Interestingly you can even pass parameters to the servlet through the URL string. For example

script type="text/javascript" src="http://attacker.com/myservlet?name=myname"

Now the servlet can be invoked and process parameters and return the result back. There is a limitation however. It can only return Javascript code. You also have to set the content type as “application/x-javascript”. Just think of it as returning javascript code instead of html code. But there is a workaround to this limitation. Just like while returning html, if you had Javascript code, you would encapsulate in script tag, here, if you have to return html code, you can always return document .body .innerHTML = ‘html code’ or document .write(‘html code’). So your typical servlet would look like


public class myservlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
response.setContentType(“application/x-javascript”);
PrintWriter out = response.getWriter();
String name = request.getParameter(“name”);
out.println(“document.body.innerHTML = ‘Welcome “ + name + “’;”);
out.close();
}
}


A JavaScript header is sent at the very beginning to inform the browser that it is receiving a JavaScript file. The final output of the servlet needs to be a valid Javascript file and must conform to Javascript syntax, servlet outputs a valid javascript code which replaces the content of the html page and displays “Welcome anurag”.
The other limitation, however, is that it cannot have an interactive session with the server side program. While loading the page, when the browser comes across the script tag, it goes to the URL mentioned in the src attribute and validates the incoming data as a valid javascript and executes it. The script tag is only executed once and after the entire page is loaded, it cannot call the server side program again.
Read More
Posted in External Javascript from Java Servlets | No comments

Wednesday, July 11, 2007

Image Verification Utility for Form submission(Captcha)

Posted on 2:02 AM by Unknown
Got from http://blog.jeffhaynie.us/image-verification-utility-for-form-submission.html
Thanks for the idea author.

Pasting the same below :
Image Verification Utility for Form submission
June 22nd, 2006 · No Comments

image verify screenshot Ever wanted one of those cool HTML form submission pages where you can make sure that only humans are submitting form data, and not machines (like spam bots)? Well, no you can have one. I created a simple Java utility class for generating the dynamic image in PNG format and then a simple servlet and web page for testing. You can download the source and demo here. Good luck!
Utility class

1: /**
2: * Copyright (c) 2006 by Jeff Haynie
3: *

4: * Licensed under the Apache License, Version 2.0 (the “License”);
5: * you may not use this file except in compliance with the License.
6: *
7: * You may obtain a copy of the License at
8: * http://www.apache.org/licenses/LICENSE-2.0

9: *
10: * Unless required by applicable law or agreed to in writing,
11: * software distributed under the License is distributed on an “AS IS” BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and

14: * limitations under the License.
15: */
16: package us.jeffhaynie.image;

17:
18: import java.awt.Color;
19: import java.awt.Font;

20: import java.awt.Graphics2D;
21: import java.awt.geom.AffineTransform;

22: import java.awt.image.BufferedImage;
23: import java.io.IOException;

24: import java.io.OutputStream;
25: import java.util.Random;

26: import java.util.UUID;
27:
28: import javax.imageio.ImageIO;

29:
30: /**
31: * ImageVerification is a simple utility class for
32: * creating an image verification PNG file that will
33: * allow you to make sure that only a human can read

34: * the alphanumeric values and enter them into a text
35: * field during verification.


36: *
37: * Make sure that when you can getVerificationCode

38: * you don’t encode the value in the URL or inside the
39: * HTML form - otherwise, this whole excerise is pointless
40: * (dummy!).
41: *
42: * @author Jeff Haynie

43: * @copyright Copyright (c) by Jeff Haynie. All Rights Reserved.
44: */
45: public class ImageVerification
46: {

47: private String value;
48:
49: public ImageVerification (OutputStream out) throws IOException

50: {
51: this(50,120,out);

52: }
53: public ImageVerification (int height, int width, OutputStream out) throws IOException

54: {
55: BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

56: Random rand=new Random(System.currentTimeMillis());

57: Graphics2D g = bimage.createGraphics();
58:
59: // create a random color

60: Color color = new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255));

61:
62: // the the background to the random color to fill the
63: // background and make it darker
64: g.setColor(color.darker());

65: g.fillRect(0, 0, width, height);

66:
67: // set the font
68: g.setFont(new Font(“arial”,Font.BOLD,36));

69:
70: // generate a random value
71: this.value = UUID.randomUUID().toString().replace(“-”,“”).substring(0,5);

72:
73: int w = (g.getFontMetrics()).stringWidth(value);

74: int d = (g.getFontMetrics()).getDescent();

75: int a = (g.getFontMetrics()).getMaxAscent();

76:
77: int x = 0, y =0;

78:
79: // randomly set the color and draw some straight lines through it
80: for (int i = 0; i < x="0;" y="0;" i =" 0;" x =" width/2" y =" height/2" fontat =" new" xp =" x-2;" c="0;c

109: {
110: // apply a random radian either left or right (left is half since it’s too far back)
111: int rotate = rand.nextInt(20);

112: fontAT.rotate(rand.nextBoolean() ? Math.toRadians(rotate) : -Math.toRadians(rotate/2));

113: Font fx = new Font(“arial”, Font.BOLD, 36).deriveFont(fontAT);

114: g.setFont(fx);
115: String ch = String.valueOf(value.charAt(c));

116: int ht = rand.nextInt(3);
117: // draw the string and move the y either up or down slightly

118: g.drawString(ch, xp, y + (rand.nextBoolean()?-ht:ht));

119: // move our pointer
120: xp+=g.getFontMetrics().stringWidth(ch) + 2;

121: }
122: // write out the PNG file
123: ImageIO.write(bimage, “png”, out);

124:
125: // make sure your clean up the graphics object
126: g.dispose();
127: }

128: /**
129: * return the value to check for when the user enters it in. Make sure you
130: * store this off in the session or something like a database and NOT in the
131: * form of the webpage since the whole point of this exercise is to ensure that
132: * only humans and not machines are entering the data.
133: *

134: * @return
135: */
136: public String getVerificationValue ()
137: {

138: return this.value;
139: }
140: }


Read More
Posted in | No comments

Tuesday, July 10, 2007

PMD integration -For better quality

Posted on 1:56 AM by Unknown

To run the PMD on the entire source code, I used the below task:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------





rulesets/favorites.xml
rulesets/logging-java.xml
basic










--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
One need's to add the pmd jar's( pmd-4.0rc1 ) to the class path of ant as well to run the report on the complete source.

Source forge link : pmd.sourceforge.net


Read More
Posted in | No comments

Thursday, July 5, 2007

Javascript trouble shooting tools:

Posted on 12:15 AM by Unknown

Javascript trouble shooting tools:

www.getFireBug.com à It is a powerful debugging tool for javascript. It is convenient just like eclipse debug. More details are in the website.

JSEclipse à Javascript editor plugin for eclipse . Helps in autocompletion, find the error in javascript. To use, extract the attached file, copy contents of plugins folder into ..\eclipse\plugins and features into ..\eclipse\features . Restart eclipse.

Simple usage details :

Right click on the JSP code enclosing the tag.

Note that this plugin marks the error in red. But it doesn’t show the actual cause of error(a limitation).

More details http://www.interaktonline.com/Products/Eclipse/JSEclipse/Overview/

Read More
Posted in Javascript trouble shooting tool | No comments

Tuesday, July 3, 2007

Banging with cruiseControl

Posted on 6:31 AM by Unknown
Cruise control,

I’ve done a cruise control setup . Subversion and cruisecontrol are integrated. My cruise control picks up the repository files from the subversion and builds the war file automatically for every 10(configurable) mins. Please follow the same steps. Use the binary mode file rather than using exe installation.

1) download cruisecontrol-bin-2.6.2.zip from http://sourceforge.net/project/showfiles.php?group_id=23523&package_id=16338&release_id=502915

2) set CVS_RSH=http://test.com/repos/Tree/TESTCMS – at cruisecontrol.bat

3) modify the project name in config.xml as TESTCMS

4) create TESTCMS header folder cruisecontrol-bin/projects/TESTCMS

5) Map the TESTCMS header with repository.(it will pull automatically all other files during ant build)

6) Set the interval in the config.xml

7) place the build.xml under TESTCMS

8) run the cruisecontrol-bin-2.6.2 >> cruisecontrol.bat

I am using the same build script where you are using for CMS. But I’ve modified only root directory as TESTCMS from cms
In addition to these, need to add the below in config.xml under tag:




Install the SVN.exe if not installed.
Change the project name in config.xml tag.
Create a folder with the project name in projects folder of CC

Deploy the webapp of CC in tomcat and control the Cruise.

A sample config is below:

<cruisecontrol>
<project name="TESTCMS">


<!-- Load environment variables -->
<property environment="env" toupper="true"/>

<!-- Commonly used directories -->
<property name="reportdir" value="${env.CCDIR}/report"/>

<!-- Defaults for email -->
<property name="buildmaster.email" value="test@test.com"/>
<property name="buildmaster.name" value="Buildmaster"/>

<listeners>
<currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
</listeners>

<bootstrappers>
<svnbootstrapper localWorkingCopy="projects/${project.name}" />
</bootstrappers>

<modificationset quietperiod="30">
<svn localWorkingCopy="projects/${project.name}"/>
</modificationset>

<schedule interval="7200">
<ant anthome="apache-ant-1.6.5" buildfile="projects/${project.name}/build.xml"/>
</schedule>

<log>
<merge dir="projects/${project.name}/target/test-results"/>
</log>

<publishers>
<onsuccess>
<artifactspublisher dest="artifacts/${project.name}" file="D:\TESTRelease\sandeep\cruisecontrol-bin-2.6.2\projects\TESTCMS\pmd_report.html"/>
<artifactspublisher dest="artifacts/${project.name}" file="D:\TESTRelease\sandeep\cruisecontrol-bin-2.6.2\projects\cms\build\war\TESTCMS.war"/>


</onsuccess>
<htmlemail>
<always address="test@test.com"/>

<!-- <failure address="tommy@test.com"/> -->
</htmlemail>
</publishers>

<plugin name="svn" classname="net.sourceforge.cruisecontrol.sourcecontrols.SVN"/>
<plugin name="svnbootstrapper" classname="net.sourceforge.cruisecontrol.bootstrappers.SVNBootstrapper"/>

<plugin name="htmlemail"
buildresultsurl="http://172.16.152.126:7070/cruisecontrol/buildresults/${project.name}"
mailhost="IP adress of mail host"
returnaddress="${buildmaster.email}"
returnname="${buildmaster.name}"
subjectprefix="[BUILD ${project.name}]"
/>

</project>
</cruisecontrol>

Tips and traps:
cruisecontrol-bin-2.6.2. integrating with SVN may be tricky.
You need to install SVN client first. Note that the plugin provided by cruise control for
SVN just calls the SVN.exe file using exec call.
Initially the SVN checkout wont work. This is deu to a bug in the SVN plugin by cruise control. The bug is something related to characters in cmd parameter.
Work around is to do a manual checkout using svn.exe co <path> . Then onwards the cruise control rocks.

Another thing to note is to put the below in cruisecontrol.bat
set CVS_RSH=<path to SVN>

There seems to be a bug in this bat file also.Like single quote not compatible with XP..Be aware

One can integrate PMD with SVN just by adding the build task in build.xml. The artifact can be pointed by specifyin the destination


Read More
Posted in cruisecontrol cruise control | No comments

Wednesday, June 6, 2007

Welcome to the J2EE Jungle

Posted on 9:43 PM by Unknown
Yes! It's a jungle out there... Piles and piles of stuff converging into newer and better species ..New creatures are evolving by merging together leaving out lot of people confused as to where to go what to use..
They end up searching through this jungle for better and sophisticated creature(s) which can do their job. First they need to tame it and then deploy it for their tasks.
Well the problem is by the time they almost tame it, there is a better one. These beasts become better and better day by day... And you end up searching and searching .......googling all the time........
Species in the J2EE jungle are broadly classified as
-Webby - Very beautiful ...eye candy + servers who serve them.
-Business providers ---Mostly similar to donkeys.Work hard! Well they have little brains so we gotta tweak them with logica.
-Model - These creatures take care of storing food stuff... :) They collect fruits and store it for use. Like a Bee colony. Very neatly managed.. These food are used by all other creatures classified above in one form or the other. :D

Well you pick up the best working beasts from the above classification, store food and serve them.

There are areas in the jungle which have evolved in such a way that they integrate all the above classified ones into a lovely place where work gets done easier and better.
They have evolved and have become a seperate Klan - ....LifeRay...



T
Read More
Posted in liferay kids version | No comments
Newer Posts Home
Subscribe to: Comments (Atom)

Popular Posts

  • LinuxPerformance Tuning(apache,tomcat,linux) and related
    Web profiling -- HTTPAnalyzer -- -- YSlow --CSS,Javascript report , time/size measurement for individual component is good. -- F...
  • (no title)
    Hardware/Software stack:  iPhone 3Gs having iOS 5.1.1(latest as of today).  The Xcdode 4.2 failed to detect this iphone as it has support on...
  • Spring interceptor ordering
    SimpleUrlHandlerMapping uses a hashMap to hold the interceptors. Ordering can only be guaranteed by setting  order property.. By default it ...
  • SVN/ Subversion Tips and traps
    SVN could be tricky and waste a hell lot of time. Case Issue : Normally we run SVN server in linux. Our dev env will be in windows NT. Windo...
  • Liferay CMS/ web content management/ workflow/ staging
    Liferay out of the box has a web content management system. The web pages can mostly have these web content (articles) as web pages. The web...
  • Cobertura- junit coverage tool
    First, you need to add a task definition to the build.xml file. This top-level taskdef element specifies that the cobertura.jar file is i...
  • XSLT caching Transformers
     The usage of cached transformer objects is recommended here A sample implementation of CachingTransformerFactory is here The above code abs...
  • Rewrite rules in apache and IIS
    Well we can control how the server serves stuff to clients by defining rewrite rules. As servers are dumb, its important to explain well abo...
  • Real-Time Tracking and Tuning for Busy Tomcat Servers
    A very nice article which details on possible options for tomcat server monitoring to tweak its performance. http://www.devx.com/Java/Articl...
  • External Javascript from Java Servlets
    Copied from http://myappsecurity.blogspot.com/2007/01 Like to thank anurag for the content. /breaking-same-origin-barrier-of.html External ...

Categories

  • AJAX javascript
  • All about UK Visa HSMP VS H1
  • All about UK Visa HSMP VS H1 hsmp assistance
  • amazon
  • android apps ship control radio hindi
  • Apache 2.x setup Quick guide for Linux
  • apache commons configurator usage
  • apache commons usage
  • arsenals for developers
  • article
  • Batch script to load developer environment
  • Blind folded chess
  • Castor castor convert dtd to xsd
  • cloud comparision price
  • cloud comparison blog
  • cloud computing monthly price
  • cloud usage
  • Cobertura- junit coverage tool
  • Code generators
  • cron jobs expressions
  • cruisecontrol cruise control
  • debugging eclipse tips
  • developer tools
  • document library
  • easy mock jmock vs mocking java tdd
  • External Javascript from Java Servlets
  • fedora 9 lenovo 3000 n200 windows xp dual boot problem
  • Fire fox plugins and tweaks
  • Free PHP hosting
  • gods debris the religion war scott adams dilbert
  • google app engine
  • gwt javascript
  • hibernate second level cache
  • i18n locale localization internationalization spring liferay portlet locale
  • ibatis sybase mapping
  • image gallery
  • iphone apps bri8 apple
  • iphone shsh 3gs ipsw downgrade ifaith tinyumbrella ios5.1.1 to ios5.0
  • java
  • java JDBC
  • javascript junit testing
  • Javascript trouble shooting tool
  • Jboss overview
  • jmeter load testing custom java sampler javasamplerclient xml test
  • JNDI test JSP page
  • Joomla CMS
  • JProfiler setup jprofiler on linux
  • jquery IE AJAX issues
  • jquery spring AJAX
  • keyboard music java typing soothing notes auto suggest
  • liferay kids version
  • liferay web 2.0 java/j2ee
  • linux - the difference between hard and soft links
  • linux mysql
  • linux mysql setup quick start
  • Linux ssh autologin with putty
  • LINUX usefuls
  • linux)
  • LinuxPerformance Tuning(apache
  • log4j setup useful
  • lucene solr
  • mac m701 android skype not working crash
  • maven
  • maven cut reduce build time
  • microsoft ODBC oracle dll connection issues
  • Mobile Ad Services (adwhirl)
  • opsourcecloud
  • oracle connect by hierarchy
  • oracle table previlege
  • Oracle thin vs OCI(type II/thick) drivers
  • pdf 2 text
  • Pega PRPC
  • php
  • rackspacecloud
  • Rewrite rules in apache and IIS
  • scaffold
  • setting up a static ip on SKY broadband
  • setup quick start
  • Single Sign on - OpenSSO with Liferay
  • smart gwt
  • smtp email test mock server james
  • SMTP MAIL telnet windows
  • Software tools mind map freemind j2ee tools
  • Speed typing tips.
  • Spring + Hibernate Usefuls BaseDAOHibernate
  • Spring annotations with spring-mock not working 2.0 2.5.6
  • spring jndi datasource lookup
  • Spring portlet mvc and spring servlet mvc validation
  • Spyware trojan and virus removal tools
  • struts magic
  • SVN/ Subversion Tips and traps
  • tabbed ms dos console cygwin console
  • Texter - An auto text expander autotyper
  • Textpad tricks
  • The art of debugging
  • tomcat
  • Tomcat Exploded war - cut deployment time
  • Tomcat on linux tips
  • Tomcat on linux tips commands
  • TypeIt4Me
  • Typinator
  • Useful Eclipse Plugins
  • Useful Eclipse Plugins eclipse shortcuts keys
  • Useful tools
  • web content
  • xcode cocos2d iphone box2d
  • xpath xml xquery

Blog Archive

  • ►  2013 (19)
    • ►  August (17)
    • ►  July (1)
    • ►  January (1)
  • ►  2012 (7)
    • ►  August (1)
    • ►  June (4)
    • ►  April (2)
  • ►  2011 (20)
    • ►  November (1)
    • ►  October (1)
    • ►  August (1)
    • ►  July (3)
    • ►  June (1)
    • ►  April (2)
    • ►  March (4)
    • ►  February (1)
    • ►  January (6)
  • ►  2010 (27)
    • ►  December (3)
    • ►  July (2)
    • ►  May (3)
    • ►  April (2)
    • ►  March (5)
    • ►  February (10)
    • ►  January (2)
  • ►  2009 (32)
    • ►  December (5)
    • ►  November (2)
    • ►  September (3)
    • ►  August (6)
    • ►  June (4)
    • ►  May (4)
    • ►  April (3)
    • ►  March (2)
    • ►  February (3)
  • ►  2008 (28)
    • ►  December (1)
    • ►  October (2)
    • ►  September (2)
    • ►  August (4)
    • ►  July (7)
    • ►  June (1)
    • ►  April (2)
    • ►  March (2)
    • ►  February (2)
    • ►  January (5)
  • ▼  2007 (24)
    • ▼  December (3)
      • Hibernate second level cache
      • All about UK Visa.
      • LinuxPerformance Tuning(apache,tomcat,linux) and r...
    • ►  November (2)
      • Spring + Hibernate Usefuls
      • Single Sign on - OpenSSO
    • ►  October (6)
      • The art of debugging
      • JNDI test JSP page
      • Useful Eclipse Plugins + shortcut keys
      • linux tips
      • JProfiler - A J2ee profiling tool
      • Apache 2.x setup Quick guide for Linux
    • ►  September (1)
      • Chess
    • ►  August (3)
      • Spring portlet mvc and spring servlet mvc validation
      • Castor --The XML Marshaller
      • LINUX usefuls
    • ►  July (8)
      • SVN/ Subversion Tips and traps
      • apache commons configurator usage
      • setting datasource lookup from tomcat JNDI using s...
      • External Javascript from Java Servlets
      • Image Verification Utility for Form submission(Cap...
      • PMD integration -For better quality
      • Javascript trouble shooting tools:
      • Banging with cruiseControl
    • ►  June (1)
      • Welcome to the J2EE Jungle
Powered by Blogger.

About Me

Unknown
View my complete profile