Showing posts with label Technical. Show all posts
Showing posts with label Technical. Show all posts

Friday, 22 April 2016

Tech Talk... Reverse UML generator in eclipse - ObjectAid

A reverse UML generator can be used to generate UML diagram from source code. Here, I am going to talk about a reverse UML generator that comes as a eclipse add on and that can be used to generate UML diagram from java code. ObjectAid is one such addon available for eclipse.
Here we see step by step how to add ObjectAid to eclipse and then use it to generate a UML diagram:

Step1: Install ObjectAid in eclipse:
  • Open Eclipse and go to Help > Install New Software
  • Click on add to add a new repository
  • Enter name ObjectAid UML Explorer
  • Enter Location http://www.objectaid.net/update

Step2: Select the objectaid class diagram plugin as it is free, and click 'next' . Sequence diagram one needs a license, so, you can skip it for now.



Step3: Click 'finish'. The installation should start now. Click 'ok' on the security warning that appears.

Step4: Once the installation finishes, eclipse would ask for a restart. Click ok and let eclipse restart.

Now, we are done with the ObjectAid installation and we are ready to create a class diagram.
Step5 : Create a folder anywhere to store the class diagrams.

Step6: To create a new ObjectAid UML diagram, launch the ObjectAid wizard by going to File->new->other.


Type Class Diagram  in the top textbox to filter this wizard out. Once you see the right wizard, select it and click 'next'.


Step7: A visual UML editor would appear in your eclipse. You can start dragging and dropping your classes or java files on to this editor. It will automatically start putting in the class diagrams, the relations between classes, methods etc.



Step8 : Once you are done, you can choose to save it as an image. for this, all you have to do is right click on the diagram and choose save as image followed by the specific image type you want to save it as (.jpeg or .gif etc.)



Friday, 19 February 2016

Tech Talk...Apache 403 forbidden error

I have worked with apache a lot during my career and I am never able to remember all the configurations required there for various apache behavior tuning at different levels but one thing that has surely helped me in solving the 403 errors time and again, particularly with the home page loading after the first time apache is configured on the fresh environment is this:

<Directory />
    Order allow,deny
    Allow from all
    Require all granted
</Directory>


Make sure the right permissions are provided at the root directory level and you should be good to go.
(With the assumption that you can safely allow all the incoming requests to pass through). Hereafter you can do VirtualHost specific configurations for allowing or denying certain requests as per your project requirement.

Sunday, 2 August 2015

Tech Talk... Java fork/join pool

What is Java fork/join pool?
There are situations when there are multiple processors that an application can leverage on to increase its computational efficiency. How the application can do this, is generally, by breaking a big chunk of work that it might be serially doing, into subtasks which can then be divided among the different processors available, which can do the processing in parallel. The java fork/join pool provides a framework to achieve exactly the same. It wraps the complexity of thread creation, pool management and getting the work done in parallel, leaving to the user the only responsibility of his core computation logic and splitting the work when desired.
How to use Java fork/pool?
Simple, need to extend a ForkJoinTask (or its subclass RecursiveAction) and then assign it to a ForkJoinPool which will get it executed. The pool executes the task and on completion, returns back the control to the invoker thread.
The Fork/Join concept it recursion based, so, the ForkJoinTask invokes its instances recursively until the work is broken into the desired level of chunks and then is executed. The invocation through invokeAll method insures that all the tasks will be completed in parallel and then the control will be returned back to the caller, so, it would appear to the caller as if the tasks were done in a blocking fashion.
Sample program
Below is a sample program that shows the use of fork/join. The execution that the program needs to do is simple - print elements of an array list, along with the name of thread that is printing it. But, the elements need not be printed in order, whenever the size of the array list is greater than a threshold, subparts of this array list are recursively handed over to further instances of the ForkJoinTask which get it executed in parallel. The parallel execution can be observed by running the task multiple times and seeing that the sub-array-lists are executed in alternate orders at time and the order keeps changing every time the program is executed.
So, below are the steps for writing a program to use the fork/join framework:
Step1: Subclass the ForkJoinTask class and have your implementation inside it:
public class ForkJoinExample extends RecursiveAction {
       //An array list that would hold the numbers to be printed
private ArrayList<Integer> events;
       //if the number of elements in the array list is > this threshold, divide the task
private int computationThreshold;
       //name of the class, when printed, can help identify how the parallel execution is happening
private String name;
       //counter for appending to the name of the class
private static int count=0;

public ForkJoinExample(ArrayList<Integer> events, int computationThreshold,
String name) {
this.events = events;
this.computationThreshold = computationThreshold;
this.name = name;
}

//this method is supposed to be invoked for direct computation once the work has been broken down to the desired extent
private void computeDirect(){
for(int i=0;i<events.size();i++){
System.out.println("Printing from :" + name + ":  " +events.get(i));
}
}

//this is the method that would be invoked by the ForkJoinPool
//Inside this method, the work can be further subdivided recursively
@Override
protected void compute() {
//if the threshold value is not reached, direct computing can be done
if(events.size() <= computationThreshold){
computeDirect();
return;
}else{
//break the task among threads and let each one do the computation of its own
int split = events.size()/2;
ArrayList<Integer>firstHalf = new ArrayList<Integer>();
ArrayList<Integer>secondHalf = new ArrayList<Integer>();
for(int i : events){
if(i>split){
secondHalf.add(i);
}else{
firstHalf.add(i);
}
}
invokeAll(new ForkJoinExample(firstHalf, computationThreshold, this.name+(++count)),
new ForkJoinExample(secondHalf, computationThreshold, this.name+(++count)));
}
}
}
Step 2: Create a ForkJoinPool and let it invoke the ForkJoinTask:
ForkJoinExample forkJoinExample = new ForkJoinExample(
new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8)), 4, "Thread");
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(forkJoinExample);

