sobota, 11 maja 2013

JAVA vs .NET differences in practice

Hello long time I didn't write any post - it's time to change it! Today I would like to show you in practice some differences between .NET and Java. I mean in some primitives data types and other. Few days ago I was involved to some task with hashed users passwords. It was necessary for test Web Services (JAX-WS) whose connect with some other services using hashed password. We have some hash algorithm which was written in .NET and we would like to have the same result in Java but it wasn't working. OK let's have some details. This is some similar example in .NET
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1.     private string generateSuperHash()
  2.  
  3.         {
  4.             byte[] t1= { 0x1f, 0xcd, 0x5, 0x12, 0xf3, 0xaa };
  5.      // byte[] t1= { 31, 205, 5, 18, 243, 170};
  6.  
  7.             byte[] t2= { 0xf3, 0x3d, 0x1, 0xb1, 0x3d, 0xc5 };
  8.     //  byte[] t2= { 243, 61, 1, 177, 61, 197};
  9.             byte[] t3= new byte[6];
  10.  
  11.             for (int i= 0; i< t3.GetLength(0); i++)
  12.             {
  13.                 t3[i] = Convert.ToByte((Convert.ToUInt16(t1[i]) ^ Convert.ToUInt16(t2[i])));
  14.             }
  15.             return Convert.ToBase64String(t3);
  16.         }



From .NET point of view everything is fine, but from Java is not! Why? - In .NET byte range is between 0-255 in Java is between (-127,128). This is 1 fail which I have discovered in code. Solution? - change the type from byte to int in Java and 1 problem fixed up.(But not really...). OK in Java there is a bitwise operator ^ (XOR) so - Convert.ToByte in Java is simple.
But XOR wouldn't work on int type, if I cast int to byte i will lost precision. Damn! There is another valuable information and comparison -Convert.ToBase64String and SHA512 algorithm. What is a problem with SHA512 algorithm in Java? There is to many code (in pure JDK) to write, but if I add just 1 library/jar Apache Commons Codec my code reduces from around 20 lines of code just to 1.
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1.     private String hashSHA512(String param)
  2.     {
  3.         return DigestUtils.sha512Hex(param);
  4.     }
But what about ToBase64String? I was searching in google and there was to many code to write the equivalent. In .NET the programmer sent to the method ToBase64String a whole table with bytes, in Java even when I tried get all bytes and "stick" them together using StringBuffer/StringBuilder or many various combinations and approaches and send it to equivalent Base64 method from Apache Commons Codec but without good effects. Time was running up, and I feel some solution in the air, just like a wolf which felt the blood. I didn't give up, what I did is just use online .NET/C# compilator and write the code and run it!

So my final solution in Java was really short and works well.
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. package pl.test;
  2.  
  3. import org.apache.commons.codec.digest.DigestUtils;
  4.  
  5. public class HashPassword {
  6.  
  7.     public static void main(String[] args) {
  8.         HashPassword hp = new HashPassword();
  9.  
  10.         String hash = hp.hashToLDAP(hp.getUserID(), hp.getUserPass(), superHash);
  11.         System.out.println("Hash ---> " + hash);
  12.     }
  13.  
  14.     private final static String superHash = "PAEo85v";
  15.     private String userID = "1234567";
  16.     private String userPass = "01234569ASP";
  17.     private String hashToLDAP(String clientID, String clientPass, String superHash) {
  18.         String finalHash = hashSHA512((hashSHA512(clientPass + getSuperhash())) + clientID);
  19.         return finalHash;
  20.     }
  21.     private static String hashSHA512(String param) {
  22.         return DigestUtils.sha512Hex(param);
  23.     }
  24.     public String getUserID() {
  25.         return userID;
  26.     }
  27.     public static String getSuperhash() {
  28.         return superHash;
  29.     }
  30.     public String getUserPass() {
  31.         return userPass;
  32.     }
  33. }
