Saturday, September 29, 2012

Git Headache Solved: 'Modified Files'


Pretty much all the dev team work on a mac environment except one! No rewards for guessing that its mine which differed from everyone else's. I occasionally use my Windows 7 box to do some development and commit to repo.
We opted to use git for this project and I have to say that the first few days were quite challenging to use git in the way its meant to be used. But after few hiccups we got the hang of it. I initially had some trouble setting up git on my windows m/c to behave the same way as on my mac. When I did a clone for a git repository a whole bunch of 'Modified' files showed up when I ran 'git status'. After some googling and tweaking the core.autocrlf setting to 'true/false/input', I got it working right. All the 'Modified Files' list disappeared. But recently I decided to look around for git clients for windows and installed git extensions and smartgit. But something changed and when I did a clone, the dreaded 'Modified Files' reared its head again! I thought "Ah! Thats a cakewalk. I know what to do" and started changing my core.autocrlf setting.. but nothing changed. When you run 'git config -l', you might see a bunch of core.autocrlf entries.. I ran the following to make sure every core.autocrlf entries are set to false:

> git config -l
> git config --global core.autocrlf false
> git config core.autocrlf false
> git config --system core.autocrlf false

Followed by
> git reset --hard
> git status

I still kept getting the 'Modified Files'. Strangely, when I ran the 'git status' from cygwin, it was fine. It showed no modified files. Cygwin git was 1.6.x version, whereas the one run from MingW was 1.7.4
After an invisible hand slapped the back of my head, I realized that I could run diff to see what the changes were.
> git diff 

This showed that the file contents were fine.. it was the mode that was the problem.
All the files showed the following:

old mode 100755  (rwx r-x r-x)
new mode 100644 (rw- r-- r--)

Not sure why it decided to do that, but changing the core.filemode solved this problem.
> git config core.filemode false

So when you run into a 'Modified Files' issue, make sure you check the setting for

core.autocrlf
core.safecrlf
core.filemode

Good Luck!

Friday, September 28, 2012

Hibernate Criteria Snippets



The very basic
session.createCriteria(Car.class);

session.createCriteria(Car.class)
.add(Restrictions.eq(“engine.code”, code))
.uniqueResult();

Collections: isEmpty(), size()
session.createCriteria(Student.class)
         .add(Restrictions.isEmpty(“courses”, 2));

Ignore case:
session.createCriteria(Student.class)
         .add(Restrictions.eq(“name”, name).ignoreCase());

session.createCriteria(Student.class)
         .add(Restrictions.ilike(“name”, name));


Wildcard:
session.createCriteria(Student.class)
         .add(Restrictions.like(“name”, “test%”));

session.createCriteria(Student.class)
         .add(Restrictions.like(“name”, “test”, MatchMode.START));


Logical Operations:
session.createCriteria(Student.class)
         .add(Restrictions.or(
                  Restrictions.and(
                           Restrictions.eq(“firstname”, fn), Restrictions.eq(“lastname”, ln)
                  ),
                  Restrictions.in(“subject”, subjects)
         ));

Projections & Transformers:
session.createCriteria(Student.class)
         .setProjection(Projections.projectionList()
                  .add(Projections.property(“name”).as(“studentName”))
                  .add(Projections.property(“section”).as(“section”)))
         .setResultTransformer(Transformers.aliasToBean(StudentDTO.class));


Aggregation:
session.createCriteria(Order.class)
         .setProjection(Projections.projectionList()
                  .add(Property.forName(“id”).group())
                  .add(Property.forName(“style”).count())
                  .add(Property.forName(“amount”).avg()));

SqlProjections:
String sql = “(select avg(o.amount) from Orders o where o.id= order_id) as avgAmount”;
session.createCriteria(Receipt.class)
         .createAlias(“orders”, “o”)
         .setProjection(Projections.projectionList()
                  .add(Projections.groupProperty(“o.id”))
                  .add(Projections.sqlProjection(
                           sql,
new String[]{“avgAmount”},
new Type[]{new BigDecimalType()})));


Conjunction & Disjunction:
Criteria criteria = session.createCriteria(Order.class);
Conjunction contact1Filter = Restrictions.conjunction();
      contact1Filter.add(Restrictions.eq("c1_firstname", c1fn));
      contact1Filter.add(Restrictions.eq("c1_lastname", c1ln));