Sample outputs on running this program:

Output Sample 1:
Printing from :Thread1:  1
Printing from :Thread1:  2
Printing from :Thread1:  3
Printing from :Thread1:  4
Printing from :Thread2:  5
Printing from :Thread2:  6
Printing from :Thread2:  7
Printing from :Thread2:  8

Output Sample 2:
Printing from :Thread1:  1
Printing from :Thread2:  5

Printing from :Thread1:  2
Printing from :Thread2:  6
Printing from :Thread1:  3
Printing from :Thread2:  7
Printing from :Thread1:  4
Printing from :Thread2:  8

Thursday, 30 April 2015

Tech talk... hashcode and equals method overriding in java

I always used to messup the concept that which one must be overridden if the other one is overridden.

Should we override equals() if we are overriding hashcode():
we can, but even if we don't it will not have side effects

Should we override hashcode() if we intend to override equals():
yes we should, otherwise it might lead to side effects.

How?
hashcode() method generates a unique integer for each object. No matter what the fields value of the object, this integer is always the same for the object. And equals() uses hashcode by default to compare if two objects are equal or not.

Suppose now I override equals() to say two person objects are equal for me if their "name" are same.
But I don't override the hashcode(). I have all person objects stored in a HashMap against their address.

I say the following:

Person john = new person("john");
mymap.put(john, addrOfJohn);


Now, i want to retrieve the address of john. Since my equals() method is overridden,I assume if i create a object again with name "john" and use it to retrieve the address of john, that should work.

So i say:

mymap.get(new Person("john");

what do i get? null !!
why?
because storage of keys in hashmap is based on their hashcode and the above two Person objects that i created, had the same name but different hash value as i had not overridden the hashcode method.
so, while the address is stored against a key that hashes to a different bucket, after creating a new person, I might be looking at it in a different bucket. this leads to an undesirable effect.

That is why when equals() is overridden, hascode() should as well be overridden.

Tech Talk... How hash map works in java

This is a very common question asked by interviewers for java.
Rather than explaining it here, I would like to compile some links that helped me immensely in understanding the internal working of hash map:

This one provides a very elaborate theoratical insite into how things work internally with hash map
http://javahungry.blogspot.com/2013/08/hashing-how-hash-map-works-in-java-or.html


This one explains the same, but rather centering the explanation around a practical example:
http://www.javacodegeeks.com/2014/03/how-hashmap-works-in-java.html

I liked both the approaches and benifitted from both these links...hoping the same will help the readers coming to this website as well.

Wednesday, 26 November 2014

Https client and server

Post the cryptograhy session (generation of asymmetric keys), I had to use my keys to communicate between a simple https client and its corresponding server. Here's how they look like:

A simple https server:

public class MyHttpsServer {
int httpsPort = 443;
String httpsPath = "/certificate";
final EventLoopGroup parentGroup = new NioEventLoopGroup();
final EventLoopGroup childGroup = new NioEventLoopGroup();
protected final LinkedBlockingQueue<ByteBuf> incomingMsgQueue = new LinkedBlockingQueue<>();
private Channel channel;

public static void main(String[] args) throws InterruptedException {
MyHttpsServer mhs = new MyHttpsServer();
mhs.createASimpleHttpsServer();
}

public void createASimpleHttpsServer(){
try {
// setup the socket address
InetSocketAddress address = new InetSocketAddress(
InetAddress.getLocalHost(), 443);

// initialise the HTTPS server
HttpServer httpsServer = HttpsServer.create(address, 0);
SSLContext sslContext = SSLContext.getInstance("SSL");

// initialise the keystore
char[] password = "dummypassword".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("keysdir/my_keystore.jks");
ks.load(fis, password);

// setup the key manager factory
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password);

// setup the trust manager factory
TrustManagerFactory tmf = TrustManagerFactory
.getInstance("SunX509");
tmf.init(ks);

// setup the HTTPS context and parameters
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
((HttpsServer) httpsServer).setHttpsConfigurator(new HttpsConfigurator(sslContext) {
public void configure(HttpsParameters params) {
try {
// initialise the SSL context
SSLContext c = SSLContext.getDefault();
SSLEngine engine = c.createSSLEngine();
params.setNeedClientAuth(false);
params.setCipherSuites(engine.getEnabledCipherSuites());
params.setProtocols(engine.getEnabledProtocols());
} catch (Exception ex) {
ex.printStackTrace();
}
}
});


httpsServer.start();
MyHttpsHandler myHttpsHandler = new MyHttpsHandler();
httpsServer.createContext(httpsPath, myHttpsHandler);
httpsServer.createContext("/key", myHttpsHandler);


System.out.println("https server is listening on " + httpsServer.getAddress());
} catch (Exception ex) {
ex.printStackTrace();
}
      }
}


