Friday, August 31, 2012

Debug remote application with Eclipse

When you have remote application with enabled debug it is easy to connect Eclipse IDE and debug the application. Here is the list of steps for it:
  1. Open menu Run, select item Debug Configurations.
  2. In the left area of the appeared window double click on Remote Java Application
  3. Enter all required information about your server. In the screenshot below you can see configurations for the server configured here
  4. Click Apply or Debug

JBoss remote debugging

As all you well know debugging is very important part of the development process. In this post I will show you how to configure your JBoss AS to allow debugging deployed applications.

We need to configure JBoss's bin/run.conf file. Add the following line at the end:
JAVA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n $JAVA_OPTS"

This options mean:
  • -Xdebug asks JBoss to work with debugging support
  • -Xrunjdwp loads JDWP (Java Debug Wire Protocol). This option has its own options:
    1. transport=dt_socket means that sockets will be used for transport
    2. address=8787 means the address(in this case it's the local machine's port 8787) where the socket will be opened
    3. server=y if it is set to 'y' then it means that JBoss will listen for debugger to attach; if it is set to 'n' then it means that JBoss will attach to the debugger at the specified address
    4. suspend=n if it is set to 'y' then it means that JBoss will be launched in the suspended mode and will stay suspended until the debugger is connected

You may also want to check how to debug remote application with Eclipse

Wednesday, August 29, 2012

LDAP Authentication and Search

LDAP is a very widespread way for authentication. In this post I would like to show you how to connect to LDAP server, authenticate user and perform search.

We will use only standard Java classes. So we don't need any dependency. In the example you can see my configurations. Yours may differ (pay attention to Context.SECURITY_PRINCIPAL). Here is the code:
import java.util.Properties;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;

public class LdapTest {
    
    public static void processRequest(InitialLdapContext ctx, String userContext, String filter, String attribute) {
        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

        NamingEnumeration<SearchResult> searchResults;
        try {
            searchResults = ctx.search(userContext, filter, searchControls);
            
            while (searchResults.hasMoreElements()) {
                SearchResult sr = searchResults.next();
                Attributes attributes = sr.getAttributes();
                Attribute a = attributes.get(attribute);
                if (a != null) {
                    String attrValue = (a.get().toString());
                    System.out.println(attrValue);
                } else {
                    System.out.println("Cannot get data");
                }
            }
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
        
    private static InitialLdapContext initialiaseLdapContext(String server, int port, String username, String password, String contextDN) {
        boolean initialised = false; 
        Properties properties = new Properties();
        properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        properties.put(Context.PROVIDER_URL, "ldap://" + server + ":"+ port);
        properties.put(Context.SECURITY_AUTHENTICATION, "simple");
        properties.put(Context.SECURITY_PRINCIPAL, "uid=" + username + "," + contextDN); //YOU MAY NEED TO CHANGE CODE HERE
        properties.put(Context.SECURITY_CREDENTIALS, password);

        InitialLdapContext ctx = null;
        try {
            // Create initial context
            ctx = new InitialLdapContext(properties, null);
            initialised = true;
        } catch (NamingException e) {
            initialised = false;
        } finally {
            if (initialised) {
                System.out.println("Initialization success");
            } else {
                System.out.println("Initialization fail");
            }
        }
        return ctx;
    }

    public static void main(String[] args) {
        String contextDN = "dc=test,dc=com";
        InitialLdapContext ctx = initialiaseLdapContext("localhost", 389, "test@test.com", "test" , contextDN);
        try {
            if (ctx != null) {
                processRequest(ctx, contextDN, "(uid=qwertTest@test.com)", "street");
                ctx.close();
            }
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
}

Fast bulk loading to the database

Whenever you have to insert a big amount of data consider using not usual 'Insert Into', but the load command. For MySQL and Oracle it's 'Load Data Infile'. Here is the small example how to import usual CSV file with the header to MySQL:

load data local infile 'load.csv'
into table someTable
character set utf8 
fields terminated by ',' 
optionally enclosed by '"'
lines terminated by '\n'
ignore 1 lines

For more information view official documentation

Fast way to kill many MySQL processes

I think everyone who works for some time with MySQL has been in trouble with suspended processes or reaching the limit of connections. The fastest way to fix it is to restart MySQL service
service mysql restart

But if it's the production server and you cannot afford restarting the service then here is the tip for you.

At first we need to find out what processes are causing troubles. Let's login to MySQL:
mysql -uroot -ptoor

And watch the list of all processes
select * from information_schema.processlist;

or
show processlist;

Let's assume we need to delete processes that are active more then 1000 seconds. To watch them we need this query:
select * from information_schema.processlist where TIME > 1000;

Let's format the output and save it to the file (if you have problems saving to the file then check this post)
select concat('kill ',id,';') 
into outfile '/home/anton/mysql/kill.sql' 
from information_schema.processlist 
where TIME > 1000;

After this let's load the created file
source /home/anton/mysql/kill.sql;

Thus we have deleted multiple MySQL processes with our own criteria.