Conjunction contact2Filter = Restrictions.conjunction();
      contact2Filter.add(Restrictions.eq("c2_firstname", c2fn));
      contact2Filter.add(Restrictions.eq("c2_lastname", c2ln));

Disjunction contact1Or2Filter = Restrictions.disjunction();
      contact1Or2Filter.add(contact1Filter);
      contact1Or2Filter.add(contact2Filter);

criteria.add(contact1Or2Filter);

... results in >>
 FROM Order WHERE 
  (c1_firstname AND c1_lastname)  -- conjunction 
     OR                           -- disjunction
  (c2_firstname AND c2_lastname)  -- conjunction


Friday, August 31, 2012

JAXB - marshalling an entity with missing @XmlRootElement


I'm currently working on an application that needs to send/receive SOAP messages which are fairly large. With simple cases, I could simply use SoapUI to load the wsdl and execute tests for each of the operations defined for that service. But when it comes to actually invoking the service via application, things could becomes little bit murkier if you start getting SOAP faults instead of valid response.
I ran into such scenario and looking at the java code, everything looked OK. Next thing was to print out the xml payload to see whats going on.

To do that, I had to marshal the java object into xml using JAXBContext and pass it to a writer. Following code does that..


        JAXBContext jaxbContext;
        String xmlData = "";
        String type = obj.getClass().getName();
        try {
            StringWriter writer = new StringWriter();
            jaxbContext = JAXBContext.newInstance(obj.getClass());
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(obj, writer);
            xmlData = writer.toString();
            logger.debug(String.format("XML Representation of %s: \n%s", type, xmlData));
        } catch (JAXBException e) {
            logger.error(String.format("Unable to marshal %s: \n%s", type, e.getMessage()));
        }


But when I ran it, I got the following error:

javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2: unable to marshal type "com.company.model.Header" as an element because it is missing an @XmlRootElement annotation]

It was easily fixed by adding @XmlRootElement annotation to those entities that I was trying to marshal, but that wasnt a good solution, since I really shouldn't have to do that.
These entities were generated via Apache CXF's wsdl2java task and every time I run that, its going to overwrite the changes that I did. After some googling, found that there were two ways that a JAXB runtime can perform marshaling:
  1. By adding @XmlRootElement
  2. Using JAXBElement wrapper objects, where T is the type that you'd want to marshal. 

Second option was definitely the way for me to go here.. Made the appropriate change and voila! I got what I wanted w/o having to worry about manipulating the wsdl generated code. :)


        JAXBContext jaxbContext;
        String xmlData = "";
        try {
            StringWriter writer = new StringWriter();
            JAXBElement<Header> jaxbWrappedHeader =  objectFactory.createHeader(obj);
            jaxbContext = JAXBContext.newInstance(Header.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(jaxbWrappedHeader, writer);
            xmlData = writer.toString();
            logger.debug(String.format("XML Representation of Header: \n%s", xmlData));
        } catch (JAXBException e) {
            logger.error(String.format("Unable to marshal Header: \n%s", e));
        }

Only downside to this was not being able to use generics..



Monday, June 4, 2012

Stopping a windows process


If you ever find yourself stuck (I was) with working on an old windows box and you dont have the benefits of using something better than the lame windows process explorer, here are some things that helped me out with force killing my process..


There were multiple instances of tomcat running on this box and there was no way to tell which .exe process belongs to the one I'm trying to stop.
To list just the tomcat instances, you could run the 'tasklist' command.


tasklist /fi "imagename eq tomcat5.exe"  (replace tomcat5.exe with whatever process you're looking for)




Now which one of those tomcat5.exe is mine?!!! 
Its ugly, but 'wmic' command would help you out to find out the specific tomcat5.exe process. 


wmic /output:C:\Processes.txt PROCESS get Caption,Commandline,Processid


This creates a Processes.txt file under C:\ which lists out all the processes and the binary executable path it was started from. 
After looking up this file, I was able to narrow it down to the specific PID 3868 and was able to kill it by running 


taskkill /f /pid 3868 


With something like Sysinternals Process Explorer, you wouldn't need to go through all this, but if you ever get stuck with some limitations.. then you could always use 'other' ways to get around! :)