Https handler (helper class):

public class MyHttpsHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) throws IOException {
try {
if (exchange.getRequestMethod().equals("GET")) {
System.out.println("Processing the incoming GET request...." + exchange.getRequestURI().getPath());
byte[] response;
try {
response = getResponse();
exchange.sendResponseHeaders(200, response.length);
exchange.getResponseBody().write(response);
exchange.getResponseBody().close();

} catch (KeyStoreException | NoSuchAlgorithmException
| CertificateException e) {
e.printStackTrace();
} catch (UnrecoverableEntryException e) {
e.printStackTrace();
}
System.out.println("Sent response sucessfully");
} else {
System.out.println("Requested http method not supported");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

private byte[] getResponse() throws FileNotFoundException, IOException,
KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableEntryException {
File privateKeyFile = new File("keysdir/my_keystore.jks");
FileInputStream fIn = new FileInputStream(privateKeyFile);
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(fIn, "dummypassword".toCharArray());
System.out.println("Successfully loaded the keystore");

Enumeration<String> aliases;
aliases = keyStore.aliases();
String alias = aliases.nextElement();
KeyStore.PrivateKeyEntry keyEnt = (KeyStore.PrivateKeyEntry) keyStore
.getEntry(
alias,
new KeyStore.PasswordProtection("dummypassword"
.toCharArray()));
PrivateKey privateKey = keyEnt.getPrivateKey();
byte[] response = privateKey.getEncoded();
return new Base64().encode(response);
}
}

Tuesday, 1 July 2014

Tech talk...Cryptography or Encryption [Using keys]

Previous post covered how to generate keys and keystores.
This post shows how to load the private key from keystore, public key from truststore and then use them for data decryption/encryption respectively:

Load keystore: (keystorePass = password of the keystore)

KeyStore keyStore= KeyStore.getInstance("JKS");
FileInputStream fin1 = new FileInputStream("D:\\MySecurityKeys\MyKeyStore.jks");
keyStore.load(fin1, keystorePass.toCharArray());

Load the truststore: (truststorePass = password of the truststore)

KeyStore trustStore= KeyStore.getInstance("JKS");
FileInputStream fin2= new FileInputStream("D:\\MySecurityKeys\MyTrustStore.jks");
trustStore.load(fin2, truststorePass.toCharArray());

Load private key from the keystore:

Enumeration<String> aliases = keyStore.aliases();
String alias = aliases.nextElement();
KeyStore.PrivateKeyEntry keyEnt = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,
                    new KeyStore.PasswordProtection(keystorePass.toCharArray()));
PrivateKey privateKey = keyEnt.getPrivateKey();

Load public key from the truststore:

aliases = trustStore.aliases();
alias = aliases.nextElement();
KeyStore.TrustedCertificateEntry keyEnt = (KeyStore.TrustedCertificateEntry) trustStore.getEntry(alias, null);
PublicKey publicKey = keyEnt.getTrustedCertificate().getPublicKey();

Initializing ciphers:

//the public and private keys use encryption and decryption ciphers respectively for encrypting //and decrypting the data. So, first, the ciphers need to be initiatized:
//Initializing the encryption cipher:
Cipher encryptionCipher = Cipher.getInstance("RSA");
                        encryptionCipher.init(Cipher.ENCRYPT_MODE, publicKey);/Initializing the decryption cipher:
Cipher  decryptionCipher = Cipher.getInstance("RSA");
                        decryptionCipher.init(Cipher.ENCRYPT_MODE, privateKey);

Encryption of data:


    public byte[] encryptData(byte[] input)                throws IllegalBlockSizeException,BadPaddingException   {
        byte[] encryptedData = null;
        encryptedData = encryptionCipher.doFinal(input);
        return new Base64().encode(encryptedData);
    }

Decryption of data:


    public byte[] decryptData(byte[] inputData) throws IllegalBlockSizeException , BadPaddingException {
        byte[] decryptedData = null;
        byte[] inputBytes = new Base64().decode(inputData);
        decryptedData = decryptionCipher.doFinal(inputBytes);
        return decryptedData;
    }

Note:The Base64 encoding decoding is done to preserve the context of data when data is converted from byte to string and string to byte and encryption/decryption is done over the data. For example, if a String "Hello" were to be encrypted using the above method, the caller would say String encryptedData = new String( encryptData("Hello".getBytes()) and when decrypting back the data, he would say String decrytedData = new String(decryptData(encryptedData.getBytes()). Here, encryptedData and decryptedData are two new Strings, the final value expected on decrypting the data is "Hello". This might not be the case if proper encoding is not used. So, to preserve the value of actual data through this process, a base 64 encoding has been used here along with the encryption.

Tech talk...Cryptography or Encryption [Generating keys]

The following code snippets in java show how to generate a private and public key pair for asymmetric cryptography and how to add them to the keystore and truststore respectively:

An enum to help differentiate public and private keys:

public enum KEY_TYPE {
PUBLIC, PRIVATE
}


 Code snippet to generate the public and private keys:


  KeyPairGenerator keyPairGenerator = KeyPairGenerator
.getInstance("RSA");
  KeyPair keyPair = keyPairGenerator.generateKeyPair();
  KeyManager keyGenerator = new KeyManager();

  // generate a public-private key pair
  PublicKey publicKey = (PublicKey) keyGenerator.generateAndStoreKey(
"MyPublicKey", KEY_TYPE.PUBLIC, keyPair);
  PrivateKey privateKey = (PrivateKey) keyGenerator.generateAndStoreKey(
"MyPrivateKey", KEY_TYPE.PRIVATE, keyPair);


Storing the keys into files:

function generateAndStoreKey:
This function would store the keys into files:

private Key generateAndStoreKey(String keyName, KEY_TYPE keyType,
KeyPair keyPair) throws IOException {
Key key = null;
switch (keyType) {
case PUBLIC:
key = keyPair.getPublic();
break;
case PRIVATE:
key = keyPair.getPrivate();
break;
}
byte[] keyBytes = key.getEncoded();
File keyFile = new File("D:\\MySecurityKeys\" + keyName);
FileOutputStream fos = new FileOutputStream(keyFile);
fos.write(keyBytes);
fos.flush();
fos.close();

return key;
}


Adding private key to keystore:

A private key, once generated, can be added to the keystore. For this, first the keystore needs to be loaded into memory. Below is the code snippet for loading a keystore file, given its location:


FileInputStream fIn = new FileInputStream("D:\\MySecurityKeys\MyKeyStore.jks");
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(fIn, KEYSTORE_PASSWORD.toCharArray());

Once the keystore is loaded, the private key can be added into it as follows:


//Convert the private key to byte array, if the key is stored in the form of file, then 
//read the file and convert it to byte array (as is the case from our private key generation code //above). If it is available in any other format, like a string, then also, the string should be //converted to byte array.
File privateKeyFile = new File("D:\\MySecurityKeys\MyPrivtekey");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
privateKeyFile));
byte[] privKeyBytes = new byte[(int) privateKeyFile.length()];
bis.read(privKeyBytes);
bis.close();

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory
.generatePrivate(new PKCS8EncodedKeySpec(privKeyBytes));

                //generate a certificate chain out of the private key  
File certFile = new File("D:\\MySecurityKeys\MyCertificateFile");
FileInputStream fin = new FileInputStream(certFile);
CertificateFactory factory = CertificateFactory.getInstance(CERTIFICATE_TYPE);
Certificate generateCertificate = factory.generateCertificate(fin);
Certificate[] chain = new Certificate[1];
chain[0] = generateCertificate;
                
                //add the entry to the keystore
keyStore.setKeyEntry("MyPrivateKey", privateKey,
PRIVATE_KEY_PASSWORD.toCharArray(), chain);
                //store the new keystore to the file system
keyStore.store(new FileOutputStream(new File("D:\\MySecurityKeys\MyKeyStore.jks")), KEYSTORE_PASSWORD.toCharArray());
System.out.println("Added private key to keystore");
}

Adding public key to truststore:

A public key can be added to the truststore as follows:
A public key needs to be embedded inside a certificate to be stored in truststore. Following code snippet shows how to do it:

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

X509Certificate[] serverChain = new X509Certificate[1];
X509V3CertificateGenerator serverCertGen = new X509V3CertificateGenerator();
X500Principal serverSubjectName = new X500Principal("CN=neha verma");
                String RANDOM = "123456789";
serverCertGen.setSerialNumber(new BigInteger(RANDOM));

serverCertGen.setIssuerDN(serverSubjectName);
serverCertGen.setNotBefore(new Date());
serverCertGen.setNotAfter(new Date());
serverCertGen.setSubjectDN(serverSubjectName);
serverCertGen.setPublicKey(publicKey);
                String CERTIFICATE_SIGNATURE_ALGO = "MD5WithRSA";
serverCertGen.setSignatureAlgorithm(CERTIFICATE_SIGNATURE_ALGO);
serverCertGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
new SubjectKeyIdentifierStructure(publicKey));
serverChain[0] = serverCertGen
.generateX509Certificate(privateKey, "BC"); // note: private key
// of CA
byte[] encodedCert = serverChain[0].getEncoded();
File certFile = new File("D:\\MySecurityKeys\MyCertificate.cert");
FileOutputStream out = new FileOutputStream(certFile);
out.write(encodedCert);
out.flush();
out.close();
}

The certificate file can be added to the truststore from command line as follows:
C:\ProgramFiles\Java\jdk1.7.0_40\bin>keytool -import -file D:\\MySecurityKeys\MyCertificate.cert -alias MyCertificate
  -keystore MyTrustStore

To see how to load and use the public key and private key generated above, you can refer to next post.