After this I gained a lot in my new Team mates eyes. But they don't know that what kind a "lazy" bustard I am ;)

What is conclusion ? -Sometimes we are wasting time to find solution using another libraries, searching equivalent type in Java/.NET and a solution is just at your fingertips. Sometimes it's better to run any online compiler and run the code and see the result, save the output and use it in our code without wasting time to translate byte> 128 to int and many miracles in Java/.NET

piątek, 1 marca 2013

Quering and queries with parameter(s)

Hello!

I would like to show you, how to retrieve object from db using queries with parameter(s).

Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. package pl.selfimproveit.hibernate;
  2. import java.util.List;
  3. import org.hibernate.Query;
  4. import org.hibernate.Session;
  5. import org.hibernate.SessionFactory;
  6. import org.hibernate.cfg.Configuration;
  7. import pl.selfimproveit.model.User;
  8.  
  9. public class Launcher {
  10.     public static void main(String[] args) {
  11.         SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
  12.         Session session = sessionFactory.openSession();
  13.         session.beginTransaction();
  14.  
  15.         Query query = session.createQuery("from User u where u.firstName =:name").setParameter("name", "John");
  16.         List<User> users = query.list();
  17.        
  18.         System.out.println(users.size());
  19.         for (User user : users) {
  20.             System.out.println(user);
  21.         }
  22.         session.close();
  23.     }
  24. }
In this example we are searching a user with name "John". This is HQL example where we used only 1 parameter. Please remember that we are using a properties name from User class (I mean firstName, lastName, id -  you cannot use directly column names from your database). We are using now "labeled paramaters", but we can use questions marks (?), but  remember about type of this parameter and their sequence in query.

Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1.     Query query = session.createQuery("from User u where u.firstName =?").setParameter(0, "John");
  2.         List<User> users = query.list();
  3.        
  4.         System.out.println(users.size());
  5.         for (User user : users) {
  6.             System.out.println(user);
  7.         }
  8.         session.close();


This above snippet we have the same result using question mark. Rembember that postion of parameters are 0 indexed.

Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. Query query = session.createQuery("from User u where u.id =?").setInteger(0, 4);
  2.         List<User> users = query.list();
  3.        
  4.         System.out.println(users.size());
  5.         for (User user : users) {
  6.             System.out.println(user);
  7.         }
In example above, we used an indexed typed parameter (?). You should try to set this parameter to String, BigDecimal etc and examine what will be execute of this code. Sometimes query will be executing fine, when we try to find user with ID= 4 and we set a parameter like a String("4")

Query query = session.createQuery("from User u where u.id =?").setString(0, "4");


This is depend on database vendor, but you shouldn't using query in this way.

You can try to build queries with 2 and more parameters it's very simple.


When simply query with parameter is not enough....


Now, let's imagine that you would like to select all of your users with the first letter of their name is M and their  surname begins with S or B.
Believe me there is a Query but it won't be look nice, there is a rescue .... Criteria !
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. public class Launcher {
  2.  
  3.     public static void main(String[] args) {
  4.  
  5.         SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
  6.         Session session = sessionFactory.openSession();
  7.         session.beginTransaction();
  8.        
  9.         Criteria criteria = session.createCriteria(User.class);
  10.         criteria.add(Restrictions.like("firstName", "M%"))
  11.         .add(Restrictions.or(Restrictions.like("lastName", "B%"), Restrictions.like("lastName", "S%")));
  12.            
  13.         List<User> users = criteria.list();
  14.        
  15.         System.out.println(users.size());
  16.         for (User user : users) {
  17.             System.out.println(user);
  18.         }
  19.         session.close();
  20.     }

Criteria iterface is very handy, you can find there many SQL equivalent for example:

- like
-between
- in ( Used in collection, but if you try to find String using "S%" it won't work, it takes full String like "John" and try to find a name in your table contains excatly this String, so any SQL wildcard "doesn't pass the exam here..")
-notNull / isNull and many many others!

I mentioned about method Restriction.in.

Let's look at this example:



Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.like("firstName", "M%")).add(Restrictions.in("lastName", new String[] { "S%", "B%" }));


From the logic point of view this Criteria query should return me the same result like above from snippet, but it's not true. Method Restrictions.in  is searching iterating through every record searching exactly fits String : S%  and after that B% (in meaning String as a String not like a SQL Wildcard).

But if you  modify above Criteria query to the following:



Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.like("firstName", "M%")).add(Restrictions.in("id", new Integer[] {6,7,8,9}));