Tech talk...Cryptography or Encryption [Generating & Using Keystore/Truststore]

Keystore is used to hold the private keys.
In java, keystore can be generated from the command prompt.
This is the oracle documentation for doing the same:
http://docs.oracle.com/cd/E19509-01/820-3503/ggfen/index.html

You need to go to the jre bin folder . Inside that the executable 'keytool' should be present. this is used to generate the keystore.
Here's the command to generate the keystore

keytool -keystore <keystore name> -genkey -alias <keystore-alias>

example:

keytool -keystore MyKeyStore -genkey -alias MyKeyStore

Once you enter the above command, you would be prompted for certain inputs, keep providing the inputs and finally the keystore file would be generated with a .jks extension in the bin folder.
From here, you can copy the keystore file anywhere.

An example of what all would be entered once the above command is entered:


Enter keystore password: javacaps
What is your first and last name?
[Unknown]: neha neha
What is the name of your organizational unit?
[Unknown]: Development
what is the name of your organization?
[Unknown]: self
What is the name of your City or Locality?
[Unknown]: Bangalore
What is the name of your State or Province?
[Unknown]: Karnataka
What is the two-letter country code for this unit?
[Unknown]: India
Is<CN=development.self.com, OU=Development, O=self, L=Bangalore, ST=Karnataka, 
C=India> correct?
[no]: yes

Enter key password for <MyKeyStore>
    (RETURN if same as keystore password):

Once the keystore is generated, either keys can be added to it using command prompt or using java program.To add keys using command prompt, you can further refer to the oracle documentation here: http://docs.oracle.com/cd/E19509-01/820-3503/ggfen/index.html I used java program to generate and add private keys to the keystore. Refer to the next post for seeing example of how to generate Asymmetric key pairs and add them to the keystore/truststore using java.


The key store that holds the public key is generally called a truststore. A truststore can be generated in the same way as demonstrated above. For example:

keytool -keystore MyTrustStore -genkey -alias MyTrustStore

Monday, 30 June 2014

Tech Talk.....Cryptography or Encryption [Introduction]

Recently, I was working on securing the communication between different components of my product using cryptography or encryption (as it was called in the old world), I explored and learnt various concepts related to cryptography which proved to be very helpful. However, they were scattered around a lot and I had to filter out lots of stuff from here and there. I would like to summarize the learning that I gathered, over a series of small posts here, that would help someone like me in the future save time and effort and keep the learning crisp and fast.

Cryptography is a way to secure communication between two parties from any third party. In the world of computers, there are two different kind of cryptography techniques that are mostly popular : Public key cryptography (also known as Asymmetric cryptography) and Symmetric cryptography.

Public key cryptography:
This cryptography or encryption technique uses a pair of keys for encryption - decryption, one being a private key and another being a public key.Private key is used for decryption of data and public key is used for encryption of data. This mode of encryption is famous in the client - server world where the server generates a pair of keys - a public key and a private key. The private key is retained with the server , while the public key is made available to any client that wants to communicate to the server. The client encrypts its data with the public key before sending it over to the server, when the server gets the data from client, it uses the private key to decrypt the data. If any third party gets hold of the encrypted data, it can't decrypt the data because it won't have the private key with it.

In the next post, I will show how to generate a public-private key pair, how to store it and how to use it.(In java)


Monday, 17 March 2014

Tech Talk... Creating a temporary file using java

Template:

File tempFile = File.createTempFile(<temp-file-name>, <temp-file-extension>);

Using the above template would create a file with name <temp-file-name> and extension <temp-file-extension>.

Code sample:

File tempFile = File.createTempFile("mytempfile", ".txt");

Where such code gets useful:

Mostly, I find it very useful when writing unit test cases in java which require to test scenarios where a file creation is required, because, this way, I don't have have to worry about which OS I am on, what location should I choose to create a temporary file etc. In the setup method in my unit test, I can create the file and in the teardown method i can call delete() on this file to ensure that the file gets created before I run my testcase and gets deleted after the testcase is complete. 

Friday, 28 February 2014

Tech talk...creating a symlink

Almost everyone knows that a symlink is a symbolic link (in simplistic words, a shortcut link) to a file or a directory and most of you would be knowing how to create a symlink on one of those linux systems. So, the question arises, why am I writing a post here on how to create a symlink, well, for some people as basic (i wont like to call naive) as me, who went through so many sites to achieve the same..somehow it was a simple line and a simple command on all those sites but yet there were contradictions due to which after 4-5 trials I was able to get the first link created properly. So, I was compelled to put it out to the world, to make a simple symlink creation even simpler. Here you go...

Create a symlink:

Command format:


ln -s [folder-or-file-for-which-symlink-is-to-be-created] [symlink-name]

Command example:


ln -s rootFolder/childFolder/folderWhoseSymlinkIsRequired symlinkToFolder
In the above case, the symlink will be created in the current directory, where the rootFolder lies.

Wednesday, 22 January 2014

Tech Talk...Byte array and String conversions in Java

How to convert a byte array to a String in Java:
To convert a byte array to a string, create a new String using the byte array as an input argument to the String constructor. Something like this:

byte[] bytes = initializeByteArray();
String str = new String(bytes);


To convert a string to a byte array, you can use the String API getBytes() :

String str = "Hello"
byte[] bytes = str.getBytes();

Monday, 30 December 2013

Tech Talk...JavaScript execution from within JVM

This tutorial describes how to execute JavaScript from within java using the Rhino provided JavaScript execution Engine.

About Rhino:

What is Rhino JavaScript Engine
Maven Repository for Rhino Jar

How to invoke a JavaScript from within java using Rhino:


public class JavaScriptInvoker {
    String myfn = ""
            + "function sayHello(inputStr, outputStr){"
            + " outputStr =  \"Hello\"+inputStr;"
            + "}";
    Function function;
    Context ctx;
    ScriptableObject scriptable;

   public void initJs(){
        ctx = Context.enter();
        ctx.setOptimizationLevel(9);
        scriptable = ctx.initStandardObjects();
        function = ctx.compileFunction(scriptable, myfn, "sayHello", 0, null);
   }

   public void invokeJs(){
      String outputStr;
      Object[] args = {"Neha", outputStr};
      function.call(ctx, scriptable, function, args);
      System.out.println(outputStr);
   }

    public static void main(String[] args) throws Exception{
       JavaScriptInvoker jsInvoker = new JavaScriptInvoker();
       jsInvoker.initJs();
       jsInvoker.invokeJs();
    }
}


Understanding different parts of the program:

1. Initializing the JavaScript engine.
The Rhino JavaScript engine needs to be initialized before it can be used to invoke a java script. This initialization involves initializing the internal objects used by the JavaScript Engine (being done using the line  scriptable = ctx.initStandardObjects(); ) .This single line would be sufficient for you in most of the cases( unless you need to do some sophisticated initializations on your own.).
Also, an optimization level can be set on the context of the engine, which ensures how performant the invocation of JavaScript from within java will be (see the line:ctx.setOptimizationLevel(9);) Optimization levels are integers, 9 being the highest.
Finally, the javascript which has to be invoked, needs to be initialized. This is being done in the line:
 function = ctx.compileFunction(_scriptable, myfn, "sayHello", 0, null);

2. Invoking the JavaScript from within java at runtime.
Once the javascript engine is initialized, it can be invoked at runtime multiple times to invoke the function compiled above, that is happening in the code :
 function.call(ctx, scriptable, function, args);
The first two arguments to the call method are context object and scriptable object of the JavaScriptEngine to let it know of the initialization parameters.
The next parameter is the compiled function that needs to be called.
The final parameter is an Object array consisting of parameters being passed to the function being invoked.

3. Parameter passing / Object sharing between JavaScript and Java.
As seen in the code above, I am passing two parameters to the method sayHello : one input string and one output string. Both these are Java String Object types. They are successfully binded and passed to the function sayHello, which appends "Hello" to the input string and then assigns the result to output string and returns the output string back. On obtaining the output string, the java runtime can successfully use it for further operation.

4. Java method invocation from within javascript engine
From within the javascript function, any of the Java methods can be invoked, even objects can be passed from the java code to the javascript as initialization parameters or arguments and then they can be used by the javascript in any way possible.

Tuesday, 6 August 2013

The Insertion Sort

How Insertion Sort works

Insertion sort is a simple sorting algorithm where the final sorted array is built by traversing through the array, taking one element at a time and placing it at its right location as per the expected sorted array.

Efficiency of insertion sort

Best case (sorted array is provided as input) : O(n)
Worst case(reverse sorted array is provided as input): O(n^2)
Average case : partially sorted array : O(n+d)
where, n = number of elements in the array and d= number of inversions required to sort the array (inversions = shuffling/interchange of array elements)

The more sorted an array is, the lesser would be d (number of inversions) and hence faster would be insertion sort algorithm.
The nature of insertion sort makes it more efficient than many other quadratic sorting algorithms like bubble sort and selection when the list to be sorted is not too huge , also, the more the list to be sorted is near to being sorted (nearly sorted lists), the better this algorithm would perform.

Advantages of insertion sort

  • It is simple to implement
  • It is quiet efficient for small sets of data
  • It is more efficient than most other quadratic sorting algorithms
  • It is stable, which means, if there are more than one elements with the same keys, their relative order remains unchanged
  • It is in-place. only requires a single extra element, which would count as constant O(1).
  • It can sort a list on-the-go, which means, as and when it is taking inputs, it can keep sorting them.

Insertion sort algorithm implementation in java

public class InsertionSort {
    public static int[] insertionSort(int[] arrayToSort) {
        int key;
        for(int i=1; i < arrayToSort.length; i++){
            //within the outer for loop, assign the next element as 'key'.
           //key is the element which is to be placed at its right location within this iteration of loop
            key =  arrayToSort[i];
            //start traversing from the back of the array in the inner for loop
            int j = i-1;
            //traverse through the elements which are greater than key and shift them as and when we   
            //traverse , one space further, to make space for the key at the right location
            for(; j >= 0 && key < arrayToSort[j]; j--){
                //shift the elements greater than key further in the array
                arrayToSort[j+1] = arrayToSort[j];
            }
           //finally place key at its right location
            arrayToSort[j+1] = key;
        }
        
        //print out the sorted array
        System.out.println("Sorted array:");
        System.out.println();
        for(int i=0; i<arrayToSort.length; i++){
            System.out.print(" " + arrayToSort[i] + " ");
        }
        System.out.println();
       
        return arrayToSort;
    }