You will get the output.

Maybe you don't know but MySQL doesn't support charlist wild cards, this mean that query like this

SELECT * FROM User
WHERE lastName LIKE '[KTM]%'

Will cause an error, instead of you should use a regexp something like follow:

select * from User where lastName REGEXP '[KTM].*';










piątek, 8 lutego 2013

JBoss Tools & Git - must needed!

Eclipse vs NetBeans (holy war)


I started programming using NetBeans IDE (6.0 as far as I remember), I thought it's the best IDE on the planet (I'm not lazy but I like comfort and utility) my favourite design pattern was "click click... and done!" 
(I hardly ever used InteliJ IDE - so I don't have full comparison between all of them)
My first touch with Eclipse Helios was in 2009 and I said - "I will be never programming in this piece of  s**t !!!"  
Don't you ever say never! In 2012  I have discover Eclipse (Juno) once again - and whoaa! I am fall in love in it! But I hate default Eclipse colors, themes and other, thankfully I installed some plugins, I changed some setting and now my Eclipse has the same colors& themes like NetBeans :) it looks more nicer than "default Eclipse"
But let's go back to the merits.
Eclipse is cool, but his power is in the plugins & features. I fully recommend you to download and install 2 very useful plugins (I will use those plugins in Hibernate tutorials):
  • JBoss Tools
  • GIT 
The best way to install them just open your IDE Eclipse click from toolbar HELP-->Eclipse Marketplace...  enter the caption "GIT" in window which appear, and search.
This should look as follows:


(I have already installed GIT - this is the reason why I have a caption uninstall)

Go ahead and click "Install" after that restart your Eclipse IDE and viola! (new features are available if you choose "Window --> show view --> GIT" (I will mention later in Hibernate tutorial about GIT usability)

It could be good for you to install GIT BASH / GUI for your PC - it is useful for see differences in your repository. You can download GIT from here.
If you are not familiar with GIT - you can very fast to learn more. Just try GIT Tutorial Online

Please do the same with JBoss Tools (Eclipse Marketplace), but please be aware - don't install all stuff from there most of them probably you will never be used. I installed JBoss plugins for Hibernate, Maven, JSF.
That's all you need for now, let's begin Hibernate Tutorial!
















poniedziałek, 4 lutego 2013

Iteresting facts and traps in Java


I am learning now for some test, and I like to share with my obeservations
Let's start with some example class.

Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. package pl.selfimproveit;
  2.  
  3. public class IntegerTest {
  4.  
  5.     public static void main(String[] args) {
  6.    
  7.         Integer a = 134;
  8.         Integer b = 134;
  9.  
  10.         if (a == b) System.out.println("The same object! - test 1");
  11.         if (a.equals(b)) System.out.println("Equals values -test 1");
  12.        
  13.         Integer c = 12;
  14.         Integer d = 12;
  15.  
  16.         if (c == d) System.out.println("The same object! - test 2");
  17.         if (c.equals(d)) System.out.println("Equals values - test 2");
  18.  
  19.     }
  20. }
How do you think, what will be the ouput?
Equals values -test 1
The same object! - test 2
Equals values - test 2

Log4j take a look closer


Hello, in this post I will show you how to logging into log files or html files.Before we look closer to the Log4j, we add some sources to our JAR's.
In my previous post we added a log4j jar and slf4j jars, but when we are trying to get more details about for example LoggerFactory class we get a sad screen - atatch sources.
To resolve this I always add the sources and javadocs to all newly downloaded files.

But there is a better solution. Let's create our own user libraries with sources and javadocs.
To do this go to Window --> Preferences. Into search window located in left up corner write down there "user". 
Try to find caption "User Libraries" and click on it! You should see something like on screen bellow .




Now let's create new user Library. Click on "New"  give a name for the new library:
SLF4J and click OK, now your User Libraries should have new entry - SLF4J.
Click on it and then click "Add external JARs". 
Do you remember where did you download and extract your SLF4J zip file? Go there and add following JAR to your User Library:
  • slf4j-api-1.7.2.jar
  • slf4j-log4j12-1.7.2.jar
And click "Open". Don't close your own libraries. Now expand the menu and double click on Source attachment


Then choose external location  and external file, try to find file (in folder where you extract the zip with SLF4J framework)  "slf4j-log4j12-1.7.2-sources.jar" and click OK.
Do it the same with "
slf4j-api-1.7.2.jar" 
Create a new user library for Log4j jars and add sources to log4j.jar file.

Now right click on your project, select "Build path" --> add libraries select "user Library" and select your newly created libraries with sources and click OK.

Now try to click with CTRL on "LoggerFactory" in our Test class, you will see all API, now I don't need to ask uncle google for this. It's really cool, especially if you use Spring 3 framework all necessary things will be in your source files!
Think about it! You spent only 5 minutes for attaching a source, or 20 minutes for searching this in Google! (But what will happens if you don't have access to the Internet, and boss tells you go on keep programming?)


OK let's go back to our main goals - logging.
There are few levels of logging. The most restrictive is ALL. The lowest is OFF (logging nothing, logging is switched off).



In our Test class we logged an error level using in log4j.properties file log4j.rootLogger=ERROR, stdout  and in our program by using 

logger.error("message",error);

Let's modify this to level all
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. # Root logger option
  2. log4j.rootLogger=ALL, stdout
  3.  
  4. # Direct log messages to stdout
  5. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  6. log4j.appender.stdout.Target=System.out
  7. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  8. log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n



Also let's add some few lines of code in our Test class.
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. package pl.selfimproveit;
  2.  
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5.  
  6. public class Test {
  7.  
  8. private static final Logger logger = LoggerFactory.getLogger(Test.class);
  9.  
  10.     public static void main(String[] args) {
  11.        
  12.         String number = "nothing";
  13.         try {
  14.             logger.info("application just started!");
  15.             int a = Integer.parseInt(number);
  16.             System.out.println("Parsed number is " + a);
  17.         }
  18.         catch (NumberFormatException ex) {
  19.             logger.error("Error parsing String "+number+ " to integer ",ex);
  20.         }
  21.         logger.info("applications stopped");
  22.     }
  23. }

Run the code and see what is happening. 

Logging to files


Logging some bugs just directly to your console is nothing more just system out - that is a stone age!

Logging to a simple text file.
Let's modify our "log4j.properties"  file 
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. # Root logger option
  2. log4j.rootLogger=ERROR, file
  3.  
  4. # Direct log messages to file
  5. log4j.appender.file=org.apache.log4j.FileAppender
  6. log4j.appender.file.File=Error.log
  7. log4j.appender.file.layout=org.apache.log4j.PatternLayout
  8. log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n



Now if we run this, there should be no input on the console, but If you click on the project and press F5 (refresh), you should see a new file ... Error.log
Check what this file contains. You can modify log4j.properties file and add a specified file location to store - for example

"log4j.appender.file.File=c:\\Error.log"

You can choose also a extension of the file (simple extensions: like *.log, *.txt, *.doc[not recommended], etc) .

Logging to a rolling file appender


I think this is the most cool in log4j logging framework, nobody likes to pure text or black-white report. Role file appender gives us the solution.
Let's modify our  log4j.properties  file:
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. log4j.rootLogger=ERROR, rfile
  2.  
  3. log4j.appender.rfile=org.apache.log4j.RollingFileAppender
  4. log4j.appender.rfile.File =logs/Error.html
  5. log4j.appender.rfile.MaxFileSize=100KB
  6. log4j.appender.rfile.Append = true
  7. log4j.appender.rfile.layout=org.apache.log4j.HTMLLayout


Now let's run our program, there is nothing in console. Refresh the project inside newly created folder log/Error.html
Open this file using web browser (it could be external web browser in Eclipse). Now log file looks really nice :)








Log4j and user libraries

Mess mess is everywhere... but not in yours user libraries!



In this post I would like to show you some aspects of logging in Java applications.

Many times during programming you are obliged to add some JAR's to your build path.
Everything is fine until you need to know API of the method/function from this JAR's.


Let's create some example project in Eclipse


I gave the name for this project : TestLog4j , and I created a Test class with the main method in package:
com.selfimproveit.

I don't know what is your attitude to the clarity of your folders/documents etc, but I like to have everything under control. In my Eclipse Juno IDE   I created inside home eclipse path a  folder named "JARS" and I download there in to the separate folders all jars, libs. (You will see this on the end of this topic).

Now we must download some jars. There are few logging framework, the most popular is Log4j.
You can download it from this link.
There is possibility to download Log4j, directly from http://logging.apache.org/  but you will download just log4.jar and examples without sources and javadoc. (I will tell you later why sources and javadocs are so important to me).
 You should download 3 following files (the version could be different, when I was wrote this post 1.2.17 version was the current version)

 This is simple, from now we could start using Log4j but we need to be more flexible. 


What I mean is, what will happen if we change the logging framework? Our code will be rewritten once again - this is sad situation, isn't?
We should have some "bridge" between our application and logging framework. Our "medicine" is SLF4J



Now we should download SLF4J.  Now let's add some JAR's to our build path and finally start coding!
First of all add this JAR's to your build path:
  • log4j-1.2.17.jar
  • slf4j-api-1.7.2.jar
  • slf4j-log4j12-1.7.2.jar
After that, we must create a log4j.properties file. Go to NEW--> OTHER--> Properties File (If you don't have this feature in your Eclipse, you may download JBoss Tools plugins for your Eclipse).
Give a name to your file : log4j. Add the following code into log4j.properties file
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. # Root logger option
  2. log4j.rootLogger=ERROR, stdout
  3.  
  4. # Direct log messages to stdout
  5. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  6. log4j.appender.stdout.Target=System.out
  7. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  8. log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n


Now our program example looks as follows:
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. package pl.selfimproveit;
  2.  
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5.  
  6. public class Test {
  7.  
  8. private static final Logger logger = LoggerFactory.getLogger(Test.class);
  9.  
  10.     public static void main(String[] args) {
  11.        
  12.         String number = "nothing";
  13.         try {
  14.             int a = Integer.parseInt(number);
  15.             System.out.println("Parsed number is " + a);
  16.         }
  17.         catch (NumberFormatException ex) {
  18.             logger.error("Error parsing String "+number+ "to integer ",ex);
  19.         }
  20.     }
  21. }


STDOUT - it means show this on console
ERROR - error level is only displayed/logged
If we run this program, the error should be displayed to our console.
 Now If you click with CTRL button on the caption "LoggerFactory" you should see an API of this class, but  whoa!? What's going on? Probably you will see something like this:


I hate this view, in next post I will show you how to fix this up, also I will show you more options with logging.



sobota, 2 lutego 2013

Introduction



Welcome!


Probably you are here to find some information about Java and web technologies, and I think you can find here some usefull infomations. I hope you find here what you are looking for, and enjoy it. Please give me some feedback how I can improve my contet to create for example better code. This blog will be contains some aspects of my hobbies like: traveling, psychology, motorism and other.

Let's get started!