    public static void main(String[] args) throws NumberFormatException, IOException {
        List<Integer>listToSort = new ArrayList<Integer>();

        //Take input from the console
        InputStreamReader in = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(in);
        System.out.println("Input comma separated list of integers and hit enter when done");
        String inputStr = br.readLine();
        String[] splittedInputs = inputStr.split(",");
        for(String str : splittedInputs){
            listToSort.add(Integer.parseInt(str));
        }
        while(!(inputStr = br.readLine()).equals("DONE")){
            listToSort.add(Integer.parseInt(inputStr));
        }
        //call the insertion sort method
        insertionSort(listToSort.toArray());
    }

}

Reverse Insertion Sort

During Insertion sort, the array elements are normally sorted in ascending order (first element of array = smallest and last one = largest). In case of reverse insertion sort, they are sorted in the descending order. Below is a java function for reverse insertion sort implementation :

    private static void reverseInsertionSort(int[] arrayToSort) {
        int key;
        for(int i=1; i < arrayToSort.length; i++){
            key = arrayToSort[i];
            int j = i-1;
           //here's the difference from the actual insertion sort
           //we traverse the array backward in the inner for loop and shift the elements which are 
          //smaller than the given key, to find the right place for the key (we shift the elements 
         //larger than the key, in case of normal insertion sort).
            for(; j >= 0 && key > arrayToSort[j]; j--){
                arrayToSort[j+1] = arrayToSort[j];
            }
            arrayToSort[j+1] = key;
        }
 

         //print out the sorted array
         System.out.println("Selection Sorted array:");
        for(int i=0; i<arrayToSort.length; i++){
            System.out.print(" " + arrayToSort[i] + " ");
        }
    }


Friday, 24 May 2013

SVN integration using SVNKit

What is SVNKit?

SVNKit is an open source java based library for working with / integrating with SVN (Subversion control system). Click here to get more details on SVNKit.
I have compiled below some simple sample code fragments that show you how to get started with SVNKit to connect with svn and perform different kind of operations like check-in, check-out, export using the right SVNKit APIs.

Where to download it from?

SVNKit can be downloaded from here.
To do any operation with a SVNKit, first thing we need to do is obtain a SVNClientManager.

Code Samples on using SVNKit 

Obtaining a SVNClientManager

Following code fragment shows how to obtain a SVNClientManager:

public SVNClientManager getSVNClientManager () throws IOException{
             SVNURL url = SVNURL
                  .parseURIDecoded("<path to the base svn repository>");                    
             SVNRepository repository = SVNRepositoryFactory.create(url, null);
             ISVNOptions myOptions = SVNWCUtil.createDefaultOptions(true);
            //provide svn username and password

            //username = name used to connect to svn
            //password = password used to connect to svn
            ISVNAuthenticationManager myAuthManager = SVNWCUtil
                .createDefaultAuthenticationManager("<username>", "<password>");
           repository.setAuthenticationManager(myAuthManager);
        //clientManager will be used to get different kind of svn clients instances to do different activities

       //like update, commit, view diff etc.
        SVNClientManager clientManager = SVNClientManager.newInstance(
                myOptions, myAuthManager);

}

Once SVNClientManager is obtained, there are different kind of 'svn client' classes that it can provide to do different kind of svn operations like check-in, check-out, add, export resources (files and folders). Below is provided sample code example for each kind of svn operations that we might be interested to perform:


Checking in a completely new file or folder into SVN

 public void commitToSvn(SVNClientManager clientManager)
            throws SVNException {
        SVNCommitClient commitClient = clientManager.getCommitClient();
        File fileToCheckin = new File("LocalDir/SampleFileFolder/SampleFile1");
        boolean recursive = true;       
       SVNCommitInfo importInfo = commitClient
                .doImport
(
                        fileToCheckin ,
                        SVNURL.parseURIDecoded("<path at which we want to check-in the file>"),
                        "testing svn kit integration", recursive);
        System.out.println(importInfo.getNewRevision());
    }
As shown by the highlighted code above, the svn client used to check-in completely new resources is 'SVNCommitClient' and the API that it used for this purpose is 'doImport(File fileToCheckin, SVNURL svnUrlAtWhichToCheckInFile, String comment, boolean recursive)'. If we want to check-in a folder and all its sub-folders and files recursively, then the last argument (boolean recursive) needs to be set to true.

Checking out a resource that exists in svn, modifying it and check-in back to svn

     public void checkOutChangeAndCheckIn(SVNClientManager clientManager) throws IOException, SVNException {
        SVNUpdateClient updateClient = clientManager.getUpdateClient();
        updateClient.setIgnoreExternals(false);
       //we are checking out a resource 'SampleFileFolder' which is having a file 'SampleFile1'
       //and putting it under 'LocalDir' in our local machine.
        SVNURL url = SVNURL
                .parseURIDecoded("<path to checkout resource from>");
        File destPath = new File("LocalDir");
        SVNRevision revision = SVNRevision.create(<revision number which we obtained when we checked in the file for the first time in the above section of code >);
        boolean isRecursive = true;
        long doCheckout = updateClient.doCheckout(url, destPath, revision,
                revision, isRecursive);
        System.out.println(doCheckout);

        
         //re-write the content of the checked-out file
        File file = new File("LocalDir/SampleFileFolder/SampleFile1");
        FileOutputStream fos = new FileOutputStream(file, false);
        StringBuffer newContent = new StringBuffer();
        newContent.append("This is new content for new version of file");
        fos.write(newContent.toString().getBytes());
        fos.flush();
        fos.close();
        
        //check-in the file folder back into svn
        SVNCommitClient commitClient = clientManager.getCommitClient();
        File[] paths = { new File("LocalDir/SampleFileFolder/SampleFile1") };
        //this should be set to false as it will keep the file locked after checkin
        boolean keepLocks = false;
        String commitMessage = "new version of sample file1 commited";
        boolean force = true;
        boolean recursive = true;
        SVNCommitInfo commitInfo = commitClient.doCommit(paths, keepLocks,
                commitMessage, force, recursive);
        System.out.println(commitInfo.getNewRevision());
    }

As seen in the above code sample, we checkout the file which we previously had checked-in into svn using SVNCommitClient.doImport API. The API that we use to check-out the folder is SVNUpdateClient.doCheckout. Then we make some changes in this checked-out file and commit it back to svn using the API SVNCommitClient.doCommit
PS: SVNCommitClient.doCommit is used to commit new set of changes to an existing file / folder in svn , if the file or folder doesn't already exist in the svn and we try to use this API, it will give error.
Similarly  SVNCommitClient.doImport is used for new files, if the file already exists in svn, then this API will throw exception complaining that the file already exists in svn.


Exporting a file from svn

    public void exportFromSvn(SVNClientManager clientManager) throws SVNException {
        SVNUpdateClient updateClient = clientManager.getUpdateClient();
        SVNURL url = SVNURL.parseURIDecoded("<svn url to export from>");
        //destination path
        File dstPath = new File("LocalDirNew");
        //the revision number which should be looked upon for the file path
        SVNRevision pegRevision = SVNRevision.create(<right svn revision number>);
        //the revision number which is required to be exported.
        SVNRevision revision = SVNRevision.create(
<right svn revision number>);
        //if there is any special character for end of line (in the file) then it is required. For our use case, //it can be null, assuming there are no special characters. In this case the OS specific EoF style will //be assumed
        String eolStyle = null;
        //this would force the operation
        boolean force = true;
        //Till what extent under a directory, export is required, is determined by depth. INFINITY means the whole subtree of that directory will be exported
        SVNDepth recursive = SVNDepth.INFINITY;
        updateClient.doExport(url, dstPath, pegRevision, revision, eolStyle, force, recursive );
    }

SVNUpdateClient.doExport is used to export a svn resource to a particular location.
Difference between export and check-out : when a resource is checked-out from svn then the svn properties (Stored in .svn files) are also checked-out into the local machine, but when a resource is exported using the doExport API , svn info is not exported along with the resources.

Finding diff between resources using SVNKit:

     private static void viewDiff(SVNClientManager clientManager)
            throws SVNException, IOException {      
        SVNDiffClient diffClient = clientManager.getDiffClient();
        // diff between two versions in svn:
        File svnDiffFile = new File("LocalDir/SvnDiffFile");
        svnDiffFile.createNewFile();
        SVNURL url1 = SVNURL
                .parseURIDecoded("<svn-file-url-for-file-whose-revisions-are-to-be-compared>");
        SVNURL url2 = SVNURL
                .parseURIDecoded("
<svn-file-url-for-file-whose-revisions-are-to-be-compared>");
        SVNRevision rN = SVNRevision.create(<revision-no-1>);
        SVNRevision rM = SVNRevision.create(<revision-no-2>);
        boolean recursive = true;
        //i didn't see the meaning of this parameter, setting it to false worked fine for me.
        boolean useAncestry = false;
        OutputStream result = new FileOutputStream(svnDiffFile);
        diffClient.doDiff(url1, rN, url2, rM, recursive, useAncestry, result);

        // diff between a file and a svn revision number
        File path1 = new File("LocalDir/SampleFile");
        rN = SVNRevision.WORKING;
        rM = SVNRevision.create(
<revision-no-1>);
        File svnToWorkingDiffFile = new File("LocalDir/SvnToWorkingDiff");
        svnToWorkingDiffFile.createNewFile();
        OutputStream result1 = new FileOutputStream(svnToWorkingDiffFile);
        diffClient.doDiff(path1, rN, url2, rM, recursive, useAncestry, result1);
}

API doc for different svn-clients and their APIs are available in the svn-kit-api-doc (javadoc) . Detailed architecture and documentation is present at the documentation section in the svnkit website.