DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Latest Articles - DZone

article thumbnail
Simplifying the Data Access Layer with Spring and Java Generics
1. Overview This is the second of a series of articles about Persistence with Spring. The previous article discussed setting up the persistence layer with Spring 3.1 and Hibernate, without using templates. This article will focus on simplifying the Data Access Layer by using a single, generified DAO, which will result in elegant data access, with no unnecessary clutter. Yes, in Java. The Persistence with Spring series: Part 1 – The Persistence Layer with Spring 3.1 and Hibernate Part 3 – The Persistence Layer with Spring 3.1 and JPA Part 4 – The Persistence Layer with Spring Data JPA Part 5 – Transaction configuration with JPA and Spring 3.1 2. The DAO mess Most production codebases have some kind of DAO layer. Usually the implementation ranges from a raw class with no inheritance to some kind of generified class, but one thing is consistent – there is always more then one. Most likely, there are as many DAOs as there are entities in the system. Also, depending on the level of generics involved, the actual implementations can vary from heavily duplicated code to almost empty, with the bulk of the logic grouped in an abstract class. 2.1. A Generic DAO Instead of having multiple implementations – one for each entity in the system – a single parametrized DAO can be used in such a way that it still takes full advantage of the type safety provided by generics. Two implementations of this concept are presented next, one for a Hibernate centric persistence layer and the other focusing on JPA. These implementation are by no means complete – only some data access methods are included, but they can be easily be made more thorough. 2.2. The Abstract Hibernate DAO public abstract class AbstractHibernateDAO< T extends Serializable > { private Class< T > clazz; @Autowired SessionFactory sessionFactory; public void setClazz( Class< T > clazzToSet ){ this.clazz = clazzToSet; } public T findOne( Long id ){ return (T) this.getCurrentSession().get( this.clazz, id ); } public List< T > findAll(){ return this.getCurrentSession() .createQuery( "from " + this.clazz.getName() ).list(); } public void save( T entity ){ this.getCurrentSession().persist( entity ); } public void update( T entity ){ this.getCurrentSession().merge( entity ); } public void delete( T entity ){ this.getCurrentSession().delete( entity ); } public void deleteById( Long entityId ){ T entity = this.getById( entityId ); this.delete( entity ); } protected Session getCurrentSession(){ return this.sessionFactory.getCurrentSession(); } } The DAO uses the Hibernate API directly, without relying on any Spring templates (such as HibernateTemplate). Using of templates, as well as management of the SessionFactory which is autowired in the DAO were covered in the previous post of the series. 2.3. The Abstract JPA DAO public abstract class AbstractJpaDAO< T extends Serializable > { private Class< T > clazz; @PersistenceContext EntityManager entityManager; public void setClazz( Class< T > clazzToSet ){ this.clazz = clazzToSet; } public T findOne( Long id ){ return this.entityManager.find( this.clazz, id ); } public List< T > findAll(){ return this.entityManager.createQuery( "from " + this.clazz.getName() ) .getResultList(); } public void save( T entity ){ this.entityManager.persist( entity ); } public void update( T entity ){ this.entityManager.merge( entity ); } public void delete( T entity ){ this.entityManager.remove( entity ); } public void deleteById( Long entityId ){ T entity = this.getById( entityId ); this.delete( entity ); } } Similar to the Hibernate DAO implementation, the Java Persistence API is used here directly, again not relying on the now deprecated Spring JpaTemplate. 2.4. The Generic DAO Now, the actual implementation of the generic DAO is as simple as it can be – it contains no logic. Its only purpose is to be injected by the Spring container in a service layer (or in whatever other type of client of the Data Access Layer): @Repository @Scope( BeanDefinition.SCOPE_PROTOTYPE ) public class GenericJpaDAO< T extends Serializable > extends AbstractJpaDAO< T > implements IGenericDAO< T >{ // } @Repository @Scope( BeanDefinition.SCOPE_PROTOTYPE ) public class GenericHibernateDAO< T extends Serializable > extends AbstractHibernateDAO< T > implements IGenericDAO< T >{ // } First, note that the generic implementation is itself parametrized – allowing the client to choose the correct parameter in a case by case basis. This will mean that the clients gets all the benefits of type safety without needing to create multiple artifacts for each entity. Second, notice the prototype scope of these generic DAO implementation. Using this scope means that the Spring container will create a new instance of the DAO each time it is requested (including on autowiring). That will allow a service to use multiple DAOs with different parameters for different entities, as needed. The reason this scope is so important is due to the way Spring initializes beans in the container. Leaving the generic DAO without a scope would mean using the default singleton scope, which would lead to a single instance of the DAO living in the container. That would obviously be majorly restrictive for any kind of more complex scenario. 3. The Service There is now a single DAO to be injected by Spring; also, the Class needs to be specified: @Service class FooService implements IFooService{ IGenericDAO< Foo > dao; @Autowired public void setDao( IGenericDAO< Foo > daoToSet ){ this.dao = daoToSet; this.dao.setClazz( Foo.class ); } // ... } Spring autowires the new DAO insteince using setter injection so that the implementation can be customized with the Class object. After this point, the DAO is fully parametrized and ready to be used by the service. 4. Conclusion This article discussed the simplification of the Data Access Layer by providing a single, reusable implementation of a generic DAO. This implementation was presented in both a Hibernate and a JPA based environment. The result is a streamlined persistence layer, with no unnecessary clutter. For a step by step introduction about setting up the Spring context using Java based configuration and the basic Maven pom for the project, see this article. The next article of the Persistence with Spring series will focus on setting up the DAL layer with Spring 3.1 and JPA. In the meantime, you can check out the full implementation in the github project. If you read this far, you should follow me on twitter here.
January 5, 2012
by Eugen Paraschiv
· 25,161 Views · 1 Like
article thumbnail
JMeter load testing against Apache Webserver: Errors and Resolutions
have been working on a fairly simple JMeter load script that I can run a series of 4 sequential pages against an Apache server, but the goal was to have the server support 2,000 concurrent requests for 5 minutes without error. Most of my issues in this exercise have been with JMeter and the client machine used to test the Apache server. To begin, I must state I was originally configuring Apache with a prefork MPM: StartServers 100 MinSpareServers 75 MaxSpareServers 100 ServerLimit 2000 MaxClients 2000 MaxRequestsPerChild 0 At approximately line 72 of Jmeter.bat, there are several entries the manage the JVM for running Jmeter. set HEAP=-Xms512m -Xmx512m set NEW=-XX:NewSize=128m -XX:MaxNewSize=128m set SURVIVOR=-XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=50% set TENURING=-XX:MaxTenuringThreshold=2 set RMIGC=-Dsun.rmi.dgc.client.gcInterval=600000 -Dsun.rmi.dgc.server.gcInterval=600000 set PERM=-XX:PermSize=64m -XX:MaxPermSize=64m I decided to start with 1,000 concurrent requests for 5 minutes just to see how the test would fair. With the above settings I started getting OOM errors almost immediately so I decided to increase the HEAP and NEW memory to eliminate the issue and wanted to add more GC settings to increase the JVM’s ability to clean up: set HEAP=-Xms1024m -Xmx1024m -Xss128k set NEW=-XX:NewSize=256m -XX:MaxNewSize=256m set SURVIVOR=-XX:SurvivorRatio=14 -XX:TargetSurvivorRatio=50% set "TENURING=-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:MaxTenuringThreshold=4" set "EVACUATION=-XX:+AggressiveOpts -XX:+UseFastAccessorMethods -XX:+UseCompressedStrings -XX:+OptimizeStringConcat" set RMIGC=-Dsun.rmi.dgc.client.gcInterval=600000 -Dsun.rmi.dgc.server.gcInterval=600000 set PERM=-XX:PermSize=64m -XX:MaxPermSize=64m This did resolve the JMeter OOM issues, but now started getting Apache errors. During the ramp-up phase, I started getting connection refused errors: Response code: Non HTTP response code: org.apache.http.conn.HttpHostConnectException Response message: Non HTTP response message: Connection to http://pasundtastgprt2:8001 refused I started looking at the Apache server and noticed that the number of httpd threads was at 1,000 and it appeared that JMeter was running out of memory because the requests where starting to back up. This is why we load test right! So I decided to run a worker MQM and recompiled Apache to support the new MPM ServerLimit 80 StartServers 25 MaxClients 2000 MinSpareThreads 75 MaxSpareThreads 125 ThreadsPerChild 5 MaxRequestsPerChild 0 I started testing this configuration and while monitoring the server running 1,000 concurrent requests and the server looked like Apache was handling 1,000 requests just fine. I was running a simple command to output the sockets and httpd processes on the server during the load test: while true do echo -----`date '+%r'` -----: netstat -ant | awk '{print $6}' | sort | uniq -c | sort -n echo httpd processes: [`ps aux | grep httpd | wc -l`] echo . sleep 30 done Then when I was monitoring the load test, I was concerned about seeing 82 httpd processes running which was the ServerLimit I had set. -----08:02:37 AM -----: 1 established) 1 Foreign 4 CLOSE_WAIT 17 LISTEN 32 FIN_WAIT2 41 ESTABLISHED 69 FIN_WAIT1 630 SYN_RECV 45386 TIME_WAIT [82] httpd processes . I now increased the load to my target of 2,000 concurrent requests and restarted the JMeter test and was able to get to around 1,800 concurrent request and started getting connection refused errors again. I suspected that my Servers where maxed out and was not able to create anymore threads for those servers where having: 80 server * 5 threads each server == 400 requests processed concurrently So I increased the number of threads to 25 80 server * 25 threads each server == 2,000 requests processed concurrently To end up with this worker setting: ServerLimit 80 StartServers 25 MaxClients 2000 MinSpareThreads 75 MaxSpareThreads 125 ThreadsPerChild 25 MaxRequestsPerChild 0 I was then able to turn the load up to 2,000 concurrent requests. -----08:53:27 AM -----: 1 established) 1 FIN_WAIT2 1 Foreign 4 CLOSE_WAIT 12 CLOSING 17 LISTEN 129 ESTABLISHED 621 FIN_WAIT1 1203 SYN_RECV 55556 TIME_WAIT [53] httpd processes At this point we are only using 53 Servers and 2,000 clients. The tests sustained zero errors for 5 minutes during the test. As a test I increased the ThreadsPerChild to 40 and run the load test against 3,000 concurrent requests. I was able to get to around 2,800 concurrent requests then I started getting connection refused errors: Error Count: 1 Response code: Non HTTP response code: org.apache.http.conn.HttpHostConnectException Response message: Non HTTP response message: Connection to http://pasundtastgprt2:8001 refused and I also started getting JMeter errors: Response code: Non HTTP response code: java.net.BindException Response message: Non HTTP response message: Address already in use: connect So in the furure I would like to see how much further I can push the server and I think I can get to 3,000 concurrent and most likely far more than that on my current installation. From http://www.baselogic.com/blog/development/adding-memory-jmeter/
January 5, 2012
by Mick Knutson
· 26,090 Views · 1 Like
article thumbnail
CSS3 Optical Illusions
today i have prepared something interesting for you. this is a demonstration of several optical illusions in css3 (without using any images or javascript). enjoy the results. here are samples and downloadable package: live demo download in package ok, download the example files and let's start coding! step 1. html as usual, we start with the html. here is full html code of all 6 demos. index.html css3 optical illusions back to original tutorial on script tutorials 1 2 3 4 5 6 38 38 step 2. css here are the css styles. maybe you’ve noticed that in our html i have two css files: layout.css and illusions.css. the first file (layout.css) contain the styles of our test page. we will not publish these styles in this article, but if you wish – you can find these styles in our package. css/illusions.css span { display: none; } .contr { color: #000000; cursor: pointer; float: left; font-size: 16px; font-weight: bold; height: 30px; line-height: 30px; margin: 10px; text-align: center; text-decoration: none; width: 60px; -webkit-border-radius:10px; -moz-border-radius:10px; -ms-border-radius:10px; -o-border-radius:10px; border-radius:10px; background-color:#e3e3ff; background: -moz-linear-gradient(#ffffff, #eee); background: -ms-linear-gradient(#ffffff, #eee); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #eee)); background: -webkit-linear-gradient(#ffffff, #eee); background: -o-linear-gradient(#ffffff, #eee); filter: progid:dximagetransform.microsoft.gradient(startcolorstr='#ffffff', endcolorstr='#eee'); -ms-filter: "progid:dximagetransform.microsoft.gradient(startcolorstr='#ffffff', endcolorstr='#eee')"; background: linear-gradient(#ffffff, #eee); } .contr:hover{ background-color:#e3e3ff; box-shadow:0px 0px 4px rgba(0,0,0,0.5) inset, 0px 0px 0px 4px rgba(51,51,204,0.5); -moz-box-shadow:0px 0px 4px rgba(0,0,0,0.5) inset, 0px 0px 0px 4px rgba(51,51,204,0.5); -webkit-box-shadow:0px 0px 4px rgba(0,0,0,0.5) inset, 0px 0px 0px 4px rgba(51,51,204,0.5); } .demos { background-color: #b2b2b2; display: block; height: 640px; margin-top: 55px; overflow: hidden; position: relative; } .demos > div { display: none; } #page1:target ~ .demos #i1 { display: block; } #page2:target ~ .demos #i2 { display: block; } #page3:target ~ .demos #i3 { display: block; } #page4:target ~ .demos #i4 { display: block; } #page5:target ~ .demos #i5 { display: block; } #page6:target ~ .demos #i6 { display: block; } /* illusion 1 */ #i1 { width: 900px; } #i1 .row { background-color: #fff; border-bottom: 2px solid #888; height: 90px; -webkit-background-size: 140px 70px; -moz-background-size: 140px 70px; -ms-background-size: 140px 70px; -o-background-size: 140px 70px; background-size: 140px 70px; background-position: 0 50%; background-image: -webkit-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: -moz-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: -ms-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: -o-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: linear-gradient(0deg, #000 50%, transparent 50%, transparent); } #i1 .row:nth-child(3n+3) { background-position: 60px 50%; } #i1 .row:nth-child(2n+2) { background-position: 30px 50%; } /* illusion 2 */ #i2 { background-color: #98cb00; height: 640px; margin: 0 auto; overflow: hidden; padding: 0 150px; position: relative; width: 600px; } #i2 > div { float: left; height: 105px; padding-left: 90px; padding-top: 90px; position: relative; width: 105px; } #i2 div div { border: 1px outset #fff; height: 20px; position: absolute; width: 30px; -webkit-border-radius: 100px / 50px; -moz-border-radius: 100px / 50px; -ms-border-radius: 100px / 50px; -o-border-radius: 100px / 50px; border-radius: 100px / 50px; background: -webkit-linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); background: -moz-linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); background: -ms-linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); background: -o-linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); background: linear-gradient(top, #580402, #a63b17, #580402, #a63b17, #580402); } #i2 #o1 { -webkit-transform: rotate(-30deg) translatex(70px); -moz-transform: rotate(-30deg) translatex(70px); -ms-transform: rotate(-30deg) translatex(70px); -o-transform: rotate(-30deg) translatex(70px); transform: rotate(-30deg) translatex(70px); } #i2 #o2 { -webkit-transform: rotate(-60deg) translatex(70px); -moz-transform: rotate(-60deg) translatex(70px); -ms-transform: rotate(-60deg) translatex(70px); -o-transform: rotate(-60deg) translatex(70px); transform: rotate(-60deg) translatex(70px); } #i2 #o3 { -webkit-transform: rotate(-90deg) translatex(70px); -moz-transform: rotate(-90deg) translatex(70px); -ms-transform: rotate(-90deg) translatex(70px); -o-transform: rotate(-90deg) translatex(70px); transform: rotate(-90deg) translatex(70px); } #i2 #o4 { -webkit-transform: rotate(-120deg) translatex(70px); -moz-transform: rotate(-120deg) translatex(70px); -ms-transform: rotate(-120deg) translatex(70px); -o-transform: rotate(-120deg) translatex(70px); transform: rotate(-120deg) translatex(70px); } #i2 #o5 { -webkit-transform: rotate(-150deg) translatex(70px); -moz-transform: rotate(-150deg) translatex(70px); -ms-transform: rotate(-150deg) translatex(70px); -o-transform: rotate(-150deg) translatex(70px); transform: rotate(-150deg) translatex(70px); } #i2 #o6 { -webkit-transform: rotate(-180deg) translatex(70px); -moz-transform: rotate(-180deg) translatex(70px); -ms-transform: rotate(-180deg) translatex(70px); -o-transform: rotate(-180deg) translatex(70px); transform: rotate(-180deg) translatex(70px); } #i2 #o7 { -webkit-transform: rotate(-210deg) translatex(70px); -moz-transform: rotate(-210deg) translatex(70px); -ms-transform: rotate(-210deg) translatex(70px); -o-transform: rotate(-210deg) translatex(70px); transform: rotate(-210deg) translatex(70px); } #i2 #o8 { -webkit-transform: rotate(-240deg) translatex(70px); -moz-transform: rotate(-240deg) translatex(70px); -ms-transform: rotate(-240deg) translatex(70px); -o-transform: rotate(-240deg) translatex(70px); transform: rotate(-240deg) translatex(70px); } #i2 #o9 { -webkit-transform: rotate(-270deg) translatex(70px); -moz-transform: rotate(-270deg) translatex(70px); -ms-transform: rotate(-270deg) translatex(70px); -o-transform: rotate(-270deg) translatex(70px); transform: rotate(-270deg) translatex(70px); } #i2 #o10 { -webkit-transform: rotate(-300deg) translatex(70px); -moz-transform: rotate(-300deg) translatex(70px); -ms-transform: rotate(-300deg) translatex(70px); -o-transform: rotate(-300deg) translatex(70px); transform: rotate(-300deg) translatex(70px); } #i2 #o11 { -webkit-transform: rotate(-330deg) translatex(70px); -moz-transform: rotate(-330deg) translatex(70px); -ms-transform: rotate(-330deg) translatex(70px); -o-transform: rotate(-330deg) translatex(70px); transform: rotate(-330deg) translatex(70px); } #i2 #o12 { -webkit-transform: rotate(0deg) translatex(70px); -moz-transform: rotate(0deg) translatex(70px); -ms-transform: rotate(0deg) translatex(70px); -o-transform: rotate(0deg) translatex(70px); transform: rotate(0deg) translatex(70px); } /* illusion 3 */ #i3 { color: #000000; font-family: times new roman; font-size: 250px; padding-left: 300px; } #i3 .rev { text-align: right; -webkit-transform: rotate(-180deg); -moz-transform: rotate(-180deg); -ms-transform: rotate(-180deg); -o-transform: rotate(-180deg); transform: rotate(-180deg); } /* illusion 4 */ #i4 .row { background-color: #fff; border-bottom: 5px solid #fff; height: 50px; -webkit-background-size: 60px 50px; -moz-background-size: 60px 50px; -ms-background-size: 60px 50px; -o-background-size: 60px 50px; background-size: 60px 50px; background-position: 0 50%; background-image: -webkit-linear-gradient(0deg, #000 90%, transparent 10%, transparent); background-image: -moz-linear-gradient(0deg, #000 90%, transparent 10%, transparent); background-image: -ms-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: -o-linear-gradient(0deg, #000 50%, transparent 50%, transparent); background-image: linear-gradient(0deg, #000 50%, transparent 50%, transparent); } /* illusion 5 */ @-webkit-keyframes custom_effect { 0% {opacity: 0;} 33% {opacity: 1;} 100% {opacity: 1;} } @-moz-keyframes custom_effect { 0% {opacity: 0;} 33% {opacity: 1;} 100% {opacity: 1;} } #i5 { background-color: #b2b2b2; height: 600px; margin: 0 auto; overflow: hidden; position: relative; width: 600px; } #i5 > div { float: left; height: 200px; padding-left: 200px; padding-top: 200px; position: relative; width: 200px; } #i5 div div { height: 50px; position: absolute; width: 50px; -webkit-border-radius: 50px; -moz-border-radius: 50px; -ms-border-radius: 50px; -o-border-radius: 50px; border-radius: 50px; background-color: #b2b2b2; background-image: -webkit-radial-gradient(50% 50%, circle, #fd19fd, #b2b2b2 70%); background-image: -moz-radial-gradient(50% 50%, circle, #fd19fd, #b2b2b2 70%); background-image: -o-radial-gradient(50% 50%, circle, #fd19fd, #b2b2b2 70%); background-image: radial-gradient(50% 50%, circle, #fd19fd, #b2b2b2 70%); -moz-animation-name: custom_effect; -moz-animation-duration: 1.2s; -moz-animation-timing-function: linear; -moz-animation-iteration-count: infinite; -moz-animation-direction: normal; -moz-animation-delay: 0; -moz-animation-play-state: running; -moz-animation-fill-mode: forwards; -webkit-animation-name: custom_effect; -webkit-animation-duration: 1.2s; -webkit-animation-timing-function: linear; -webkit-animation-iteration-count: infinite; -webkit-animation-direction: normal; -webkit-animation-delay: 0; -webkit-animation-play-state: running; -webkit-animation-fill-mode: forwards; } #i5 #o1 { -moz-transform: rotate(30deg) translatex(150px); -moz-animation-delay: 0.1s; -webkit-transform: rotate(30deg) translatex(150px); -webkit-animation-delay: 0.1s; } #i5 #o2 { -moz-transform: rotate(60deg) translatex(150px); -moz-animation-delay: 0.2s; -webkit-transform: rotate(60deg) translatex(150px); -webkit-animation-delay: 0.2s; } #i5 #o3 { -moz-transform: rotate(90deg) translatex(150px); -moz-animation-delay: 0.3s; -webkit-transform: rotate(90deg) translatex(150px); -webkit-animation-delay: 0.3s; } #i5 #o4 { -moz-transform: rotate(120deg) translatex(150px); -moz-animation-delay: 0.4s; -webkit-transform: rotate(120deg) translatex(150px); -webkit-animation-delay: 0.4s; } #i5 #o5 { -moz-transform: rotate(150deg) translatex(150px); -moz-animation-delay: 0.5s; -webkit-transform: rotate(150deg) translatex(150px); -webkit-animation-delay: 0.5s; } #i5 #o6 { -moz-transform: rotate(180deg) translatex(150px); -moz-animation-delay: 0.6s; -webkit-transform: rotate(180deg) translatex(150px); -webkit-animation-delay: 0.6s; } #i5 #o7 { -moz-transform: rotate(210deg) translatex(150px); -moz-animation-delay: 0.7s; -webkit-transform: rotate(210deg) translatex(150px); -webkit-animation-delay: 0.7s; } #i5 #o8 { -moz-transform: rotate(240deg) translatex(150px); -moz-animation-delay: 0.8s; -webkit-transform: rotate(240deg) translatex(150px); -webkit-animation-delay: 0.8s; } #i5 #o9 { -moz-transform: rotate(270deg) translatex(150px); -moz-animation-delay: 0.9s; -webkit-transform: rotate(270deg) translatex(150px); -webkit-animation-delay: 0.9s; } #i5 #o10 { -moz-transform: rotate(300deg) translatex(150px); -moz-animation-delay: 1.0s; -webkit-transform: rotate(300deg) translatex(150px); -webkit-animation-delay: 1.0s; } #i5 #o11 { -moz-transform: rotate(330deg) translatex(150px); -moz-animation-delay: 1.1s; -webkit-transform: rotate(330deg) translatex(150px); -webkit-animation-delay: 1.1s; } #i5 #o12 { -moz-transform: rotate(0deg) translatex(150px); -moz-animation-delay: 1.2s; -webkit-transform: rotate(0deg) translatex(150px); -webkit-animation-delay: 1.2s; } /* illusion 5 */ #i6 { background-color: #3f023e; height: 640px; margin: 0 auto; overflow: hidden; padding-left: 120px; position: relative; width: 900px; } #i6 .yellow { background-color: #b9bd04; background-image: -webkit-radial-gradient(50% 50%, circle, #fff531 40%, #b9bd04 80%); background-image: -moz-radial-gradient(50% 50%, circle, #fff531 40%, #b9bd04 80%); background-image: -o-radial-gradient(50% 50%, circle, #fff531 40%, #b9bd04 80%); background-image: radial-gradient(50% 50%, circle, #fff531 40%, #b9bd04 80%); } #i6 .pink { background-color: #f101e8; background-image: -webkit-radial-gradient(50% 50%, circle, #0e0403 40%, #f101e8 80%); background-image: -moz-radial-gradient(50% 50%, circle, #0e0403 40%, #f101e8 80%); background-image: -o-radial-gradient(50% 50%, circle, #0e0403 40%, #f101e8 80%); background-image: radial-gradient(50% 50%, circle, #0e0403 40%, #f101e8 80%); } #i6 > div { float: left; height: 320px; position: relative; width: 320px; } #i6 .r1 { height: 320px; position: absolute; width: 320px; -webkit-border-radius: 320px; -moz-border-radius: 320px; -ms-border-radius: 320px; -o-border-radius: 320px; border-radius: 320px; } #i6 .r2 { height: 240px; left: 40px; position: absolute; top: 40px; width: 240px; -webkit-border-radius: 240px; -moz-border-radius: 240px; -ms-border-radius: 240px; -o-border-radius: 240px; border-radius: 240px; } #i6 .r3 { height: 160px; left: 40px; position: absolute; top: 40px; width: 160px; -webkit-border-radius: 160px; -moz-border-radius: 160px; -ms-border-radius: 160px; -o-border-radius: 160px; border-radius: 160px; } #i6 .r4 { height: 80px; left: 40px; position: absolute; top: 40px; width: 80px; -webkit-border-radius: 80px; -moz-border-radius: 80px; -ms-border-radius: 80px; -o-border-radius: 80px; border-radius: 80px; } this is very big pack of styles, but i hope that this is ok. i have used several different css3 techniques: and keyframe animation, and transform rotate, and sometimes – gradients. live demo download in package conclusion hope you enjoyed the new demo. don’t forget to give thanks and leave a comment good luck! source: http://www.script-tutorials.com/css3-optical-illusions/
January 5, 2012
by Andrei Prikaznov
· 8,312 Views
article thumbnail
Different SOAP encoding styles – RPC, RPC-literal, and document-literal
SOAP uses XML to marshal data that is transported to a software application. Since SOAP’s introduction, three SOAP encoding styles have become popular and are reliably implemented across software vendors and technology providers: SOAP Remote Procedure Call (RPC) encoding, also known as Section 5 encoding, which is defined by the SOAP 1.1 specification SOAP Remote Procedure Call Literal encoding (SOAP RPC-literal), which uses RPC methods to make calls but uses an XML do-it-yourself method for marshalling the data SOAP document-style encoding, which is also known as message-style or document-literal encoding. There are other encoding styles, but software developers have not widely adopted them, mostly because their promoters disagree on a standard. For example, Microsoft is promoting Direct Internet Message Exchange (DIME) to encode binary file data, while the rest of the world is promoting SOAP with Attachments. SOAP RPC encoding, RPC-literal, and document-style SOAP encoding have emerged as the encoding styles that a software developer can count on. SOAP RPC is the encoding style that offers you the most simplicity. You make a call to a remote object, passing along any necessary parameters. The SOAP stack serializes the parameters into XML, moves the data to the destination using transports such as HTTP and SMTP, receives the response, deserializes the response back into objects, and returns the results to the calling method. Whew! SOAP RPC handles all the encoding and decoding, even for very complex data types, and binds to the remote object automatically. Now, imagine that you have some data already in XML format. SOAP RPC also allows literal encoding of the XML data as a single field that is serialized and sent to the Web service host. This is what’s referred to as RPC-literal encoding. Since there is only one parameter — the XML tree — the SOAP stack only needs to serialize one value. The SOAP stack still deals with the transport issues to get the request to the remote object. The stack binds the request to the remote object and handles the response. Lastly, in a SOAP document-style call, the SOAP stack sends an entire XML document to a server without even requiring a return value. The message can contain any sort of XML data that is appropriate to the remote service. In SOAP document-style encoding, the developer handles everything, including determining the transport (e.g., HTTP, MQ, SMTP), marshaling and unmarshaling the body of the SOAP envelope, and parsing the XML in the request and response to find the needed data. The three encoding systems are compared here: SOAP RPC encoding is easiest for the software developer; however, all that ease comes with a scalability and performance penalty. In SOAP RPC-literal encoding, you are more involved with handling XML parsing, but it requires there to be overhead for the SOAP stack to deal with. SOAP document-literal encoding is most difficult for the software developer, but consequently requires little SOAP overhead. Why is SOAP RPC easier? With this encoding style, you only need to define the public object method in your code once; the SOAP stack unmarshals the request parameters into objects and passes them directly into the method call of your object. Otherwise, you are stuck with the task of parsing through the XML tree to find the data elements you need before you get to make the call to the public method. There is an argument for parsing the XML data yourself: since you know the data in the XML tree best, your code will parse that data more efficiently than generalized SOAP stack code. You will find this when measuring scalability and performance in SOAP encoding styles. References: 1. Discover SOAP encoding’s impact on Web service performance (http://www.ibm.com/developerworks/webservices/library/ws-soapenc/) From http://singztechmusings.wordpress.com/2011/12/20/different-soap-encoding-styles-rpc-rpc-literal-and-document-literal/
January 4, 2012
by Singaram Subramanian
· 49,930 Views · 2 Likes
article thumbnail
Process Related Classic Mistakes
In my last blog I looked a People Related Classic Mistakes from Rapid Development: Taming Wild Software Schedules by Steve McConnell, which although it’s now been around for at least 10 years, and times have changed, is still as relevant today as when it was written. As Steve’s book states, classic mistakes are classic mistakes because they’re mistakes that are made so often and by so many people. They have predictably bad results and, when you know them, they stick out like a sore thumb and the idea behind listing them here is that, once you know them, you can spot them and hopefully do something to remedy their effect. Classic mistakes can be divided in to four types: People Related Mistakes Process Related Mistakes Product Related Mistakes Technology Related Mistakes Today’s blog takes a quick look at the second of Steve’s categories of mistakes: Process Related Mistakes, which include: Overly Optimistic Schedules Insufficient Risk Management Contractor Failure Insufficient Planning Abandonment of Planning Under Pressure Wasted Time During Fuzzy Front End Short-changed Upstream Activities Inadequate Design Shortchanged QA Insufficient Management Controls Premature or Overly Frequent Convergence Omitting Necessary Tasks from Estimates Planning to Catch Up Later Code Like Hell Programming Overly Optimistic Schedules Related to Wishful Thinking. Setting an overly optimistic schedule sets a project up for failure by under-scoping the project, short cutting requirements analysis and testing and failing to appreciate some of the most important development activities. It is a failure to recognise that software takes time to develop. This also has a detrimental affect on staff morale and productivity. Insufficient Risk Management If you don’t manage risks then only one thing has to go wrong to throw your project in to the gutter. Failure to plan for catastrophe and manage risk is a classic mistake. Contractor Failure Contractors frequently deliver work that is late, of low quality and fails to meet specifications - despite the fact that they’re frequently used and well paid! Unstable or ill-defined requirements or interfaces are magnified when a contractor is used. Manage the contractor relationship carefully or else contractors can slow a project down rather than speed it up. Insufficient Planning If you don’t plan to produce good software then how can you produce it. Abandonment of Planning Under Pressure Project teams make plans and then abandon them under pressure - like when they run into schedule trouble. The problem is that plans need to change and adapt. Failing to make new plans and dropping into "Code and Fix" mode is common. Wasted Time During Fuzzy Front End This is the time normally spent before a project commences, seeking approval and budgeting. Keep this stage short and intense saving your self time that can be used later when the project is under way. Shortchanged Upstream Activities Don’t skimp on activities that don’t directly produce code such as Requirements analysis, architecture and design. Do not "jump into coding", fixing bugs later in a project is ten times more costly in terms of time than doing it right in the first place. Inadequate Design A special case of the above - some people just don’t do design, they go straight into coding. Shortchanged QA Projects in a hurry often miss out QA. This includes eliminating design, coding reviews, test planning and performing only very basic testing. Short cutting 1 days QA will cost you 3 to 10 days later. Insufficient Management Controls Controls are needed to provide timely warnings of impeding schedule slips and other problems. Often controls are abandoned when trouble occurs. Premature or Overly Frequent Convergence Tying together all the various bits of the project to make a product (e.g. documentation, code modules and installation program) either too often or too early in the project life cycle can waste time and effort. Omitting Necessary Tasks from Estimates People don’t keep records from previous project, they forget about the less visible tasks. These tasks add up. Omitted effort from the original estimate adds up to 20 to 30 percent of a development schedule. Planning to Catch Up Later When late many projects simply plan to catch up later, but they never do. Re-estimated schedules need to reflect slips and lessons learned in building the product. They also need to reflect changes in the requirements specification. If a new function point is added that requires 3 weeks development, then the schedule slips by 3 weeks. Code Like Hell Programming Or code and fix programming. It is often thought that once a loose requirements specification is defined then well motivated developers can overcome any obstacle using fast loose code as you go techniques. From http://www.captaindebug.com/2011/12/process-related-classic-mistakes.html
January 4, 2012
by Roger Hughes
· 9,270 Views · 2 Likes
article thumbnail
TDD for multithreaded applications
This article describes some practices for test-driving multithreaded and distributed applications written in Java. The example I worked on and we will use is a peer-to-peer application composed of many Nodes (clients) and of a few Supernodes (servers). The ultimate goal it to build an application composed of all these entities, but the first tests target a Supernode serving one or more Nodes. The walking skeleton TDD is mostly iterative, but needs a starting point. The simplest story we can think of is that of a Node connecting to a Supernode. Client and servers usually run in their own threads (in the case of the server, multiple ones), but initially the Node object can just be a POJO and run in the test's thread because we do not need to manage multiple Nodes yet. The Supernode object instead is a Thread (or a Runnable) and so we already face a simplified version of the synchronization problem: how to make sure the Supernode is ready to answer to connections once we have started its thread? The JUnit test is the following: @Test public void aNodeCanConnectToASupernode() throws Exception { Supernode supernode = new Supernode(8888); supernode.start(); supernode.ensureStartupIsFinished(); Node n = new Node(); n.connect("127.0.0.1", 8888); assertEquals(1, supernode.getNodes()); } supernode.start() runs the new thread, while the call to ensureStartupIsFinished() will have to block until the other thread is ready. Then, we create a Node object and tell it to connect; after it has finished this operation, we count how many nodes have connected to the Supernode. To satisfy this test, the Supernode can be a single-threaded server: public class Supernode extends Thread { private int port; private boolean startupCompleted; private int nodes = 0; public Supernode(int port) { this.port = port; this.startupCompleted = false; } public void run() { ServerSocket sock; try { sock = new ServerSocket(this.port); // ...networking setup... synchronized (this) { this.startupCompleted = true; notify(); } while (true) { // ...accepting new connections on sock and other stuff } } public int getNodes() { return nodes; } synchronized public void ensureStartupIsFinished() throws InterruptedException { while (!this.startupCompleted) { wait(); } } } What's in this first example? Thread objects are manageable as POJOs from a single JVM: as long as we write them with this API it will be simple to instantiate and terminate them, and to add primitives for synchronization. The startupCompleted field, which is an example of this synchronization behavior added to the production code. Adding production code just for end-to-end testing purposes is not uncommon. The test thread blocks inside ensureStartupIsFinished() until it is woken up via notification. Even then, startupCompleted must be true or it will wait more. This is Plain Old Java Synchronization: note the synchronized blocks around this.wait() and this.notify(). The problem with frameworks and containers is you have to hope they provide the synchronization facilities to test your code once it's inside them: have you ever tried to wait for Tomcat to start? There are some noticeable missing parts in this code: the threads for each node. The current test does not require them as only one Node is connecting for now. Thread.sleep() calls: at least for the happy paths I have covered until now, I never need to introduce them and considered them a smell. Configuration files: if we had to read configuration, the tests would take really long to write and would refer continuously to external resources. This is the case when testing with external tools which are not embeddable (Tomcat requiring configuration files while Jetty allowing configuration to be passed in Java test code). You can always add file-based configuration later, but for now it will slow us down. Evolution By adding one test at the time with a larger scope, we can try to evolve the code and add the difficult networking, multithreading part one bit at a time. After some iterations, the test becomes: public class FileSharingNetworkTest { Supernode supernode; @Before public void setUp() throws Exception { supernode = new Supernode(8888); supernode.start(); supernode.ensureStartupIsFinished(); } @After public void tearDown() throws Exception { supernode.ensureStop(); } @Test public void aNodeCanConnectToASupernode() throws Exception { Node n = newNode(Arrays.asList("1.txt", "2.txt")); n.ensureConnectionIsFinished(); assertEquals(1, supernode.getNodes()); assertEquals(2, supernode.getDocuments()); } @Test public void multipleNodesCanConnectToASupernodeSimultaneously() throws Exception { Node n1 = newNode(); Node n2 = newNode(); n1.ensureConnectionIsFinished(); n2.ensureConnectionIsFinished(); assertEquals(2, supernode.getNodes()); } private Node newNode() { Node n = new Node("127.0.0.1", 8888); n.start(); n.setDocumentList(Arrays.asList("1.txt", "2.txt")); return n; } private Node newNode(List documentList) { Node n = new Node("127.0.0.1", 8888); n.start(); n.setDocumentList(documentList); return n; } } The server-side code doesn't have multiple threads yet. What is the test case that will call for them? You have to find it and write it. This workflow will ensure that there is a test that targets this case. In my case, it was the first test requiring interaction between the two clients, where one had to see the documents listed by the other after both had connected. Even if you know where you will end up, you can test-drive the implementation: the advantage is that you understand better a standard design and ensure its test coverage. After a few more tests, I have reached a multithreaded server with a main thread and chidren for managing the connections; and Node objects implemented as independent threads. Conclusions When working with TDD at a system scale that includes asynchronous behavior, we should strive for a test suite that is: fast; even with multiple threads to wait for, a single end to end test should take less than a second to complete. Comprehensive; TDD makes us only write tested code instead of copying down snippets from the web. Robust: totally deterministic, as every run will either pass or fail, even when repeated dozens of times. There should be no sleeping calls for all the happy paths; there should be synchronization and stopping facilities built into the system. Featuring unit tests: along with the end to end tests we should write unit tests for the objects we need to extract (and that will be single threaded). It was easy for me to get caught up into covering more and more cases with a full scale test, but unit tests are better at pointing out where a bug resides. We also have to keep in mind how to design our objects and interfaces: not starting with N threads but with at most 1 more than the test's one (the server or a remote peer). Evolving them: adding a few lines of verbose Java networking code each time. My example has evolved to N client threads, a server main thread and N server children threads talking with each client. I will now have to evolve it to a network of supernodes, being this about a file sharing network; to introduce secure channels and certificates. The difficult part is to constantly refactor to support new stories without having to rework the whole system for a single one. Not only extracting methods (an automated operation), but also to extract interfaces and most importantly objects; targeting the longest and complex classes and chopping them down into basic responsibilities.
January 3, 2012
by Giorgio Sironi
· 15,161 Views
article thumbnail
Java: How to Save / Download a File Available at a Particular URL Location on the Internet?
package singz.test; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import org.apache.commons.io.FileUtils; /* * @author Singaram Subramanian */ public class FileDownloadTest { public static void main(String[] args) { // Make sure that this directory exists String dirName = "C:\\FileDownload"; try { System.out.println("Downloading \'Maven, Eclipse and OSGi working together\' PDF document..."); saveFileFromUrlWithJavaIO( dirName + "\\maven_eclipse_and_osgi_working_together.pdf", "http://singztechmusings.files.wordpress.com/2011/09/maven_eclipse_and_osgi_working_together.pdf"); System.out.println("Downloaded \'Maven, Eclipse and OSGi working together\' PDF document."); System.out.println("Downloading \'InnoQ Web Services Standards Poster\' PDF document..."); saveFileFromUrlWithCommonsIO( dirName + "\\innoq_ws-standards_poster_2007-02.pdf", "http://singztechmusings.files.wordpress.com/2011/08/innoq_ws-standards_poster_2007-02.pdf"); System.out.println("Downloaded \'InnoQ Web Services Standards Poster\' PDF document."); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // Using Java IO public static void saveFileFromUrlWithJavaIO(String fileName, String fileUrl) throws MalformedURLException, IOException { BufferedInputStream in = null; FileOutputStream fout = null; try { in = new BufferedInputStream(new URL(fileUrl).openStream()); fout = new FileOutputStream(fileName); byte data[] = new byte[1024]; int count; while ((count = in.read(data, 0, 1024)) != -1) { fout.write(data, 0, count); } } finally { if (in != null) in.close(); if (fout != null) fout.close(); } } // Using Commons IO library // Available at http://commons.apache.org/io/download_io.cgi public static void saveFileFromUrlWithCommonsIO(String fileName, String fileUrl) throws MalformedURLException, IOException { FileUtils.copyURLToFile(new URL(fileUrl), new File(fileName)); } } From http://singztechmusings.wordpress.com/2011/12/20/java-how-to-save-download-a-file-available-at-a-particular-url-location-in-internet/
January 3, 2012
by Singaram Subramanian
· 148,547 Views
article thumbnail
Styling a JavaFX Control with CSS
Change the look and feel of any JavaFX control using CSS.
January 2, 2012
by Toni Epple
· 97,126 Views · 1 Like
article thumbnail
JAXB, SAX, DOM Performance
This post investigates the performance of unmarshalling an XML document to Java objects using a number of different approaches. The XML document is very simple. It contains a collection of Person entities. person0 name0 person1 name1 ... There is a corresponding Person Java object for the Person entity in the XML ... @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "id", "name" }) public class Person { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String value) { this.name = value; } } and a PersonList object to represent a collection of Persons. @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "persons") public class PersonList { @XmlElement(name="person") private List personList = new ArrayList(); public List getPersons() { return personList; } public void setPersons(List persons) { this.personList = persons; } } The approaches investigated were: Various flavours of JAXB SAX DOM In all cases, the objective was to get the entities in the XML document to the corresponding Java objects. The JAXB annotations on the Person and PersonList POJOS are used in the JAXB tests. The same classes can be used in SAX and DOM tests (the annotations will just be ignored). Initially the reference implementations for JAXB, SAX and DOM were used. The Woodstox STAX parsing was then used. This would have been called in some of the JAXB unmarshalling tests. The tests were carried out on my Dell Laptop, a Pentium Dual-Core CPU, 2.1 GHz running Windows 7. Test 1 - Using JAXB to unmarshall a Java File. @Test public void testUnMarshallUsingJAXB() throws Exception { JAXBContext jc = JAXBContext.newInstance(PersonList.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); PersonList obj = (PersonList)unmarshaller.unmarshal(new File(filename)); } Test 1 illustrates how simple the progamming model for JAXB is. It is very easy to go from an XML file to Java objects. There is no need to get involved with the nitty gritty details of marshalling and parsing. Test 2 - Using JAXB to unmarshall a Streamsource Test 2 is similar Test 1, except this time a Streamsource object wraps around a File object. The Streamsource object gives a hint to the JAXB implementation to stream the file. @Test public void testUnMarshallUsingJAXBStreamSource() throws Exception { JAXBContext jc = JAXBContext.newInstance(PersonList.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); StreamSource source = new StreamSource(new File(filename)); PersonList obj = (PersonList)unmarshaller.unmarshal(source); } Test 3 - Using JAXB to unmarshall a StAX XMLStreamReader Again similar to Test 1, except this time an XMLStreamReader instance wraps a FileReader instance which is unmarshalled by JAXB. @Test public void testUnMarshallingWithStAX() throws Exception { FileReader fr = new FileReader(filename); JAXBContext jc = JAXBContext.newInstance(PersonList.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); XMLInputFactory xmlif = XMLInputFactory.newInstance(); XMLStreamReader xmler = xmlif.createXMLStreamReader(fr); PersonList obj = (PersonList)unmarshaller.unmarshal(xmler); } Test 4 - Just use DOM This test uses no JAXB and instead just uses the JAXP DOM approach. This means straight away more code is required than any JAXB approach. @Test public void testParsingWithDom() throws Exception { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(filename); List personsAsList = new ArrayList(); NodeList persons = doc.getElementsByTagName("person"); for (int i = 0; i persons = new ArrayList(); DefaultHandler handler = new DefaultHandler() { boolean bpersonId = false; boolean bpersonName = false; public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("id")) { bpersonId = true; Person person = new Person(); persons.add(person); } else if (qName.equalsIgnoreCase("name")) { bpersonName = true; } } public void endElement(String uri, String localName, String qName) throws SAXException { } public void characters(char ch[], int start, int length) throws SAXException { if (bpersonId) { String personID = new String(ch, start, length); bpersonId = false; Person person = persons.get(persons.size() - 1); person.setId(personID); } else if (bpersonName) { String name = new String(ch, start, length); bpersonName = false; Person person = persons.get(persons.size() - 1); person.setName(name); } } }; saxParser.parse(filename, handler); } The tests were run 5 times for 3 files which contain a collection of Person entities. The first first file contained 100 Person entities and was 5K in size. The second contained 10,000 entities and was 500K in size and the third contained 250,000 Person entities and was 15 Meg in size. In no cases was any XSD used, or any validations performed. The results are given in result tables where the times for the different runs are comma separated. TEST RESULTS The tests were first run using JDK 1.6.26, 32 bit and the reference implementation for SAX, DOM and JAXB shipped with JDK was used. Unmarshall Type 100 Persons time (ms) 10K Persons time (ms) 250K Persons time (ms) JAXB (Default) 48,13, 5,4,4 78, 52, 47,50,50 1522, 1457, 1353, 1308,1317 JAXB(Streamsource) 11, 6, 3,3,2 44, 44, 48,45,43 1191, 1364, 1144, 1142, 1136 JAXB (StAX) 18, 2,1,1,1 111, 136, 89,91,92 2693, 3058, 2495, 2472, 2481 DOM 16, 2, 2,2,2 89,50, 55,53,50 1992, 2198, 1845, 1776, 1773 SAX 4, 2, 1,1,1 29, 34, 23,26,26 704, 669, 605, 589,591 JDK 1.6.26 Test comments The first time unmarshalling happens is usually the longest. The memory usage for the JAXB and SAX is similar. It is about 2 Meg for the file with 10,000 persons and 36 - 38 Meg file with 250,000. DOM Memory usage is far higher. For the 10,000 persons file it is 6 Meg, for the 250,000 person file it is greater than 130 Meg. The performance times for pure SAX are better. Particularly, for very large files. The exact same tests were run again, using the same JDK (1.6.26) but this time the Woodstox implementation of StAX parsing was used. Unmarshall Type 100 Persons time (ms) 10K Persons time (ms) 250K Persons time (ms) JAXB (Default) 48,13, 5,4,4 78, 52, 47,50,50 1522, 1457, 1353, 1308,1317 JAXB(Streamsource) 11, 6, 3,3,2 44, 44, 48,45,43 1191, 1364, 1144, 1142, 1136 JAXB (StAX) 18, 2,1,1,1 111, 136, 89,91,92 2693, 3058, 2495, 2472, 2481 DOM 16, 2, 2,2,2 89,50, 55,53,50 1992, 2198, 1845, 1776, 1773 SAX 4, 2, 1,1,1 29, 34, 23,26,26 704, 669, 605, 589,591 JDK 1.6.26 + Woodstox test comments Again, the first time unmarshalling happens is usually proportionally longer. Again, memory usage for SAX and JAXB is very similar. Both are far better than DOM. The results are very similar to Test 1. The JAXB (StAX) approach time has improved considerably. This is due to the Woodstox implementation of StAX parsing being used. The performance times for pure SAX are still the best. Particularly for large files. The the exact same tests were run again, but this time I used JDK 1.7.02 and the Woodstox implementation of StAX parsing. Unmarshall Type 100 Persons time (ms) 10,000 Persons time (ms) 250,000 Persons time (ms) JAXB (Default) 165,5, 3, 3,5 611,23, 24, 46, 28 578, 539, 511, 511, 519 JAXB(Streamsource) 13,4, 3, 4, 3 43,24, 21, 26, 22 678, 520, 509, 504, 627 JAXB (StAX) 21,1,0, 0, 0 300,69, 20, 16, 16 637, 487, 422, 435, 458 DOM 22,2,2,2,2 420,25, 24, 23, 24 1304, 807, 867, 747, 1189 SAX 7,2,2,1,1 169,15, 15, 19, 14 366, 364, 363, 360, 358 JDK 7 + Woodstox test comments: The performance times for JDK 7 overall are much better. There are some anomolies - the first time the 100 persons and the 10,000 person file is parsed. The memory usage is slightly higher. For SAX and JAXB it is 2 - 4 Meg for the 10,000 persons file and 45 - 49 Meg for the 250,000 persons file. For DOM it is higher again. 5 - 7.5 Meg for the 10,000 person file and 136 - 143 Meg for the 250,000 persons file. Note: W.R.T. all tests No memory analysis was done for the 100 persons file. The memory usage was just too small and so it would have pointless information. The first time to initialise a JAXB context can take up to 0.5 seconds. This was not included in the test results as it only took this time the very first time. After that the JVM initialises context very quickly (consistly < 5ms). If you notice this behaviour with whatever JAXB implementation you are using, consider initialising at start up. These tests are a very simple XML file. In reality there would be more object types and more complex XML. However, these tests should still provide a guidance. Conclusions: The peformance times for pure SAX are slightly better than JAXB but only for very large files. Unless you are using very large files the performance differences are not worth worrying about. The progamming model advantages of JAXB win out over the complexitiy of the SAX programming model. Don't forget JAXB also provides random accses like DOM does. SAX does not provide this. Performance times look a lot better with Woodstox, if JAXB / StAX is being used. Performance times with 64 bit JDK 7 look a lot better. Memory usuage looks slightly higher. From http://dublintech.blogspot.com/2011/12/jaxb-sax-dom-performance.html
December 31, 2011
by Alex Staveley
· 47,488 Views · 4 Likes
article thumbnail
What are the differences between JAXB 1.0 and JAXB 2.0
What are the differences between JAXB 1.0 and JAXB 2.0? JAXB 1.0 only requires JDK 1.3 or later. JAXB 2.0 requires JDK 1.5 or later. JAXB 2.0 makes use of generics and thus provides compile time type safety checking thus reducing runtime errors. Validation is only available during marshalling in JAXB 1.0. Validation is also available during unmarshalling in JAXB 2.0. Termination occurs in JAXB 1.0 when a validation error occurs. In JAXB 2.0 custom ValidationEventHandlers can be used to deal with validation errors. JAXB 2.0 uses annotations and supports bi-directional mapping. JAXB 2.0 generates less code. JAXB 1.0 does not support key XML Schema components like anyAttribute, key, keyref, and unique. It also does not support attributes like complexType.abstract, element.abstract, element.substitutionGroup, xsi:type, complexType.block, complexType.final, element.block, element.final, schema.blockDefault, and schema.finalDefault. In version 2.0, support has been added for all of these schema constructs. References: http://javaboutique.internet.com/tutorials/jaxb/index3.html From http://dublintech.blogspot.com/2011/04/what-are-differences-between-jaxb-10.html
December 30, 2011
by Alex Staveley
· 15,447 Views
article thumbnail
XML Schema to Java - Generating XmlAdapters
In previous posts I have demonstrated how powerful JAXB's XmlAdapter can be when starting from domain objects. In this example I will demonstrate how to leverage an XmlAdapter when generating an object model from an XML schema. This post was inspired by an answer I gave to a question on Stack Overflow (feel free to up vote). XMLSchema (format.xsd) The following is the XML schema that will be used for this example. The interesting portion is a type called NumberCodeValueType. This type has a specified pattern requiring it be a seven digit number. This number can have leading zeros which would not be marshalled by JAXB's default conversion of numbers. NumberFormatter Since JAXB's default number to String algorithm will not match our schema requirements, we will need to write our own formatter. We are required to provide two static methods one that coverts our type to the desired XML format, and another that converts from the XML format. package blog.xmladapter.bindings; public class NumberFormatter { public static String printInt(Integer value) { String result = String.valueOf(value); for(int x=0, length = 7 - result.length(); x XJC Call The bindings file is referenced in the XJC call as: xjc -d out -p blog.xmladapter.bindings -b bindings.xml format.xsd Adapter1 This will cause an XmlAdapter to be created that leverages the formatter: package blog.xmladapter.bindings; import javax.xml.bind.annotation.adapters.XmlAdapter; public class Adapter1 extends XmlAdapter { public Integer unmarshal(String value) { return (blog.xmladapter.bindings.NumberFormatter.parseInt(value)); } public String marshal(Integer value) { return (blog.xmladapter.bindings.NumberFormatter.printInt(value)); } } Root The XmlAdapter will be referenced from the domain object using the @XmlJavaTypeAdapter annotation: package blog.xmladapter.bindings; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "number" }) @XmlRootElement(name = "root") public class Root { @XmlElement(required = true, type = String.class) @XmlJavaTypeAdapter(Adapter1 .class) protected Integer number; public Integer getNumber() { return number; } public void setNumber(Integer value) { this.number = value; } } Demo Now if we run the following demo code: package blog.xmladapter.bindings; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Root root = new Root(); root.setNumber(4); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(root, System.out); } } Output We will get the desired output: 0000004 From http://blog.bdoughan.com/2011/08/xml-schema-to-java-generating.html
December 30, 2011
by Blaise Doughan
· 15,483 Views
article thumbnail
HowTo: Build a VNC Client for the Browser
VNC is just a special case of client-server, though perhaps an especially cool one. Quite a few rising web technologies do robust client-server work extra well (Node.js, WebSockets, etc.) -- and in-browser VNC is nothing new. Here are two (open-source, of course): noVNC is more ambitiously HTML5-duplexed, using WebSockets as well as Canvas. It's quite popular, and has its own 10-page Github wiki. Also supports wss:// encryption. Use this if you want a reliable, battle-tested HTML5 client. (WebSocket fallback is provided by web-socket-js.) vnc.js was written in 24 hours, during LinkedIn's first public Intern Hackday. So of course it hasn't been tested thoroughly, and probably could be written a little more cleanly. But there's something beautifully coherent about an app written in a single session. If the app really does work, then some of the decisions will make a little more sense -- it's possible to get into the developer's mind a little more easily -- and breaking down the code doesn't result in as many 'why did they do this??' moments, because the developers' minds were never far from any part of the project, at any moment during development. vnc.js doesn't use WebSockets (it uses Socket.io instead), but that's fine -- a little less HTML5, a little more slick JavaScript doesn't hurt anyone. Plus the marathoning hackers behind vnc.js put together a sweet little tutorial detailing the decisions made that 24-hour period, emphasizing the rapid thought-process behind the architecture (in clear diagrams), and a very practical abstraction for easier in-browser work with TCP (using Node.js and Socket.io) and RFB. Both packages are worth checking out; the hacking tutorial is a fun read for any web developer interested in coding a VNC client, or even just sophisticated with with different network protocols in the browser.
December 30, 2011
by John Esposito
· 19,914 Views
article thumbnail
JAXB and Joda-Time: Dates and Times
Joda-Time provides an alternative to the Date and Calendar classes currently provided in Java SE. Since they are provided in a separate library JAXB does not provide a default mapping for these classes. We can supply the necessary mapping via XmlAdapters. In this post we will cover the following Joda-Time types: DateTime, DateMidnight, LocalDate, LocalTime, LocalDateTime. Java Model The following domain model will be used for this example: package blog.jodatime; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import org.joda.time.DateMidnight; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; @XmlRootElement @XmlType(propOrder={ "dateTime", "dateMidnight", "localDate", "localTime", "localDateTime"}) public class Root { private DateTime dateTime; private DateMidnight dateMidnight; private LocalDate localDate; private LocalTime localTime; private LocalDateTime localDateTime; public DateTime getDateTime() { return dateTime; } public void setDateTime(DateTime dateTime) { this.dateTime = dateTime; } public DateMidnight getDateMidnight() { return dateMidnight; } public void setDateMidnight(DateMidnight dateMidnight) { this.dateMidnight = dateMidnight; } public LocalDate getLocalDate() { return localDate; } public void setLocalDate(LocalDate localDate) { this.localDate = localDate; } public LocalTime getLocalTime() { return localTime; } public void setLocalTime(LocalTime localTime) { this.localTime = localTime; } public LocalDateTime getLocalDateTime() { return localDateTime; } public void setLocalDateTime(LocalDateTime localDateTime) { this.localDateTime = localDateTime; } } XmlAdapters Since Joda-Time and XML Schema both represent data and time information according to ISO 8601 the implementation of the XmlAdapters is quite trivial. DateTimeAdapter package blog.jodatime; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.joda.time.DateTime; public class DateTimeAdapter extends XmlAdapter{ public DateTime unmarshal(String v) throws Exception { return new DateTime(v); } public String marshal(DateTime v) throws Exception { return v.toString(); } } DateMidnightAdapter package blog.jodatime; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.joda.time.DateMidnight; public class DateMidnightAdapter extends XmlAdapter { public DateMidnight unmarshal(String v) throws Exception { return new DateMidnight(v); } public String marshal(DateMidnight v) throws Exception { return v.toString(); } } LocalDateAdapter package blog.jodatime; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.joda.time.LocalDate; public class LocalDateAdapter extends XmlAdapter{ public LocalDate unmarshal(String v) throws Exception { return new LocalDate(v); } public String marshal(LocalDate v) throws Exception { return v.toString(); } } LocalTimeAdapter package blog.jodatime; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.joda.time.LocalTime; public class LocalTimeAdapter extends XmlAdapter { public LocalTime unmarshal(String v) throws Exception { return new LocalTime(v); } public String marshal(LocalTime v) throws Exception { return v.toString(); } } LocalDateTimeAdapter package blog.jodatime; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.joda.time.LocalDateTime; public class LocalDateTimeAdapter extends XmlAdapter{ public LocalDateTime unmarshal(String v) throws Exception { return new LocalDateTime(v); } public String marshal(LocalDateTime v) throws Exception { return v.toString(); } } Registering the XmlAdapters We will use the @XmlJavaTypeAdapters annotation to register the Joda-Time types at the package level. This means that whenever these types are found on a field/property on a class within this package the XmlAdapter will automatically be applied. @XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(type=DateTime.class, value=DateTimeAdapter.class), @XmlJavaTypeAdapter(type=DateMidnight.class, value=DateMidnightAdapter.class), @XmlJavaTypeAdapter(type=LocalDate.class, value=LocalDateAdapter.class), @XmlJavaTypeAdapter(type=LocalTime.class, value=LocalTimeAdapter.class), @XmlJavaTypeAdapter(type=LocalDateTime.class, value=LocalDateTimeAdapter.class) }) package blog.jodatime; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; import org.joda.time.DateMidnight; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; Demo To run the following demo you will need the Joda-Time jar on your classpath. It can be obtained here: http://sourceforge.net/projects/joda-time/files/joda-time/ package blog.jodatime; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import org.joda.time.DateMidnight; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; public class Demo { public static void main(String[] args) throws Exception { Root root = new Root(); root.setDateTime(new DateTime(2011, 5, 30, 11, 2, 30, 0)); root.setDateMidnight(new DateMidnight(2011, 5, 30)); root.setLocalDate(new LocalDate(2011, 5, 30)); root.setLocalTime(new LocalTime(11, 2, 30)); root.setLocalDateTime(new LocalDateTime(2011, 5, 30, 11, 2, 30)); JAXBContext jc = JAXBContext.newInstance(Root.class); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(root, System.out); } } Output The following is the output from our demo code: 2011-05-30T11:02:30.000-04:00 2011-05-30T00:00:00.000-04:00 2011-05-30 11:02:30.000 2011-05-30T11:02:30.000 From http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html
December 29, 2011
by Blaise Doughan
· 15,812 Views
article thumbnail
Maven's WAR Overlays: How to manage dependencies
If you're stumbling on this post looking for a way to manage dependencies with WAR overlays, please make sure you check out part one of this blog posting to get the background about how to apply and use WAR overlays in your POM file. This post picks up from the last post and it's assumed that you understand how to apply a WAR to an existing master project. Quick recap Why a quick recap? We're going to go into depth on how dependencies and libraries are applied to the master project. In order to have a WAR overlay, you must include the WAR as a dependency to the master project and must be overlayed during the war-plugin package phase. Where do the dependency libraries go? As mentioned in part one of this blog posting, files are placed in their parent's locations if it exists. What this means is that if, in your overlay WAR you have a .jsp file in /WEB-INF/welcome.jsp, the master WAR will then have a file named "welcome.jsp" in the /WEB-INF. Furthermore, if there is already a file named "welcome.jsp", that file will not be overwritten. If we extrapolate this a bit more, the libraries in the /WEB-INF/lib folder from the overlay will be placed inside the /WEB-INF/lib folder of the master project. This is great and all except when different versions of libraries exist causing runtime failures. Good news, there are ways to manage the dependencies in both the overlay WAR and the master project. How to see your main artifact's libraries? In order to determine what libraries are in which artifact, there are two simple ways. First, determine what libraries are in your master WAR. mvn clean package ls -al target/YOUR_ARTIFACT_WAR/WEB-INF/lib NOTE: adding "-DskipTests" when added to the above maven command would skip tests and would make this step a bit faster, though, it is strictly optional Secondly, add the "workDirectory" parameter to the configuration portion of your war-plugin when applying the overlay. Example: target/extract_here In your master project's POM file: ... ... org.apache.maven.plugins maven-war-plugin 2.1.1 target/overlay-war-folder com.yourcompany branded-templates ... ... This additional property will place each overlay's exploded contents into the specified folder to help debug library conflicts. How to exclude dependencies/libraries at build time? It can be a pain to manage the dependencies between each of the overlays, especially if the overlay is not under your development control. One method would be to manage the dependencies within the two POM files by utilizing the "provided" and "optional" dependencies that maven provides. However, if the overlay project can also stand as stand-alone project, this method will not work because the libraries are not considered to be provided or optional when running independently. This is common when trying to test each of the overlays independently. An additional option to control the libraries is to exclude them from the master WAR during the package phase. This is achieved by using the "excludes" parameter in each of the overlay sections. For example, to remove all of the spring libraries, you could exclude "spring*.jar" ... ... org.apache.maven.plugins maven-war-plugin 2.1.1 target/overlay-war-folder com.yourcompany branded-templates WEB-INF/lib/spring*.jar WEB-INF/lib/log4j*.jar ... ... You might start asking yourself, this is going to get complicated really quickly, and you're right, there are other options. Skinny vs Fat WAR Overlays Up until now, all of our overlays have been considered "fat" because they contain all of it's dependencies which get overlaid onto the master WAR file. There is an alternative that is more commonly known as the "skinny WAR". A skinny WAR is a combination between most of this post's tactics. NOTE: The method I am showing you is known as a "skinnier WAR" because the dependency libraries do exist in the overlay's WAR file, however, the classes will be externalized and the libraries can be removed during final packaging of the master project. Achieving the "skinny WAR" First, in the overlay project, during the package phase, tell maven to build the project's classes as an extra artifact in addition to the WAR file. This set of classes will become a jar file which will be used as a second dependency in the master project's POM. In the Overlay's POM file (add to the existing war plugin): ... ... org.apache.maven.plugins maven-war-plugin 2.1.1 true ... ... After successfully installing/deploying the overlay project, we will add the classes/jar file and the WAR dependency to the master project's POM file. In the master project's POM file: com.yourcompany branded-templates war ... ... com.yourcompany branded-templates 1.1 war com.yourcompany branded-templates 1.1 jar classes ... ... And finally, combine the excludes learned in the last example section above to exclude all .jar files from the overlay WAR. ... ... org.apache.maven.plugins maven-war-plugin 2.1.1 target/overlay-war-folder com.yourcompany branded-templates WEB-INF/lib/*.jar ... ... NOTE: Dependencies that exist in the Overlay will need to be added as dependencies to the master project because they have been removed from the overlay's /WEB-INF/lib folder. This is the main known risk of using skinny war overlays Congratulations! You now have a project with limited library conflicts and can better manager the main project and it's stability. Thank you for reading part one and this post, part two. Please feel free too leave comments or questions and I will do my best to answer them in a timely manner. From http://www.ensor.cc/2011/07/mavens-war-overlays-how-to-manage.html
December 29, 2011
by Mike Ensor
· 34,265 Views · 2 Likes
article thumbnail
Mapping Objects to Multiple XML Schemas - Weather Example
I have written previous posts on EclipseLink JAXB (MOXy)'s @XmlPath and external binding file extensions. In this post I will demonstrate how powerful these extensions are by mapping a single object model to two different XML schemas. To make the example more "real", the XML data will come from two different services that provide weather information: Google and Yahoo. Java Model The following domain model will be used for this post: Weather Report package blog.weather; import java.util.List; public class WeatherReport { private String location; private int currentTemperature; private String currentCondition; private List forecast; } Forecast package blog.weather; public class Forecast { private String dayOfTheWeek; private int low; private int high; private String condition; } Google Weather API First we will leverage Google's Weather API. The following URL will be used to access the weather data for Ottawa, Canada: http://www.google.com/ig/api?weather=Ottawa The following is the result of performing the above query at time I was writing this article. I have highlighted the portions of the XML document that we will map to: Java Model - Mapped to Google's XML Schema via Annotations We will map the result of the Google weather API via a combination of standard JAXB and MOXy extension annotations. Weather Report package blog.weather; import java.util.List; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlRootElement(name="xml_api_reply") @XmlType(propOrder={"location", "currentCondition", "currentTemperature", "forecast"}) @XmlAccessorType(XmlAccessType.FIELD) public class WeatherReport { @XmlPath("weather/forecast_information/city/@data") private String location; @XmlPath("weather/current_conditions/temp_f/@data") private int currentTemperature; @XmlPath("weather/current_conditions/condition/@data") private String currentCondition; @XmlPath("weather/forecast_conditions") private List forecast; } Forecast package blog.weather; import org.eclipse.persistence.oxm.annotations.XmlPath; public class Forecast { @XmlPath("day_of_week/@data") private String dayOfTheWeek; @XmlPath("low/@data") private int low; @XmlPath("high/@data") private int high; @XmlPath("condition/@data") private String condition; } Specify MOXy as the JAXB Provider (jaxb.properties) To configure MOXy as your JAXB provider simply add a file named jaxb.properties in the same package as your domain model with the following entry: javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory For more information see: Specifying EclipseLink MOXy as Your JAXB Provider. Demo The following demo code will read the XML data for Google's weather service, and marshal the objects back to XML: package blog.weather; import java.net.URL; import javax.xml.bind.*; public class GoogleDemo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(WeatherReport.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); URL url = new URL("http://www.google.com/ig/api?weather=Ottawa"); WeatherReport weatherReport = (WeatherReport) unmarshaller.unmarshal(url); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(weatherReport, System.out); } } Output Below is the result of running the demo code. The output represents the portion of the XML document that we had mapped to: expand source Yahoo Weather API The following URL will be used to access the weather data for Ottawa using the Yahoo Weather API (3369 is the WOEID for Ottawa): http://weather.yahooapis.com/forecastrss?w=3369 The following is the result of performing the above query at time I was writing this article: http://us.rd.yahoo.com/dailynews/rss/weather/Ottawa__CA/*http://weather.yahoo.com/forecast/CAXX0343_f.html Yahoo! Weather for Ottawa, CA en-us Thu, 08 Sep 2011 10:58 am EDT 60 142 18 http://weather.yahoo.com http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif 45.42 -75.69 http://us.rd.yahoo.com/dailynews/rss/weather/Ottawa__CA/*http://weather.yahoo.com/forecast/CAXX0343_f.html Thu, 08 Sep 2011 10:58 am EDT Current Conditions: Mostly Cloudy, 66 F Forecast: Thu - Partly Cloudy. High: 75 Low: 57 Fri - Partly Cloudy. High: 79 Low: 53 Full Forecast at Yahoo! Weather (provided by The Weather Channel) ]]> CAXX0343_2011_09_09_7_00_EDT Java Model - Mapped to Yahoo's XML Schema via XML Metadata Since we can not supply a second set of mappings to an object model via annotations, we must supply subsequent mappings by leveraging MOXy's XML metadata. By default MOXy's mapping document is used to supplement any annotations that are specified on the model. However, if the xml-mapping-metadata-complete flag is set, then the XML metadata will completely replace the metadata provided by annotations (the annotations for the Google mapping will remain on the POJOs, but the xml-mapping-metadata-complete flag tells MOXy to ignore them). Demo The following demo code will read the XML data for Yahoo's weather service, and marshal the objects back to XML. Due to a MOXy bug regarding unmapped CDATA sections (https://bugs.eclipse.org/357145, this bug has been fixed in EclipseLink 2.3.1), a filtered XMLStreamReader was used to remove it from the XML input: package blog.weather; import java.util.HashMap; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.stream.StreamFilter; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.stream.StreamSource; import org.eclipse.persistence.jaxb.JAXBContextFactory; public class YahooDemo { public static void main(String[] args) throws Exception { Map properties = new HashMap(1); properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "blog/weather/yahoo-binding.xml"); JAXBContext jc = JAXBContext.newInstance(new Class[] {WeatherReport.class}, properties); XMLInputFactory xif = XMLInputFactory.newFactory(); StreamSource xml = new StreamSource("http://weather.yahooapis.com/forecastrss?w=3369"); XMLStreamReader xsr = xif.createXMLStreamReader(xml); xsr = xif.createFilteredReader(xsr, new CDATAFilter()); Unmarshaller unmarshaller = jc.createUnmarshaller(); WeatherReport weatherReport = (WeatherReport) unmarshaller.unmarshal(xsr); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(weatherReport, System.out); } private static class CDATAFilter implements StreamFilter { public boolean accept(XMLStreamReader xsr) { return XMLStreamReader.CDATA != xsr.getEventType(); } } } Output Below is the result of running the demo code. The output represents the portion of the XML document that we had mapped to: From http://blog.bdoughan.com/2011/09/mapping-objects-to-multiple-xml-schemas.html
December 28, 2011
by Blaise Doughan
· 10,331 Views
article thumbnail
The “4+1” View Model of Software Architecture
In November 1995, while working as Lead software architect at Hughes Aircraft Of Canada Philippe Kruchten published a paper entitled: "Architectural Blueprints—The “4+1” View Model of Software Architecture". The intent was to come up with a mechanism to separate the different aspects of a software system into different views of the system. Why? Because different stakeholders always have different interest in a software system. Some aspects of a system are relevant to the Developers; others are relevant to System administrators. The Developers want to know about things like classes; System administrators want to know about deployment, hardware and network configurations and don't care about classes. Similar points can be made for Testers, Project Managers and Customers. Kruchten thought it made sense to decompose architecture into distinct views so stakeholders could get what they wanted. In total there were 5 views in his approach but he decided to call it 4 + 1. We'll discuss why it's called 4 + 1 later! But first, let's have a look at each of the different views. The logical view This contains information about the various parts of the system. In UML the logical view is modelled using Class, Object, State machine and Interaction diagrams (e.g Sequence diagrams). It's relevance is really to developers. The process view This describes the concurrent processes within the system. It encompasses some non-functional requirements such as performance and availability. In UML, Activity diagrams - which can be used to model concurrent behaviour - are used to model the process view. The development view The development view focusses on software modules and subsystems. In UML, Package and Component diagrams are used to model the development view. The physical view The physical view describes the physical deployment of the system. For example, how many nodes are used and what is deployed on what node. Thus, the physical view concerns some non-functional requirements such as scalability and availability. In UML, Deployment diagrams are used to model the physical view. The use case view This view describes the functionality of the system from the perspective from outside world. It contains diagrams describing what the system is supposed to do from a black box perspective. This view typically contains Use Case diagrams. All other views use this view to guide them. Why is it called the 4 + 1 instead of just 5? Well this is because of the special significance the use case view has. When all other views are finished, it's effectively redundant. However, all other views would not be possible without it. It details the high levels requirements of the system. The other views detail how those requirements are realised. 4 + 1 came before UML It's important to remember the 4 + 1 approach was put forward two years before the first the introduction of UML which did not manifest in its first guise until 1997. UML is how most enterprise architectures are modelled and the 4 + 1 approach still plays a relevance to UML today. UML 2.0 has 13 different types of diagrams - each diagram type can be categorised into one of the 4 + 1 views. UML is 4 + 1 friendly! So is it important? The 4 + 1 approach isn't just about satisfying different stakeholders. It makes modelling easier to do because it makes it easier to organise. A typical project will contain numerous diagrams of the various types. For example, a project may contain a few hundred sequence diagrams and several class diagrams. Grouping diagrams of similar types and purpose means there is an emphasis in separating concerns. Sure isn't it just the same with Java? Grouping Java classes of similar purpose and related responsibilities into packages means organisation is better. Similarly, grouping different components into different jar files means organisation is better. Modelling tools will usually support the 4 + 1 approach and this means projects will have templates for how to split the various types of diagrams. In a company when projects follow industry standard templates again it means things are better organised. The 4 + 1 approach also provides a way for architects to be able to prioritise modelling concerns. It is rare that a project will have enough time to model every single diagram possible for an architecture. Architects can prioritise different views. For example, for a business domain intensive project it would make sense to prioritise the logical view. In a project with high concurrency and complex timing it would make sense to ensure the process view gets ample time. Similarly, the 4 + 1 approach makes it possible for stakeholders to get the parts of the model that are relevant to them. References: Architectural Blueprints—The “4+1” View Model of Software Architecture Paper http://www.cs.ubc.ca/~gregor/teaching/papers/4+1view-architecture.pdf Learning UML 2.0 by Russ Miles & Kim Hamilton. O'Reilly From http://dublintech.blogspot.com/2011/05/41-view-model-of-software-architecture.html
December 28, 2011
by Alex Staveley
· 53,932 Views
article thumbnail
Guava Stopwatch
Guava's Stopwatch is another Guava class new to Guava Release 10 (as is Optional, the subject of another recent post). As its name implies, this simple class provides a method to conveniently measure time elapsed between two code points. It has several advantages over use of System.currentTimeMillis() or System.nanoTime(). I don't focus on these advantages here, but the Javadoc documentation for Stopwatch does cover some of these advantages. As is true of many of Guava's classes, one of the endearing features of Stopwatch is its simplicity and appropriately named methods. The class features two constructors, one that takes no arguments (likely to be most commonly used) and one that accepts an customized extension of the Ticker class. Once an instance of Stopwatch is obtained, it's a simple matter of using methods with "obvious" names like start(), stop(), and reset() to control the stopwatch. Any given Stopwatch instance records elapsed time in a cumulative fashion. In other words, you can start and stop the stopwatch multiple times (just don't start an already started stopwatch and don't stop an already stopped stopwatch) and the elapsed time accumulates with each start and stop. If that's not what is wanted and a single instance of the stopwatch is to be used to measure independent events (but not concurrent events), then the reset() method is used between the last run's stop() and the next run's start(). I have already alluded to several caveats to keep in mind when using Guava's Stopwatch. First, two successive start() methods should not be invoked on a given instance of Stopwatch without first stopping it with stop() before making the second call to stop(). Stopwatch has an instance method isRunning() that is useful for detecting a running stopwatch before trying to start it again or even before trying to stop one that has already been stopped or was never started. Most of these issues such as starting the stopwatch twice without stopping it or stopping a stopwatch that is not running or was never started lead to IllegalStateExceptions being thrown. Guava developers make use of their own Preconditions class to ascertain these aberrant conditions and to the throwing of these exceptions. The further implication of this, which is spelled out in the Javadoc documentation, is that Stopwatch is not thread-safe and should be used in a single-thread environment. The methods covered so far handle constructing instances of Stopwatch and managing the stopwatch. However, a stopwatch is almost always useful only when the timed results are available for viewing. The Stopwatch class provides two main methods for accessing elapsed time recorded by the stopwatch instance. One method, elapsedMillis(), is similar to standard Java methods that return milliseconds since epoch time. The big difference here is that Stopwatch is returning milliseconds elapsed between given points in time (start() and stop() calls) versus since an absolute epoch time. I prefer elapsedTime(TimeUnit) for acquiring the elapsed time recorded in my stopwatch instance. This method makes use of the TimeUnit enum (see my post on TimeUnit) to specify the units that the elapsed time should be expressed in. Both of these methods for reporting elapsed time can be run while the stopwatch is running or after it has stopped. The following code listing contains a class that demonstrates the methods on Stopwatch that have been highlighted in this post. StopWatchDemo.java package dustin.examples; import static java.lang.System.out; import com.google.common.base.Stopwatch; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; /** * Demonstrates Guava's (Release 10) Stopwatch class. * * @author Dustin */ public class StopWatchDemo { private final static Logger LOGGER = Logger.getLogger(StopWatchDemo.class.getCanonicalName()); public static void doSomethingJustToBeDoingIt(final int numberOfTimesToDoNothing) { for (int count=0; count < numberOfTimesToDoNothing; count++) { try { Thread.sleep(TimeUnit.SECONDS.toMillis(1)); } catch (InterruptedException interruptEx) { LOGGER.log(Level.INFO, "Don't interrupt me when I'm trying to sleep!", interruptEx); } } } /** * Print statistics on Stopwatch-reported times for provided number of loops. * * @param numberLoops Number of loops executed. * @param stopwatch Stopwatch instance with time used statistics. */ public static void printElapsedTime(final int numberLoops, final Stopwatch stopwatch) { if (stopwatch.isRunning()) { out.println("WARNING! Your stopwatch is still running!"); } else // stopwatch not running { out.println(numberLoops + " loops required: "); out.println("\t" + stopwatch.toString(6)); out.println("\t" + stopwatch.elapsedMillis() + " elapsed milliseconds."); out.println("\t" + stopwatch.elapsedTime(TimeUnit.MINUTES) + " minutes"); out.println("\t" + stopwatch.elapsedTime(TimeUnit.SECONDS) + " seconds"); out.println("\t" + stopwatch.elapsedTime(TimeUnit.MILLISECONDS) + " milliseconds"); out.println("\t" + stopwatch.elapsedTime(TimeUnit.NANOSECONDS) + " nanoseconds"); } } public static void main(final String[] arguments) { final Stopwatch stopwatch = new Stopwatch(); int numberTimes = 5; stopwatch.start(); doSomethingJustToBeDoingIt(numberTimes); stopwatch.stop(); printElapsedTime(numberTimes, stopwatch); numberTimes = 45; stopwatch.reset(); stopwatch.start(); doSomethingJustToBeDoingIt(numberTimes); stopwatch.stop(); printElapsedTime(numberTimes, stopwatch); numberTimes = 125; stopwatch.reset(); stopwatch.start(); doSomethingJustToBeDoingIt(numberTimes); stopwatch.stop(); printElapsedTime(numberTimes, stopwatch); } } When the above code is executed, its output is similar to that shown in the following screen snapshot. If I comment out the lines that reset the stop watch instance, the stopwatch instance accumulates elapsed time rather than tracking it separately. This difference is shown in the next screen snapshot. The Guava Stopwatch class makes it easy to perform simple timing measurements to analyze how long certain operations take. It is easy to use and provides the flexibility to readily provide output in the desired time scale. From http://marxsoftware.blogspot.com/2011/10/guava-stopwatch.html
December 28, 2011
by Dustin Marx
· 28,510 Views · 15 Likes
article thumbnail
How to deploy a neo4j instance in Amazon EC2 in 10 minutes
Neo4j is a high-performance, NOSQL graph database with all the features of a mature and robust database. In this post I will explain how to deploy a neo4j instance in Amazon EC2 web service. For this tutorial to take you no more than 10 minutes you should be able to execute properly some bash commands like mv, tar, ssh and scp (secure copy). I also assume that you have an account in Amazon Web Services and you are familiar to the process of launching instances. If not, I strongly recommend you to follow this starting guide and complete it till you manage to connect to your instance with ssh. Start downloading the latest stable version of neo4j. Which you can find here. The “Community Edition” fits well for development purposes. Do not forget to select the Unix version of the server. This will download a tar.gz file which you will copy to your EC2 instance later. While you download the neo4j server open the AWS Management Console and launch a Basic 32-bit Amazon Linux AMI. If you want to launch an Ubuntu AMI please notice that it doesn’t ship with Java, which is required for running neo4j. If you are not familiar with key pairs, pem files or security groups I insist you to follow the EC2 starting guide I mentioned above. You can either create a new security group or use the default, but you will need to configure a new security rule for the neo4j server port. After launching the instance, create a TCP rule on port 7474 with source 0.0.0.0/0. Here you are opening port 7474 for anyone. If you are planning to use the neo4j REST API and remotely call it from another server, for example a Rails application hosted in Heroku, for security reasons, you may want to change the source field to the address of your Heroku server. Do not forget to open port 22 (SSH), this is typically the first rule normal people create after launching an instance. You are almost done! You should now install neo4j in your instance. Open a terminal in your localhost and navigate to the path where you downloaded neo4j. Copy the file to your Amazon instance by using the scp command: scp -i your_pem_file.pem neo4j-community-1.6.M01-unix.tar.gz ec2-user@YOUR_PUBLIC_INSTANCE_DNS:/home/ec2-user Please notice that you will need to change the path to your pem file, typically placed in ~/.ssh, the filename of the neo4j server you just downloaded and the plublic DNS of your instance. Now connect to your instance with SSH: ssh -i your_pem_file.pem ec2-user@YOUR_PUBLIC_INSTANCE_DNS Untar the neo4j server: tar xvfz neo4j-community-1.6.M01-unix.tar.gz.tar.gz Move it to /usr/local and rename the folder to neo4j: sudo mv neo4j-community-1.6.M01 /usr/local/neo4j Almost done!!! You should now open neo4j-server.properties under the conf directory and add the following line: org.neo4j.server.webserver.address=0.0.0.0 This lines allows anyone to connect remotely to your neo4j database server. Now run the start script. From the neo4j server folder. sudo ./bin/neo4j start Finally, open a browser and access the webadmin interface of your neo4j database by typing http://YOUR_PUBLIC_INSTANCE_DNS:7474. You should see the Neo4j Monitoring and Management Tool, pretty cool! If not, ask me You can now try using the REST API and the curl bash command to insert nodes and relationships. I hope this post helped you, good luck! Follow me on Twitter @negarnil Source: http://www.cloudtmp.com/java/how-to-deploy-a-neo4j-instance-in-amazon-ec2-in-10-minutes/
December 27, 2011
by Nicolas Garnil
· 27,450 Views · 1 Like
article thumbnail
Maven's WAR Overlay: What are WAR Overlays?
Overlays are used to share common resources across multiple web applications.
December 27, 2011
by Mike Ensor
· 64,049 Views · 2 Likes
article thumbnail
Consistent Hashing
Consistent Hashing is a clever algorithm that is used in high volume caching architectures where scaling and availability are important. It is used in many high end web architectures for example: Amazon's Dynamo. Let me try and explain it! Firstly let's consider the problem. Let's say your website sells books (sorry Amazon but you're a brilliant example). Every book has an author, a price, details such as the number of pages and an ISBN which acts as a primary key uniquely identifying each book. To improve the performance of your system you decide to cache the books. You split the cache over four servers. You have to decide which book to put on which server. You want to do this using a deterministic function so you can be sure where things are. You also want to do this at low computational cost (otherwise what's the point caching). So you hash the book's ISBN and then mod the result by the number of servers which in our case is 4. Let's call this number the book's hash key. So let's say your books are: Toward the Light, A.C. Grayling (ISBN=0747592993) Aftershock, Philippe Legrain (ISBN=1408702231) The Outsider, Albert Camus (ISBN=9780141182506) This History of Western Philosophy, Bertrand Russell (ISBN=0415325056) The life you can save, Peter Singer (ISBN=0330454587) ... etc After hashing the ISBN and moding the result by 4, let's say the resulting hash keys are: Hash(Toward the Light) % 4 = 2. Hashkey 2 means this book will be cached by Server 2. Hash(Aftershock) % 4 = 1. Hashkey 1 means this book will be cached by Server 1. Hash(The Outsider) % 4 = 4. Hashkey 1 means this book will be cached by Server 4. Hash(The History of Western Philosophy) % 4 = 1. Hashkey 1 means this book will be cached by Server 1. Hash(The Life you can save) % 4 = 3. Hashkey 1 means this book will be cached by Server 3. Oh wow doesn't everything look so great. Anytime we have a book's ISBN we can work out its hash key and know what server its on! Isn't that just so amazing! Well no. Your website has become so cool, more and more people are using it. Reading has become so cool there are more books you need to cache. The only thing that hasn't become so cool is your system. Things are slowing down and you need to scale. Vertical scaling will only get you so far; you need to scale horizontally. Ok, so you go out and you buy another 2 servers thinking this will solve your problem. You now have six servers. This is where you think the pain will end but alas it won't. Because you know have 6 servers your algorithm changes. Instead of moding by 4 you mod by 6. What does this mean? Initially, when you look for a book because your moding by 6 you'll end up with a different hash key for it and hence a different server to look for it on. It won't be there and you'll have incurred a database read to bring it back into the cache. It's not just one book, it will be the for the majority of your books. Why? Because the only time a book will be on the correct server and not need to be re-read from the database is when the hash(isbn) % 4 = hash(isbn) % 6. Mathematically this will be the minority of your books. So, your attempt at scaling has put a burden on there majority of your cache to restructure itself resulting in massive database re-reads. This can bring your system down. Customers won't be happy with you sunshine! We need a solution! The solution is to come up with a system where when you add more servers and only a small minority will change books will move to new servers meaning a minimum number of database reads. Let's go for it! Consistent Hashing explained Consistent hashing is an approach where the books get the same hash key irrespective of the number of books and irrespective of the number of servers - unlike our previous algorithm which mod'ed by the number of servers. It doesn't matter if there is one server, 5 servers or 5 million servers, the books always always always always get the same hash key. So how exactly do we generate consistent hash values for the books? Simple. We use a similar approach to our initial approach except we stop moding on the number of servers. Instead we mod by something else, that is constant and independent of the number of servers. Ok, so let's hash the ISBN as before and then mod by 100. So if you have 1,000 books. You end up with a distribution of hash keys for the books between 0 - 100 irrespective of the number of servers. All good. All we need is a way to figure determinstically and at low computational cost which books reside on which servers. Otherwise again what would be the point in caching? So here's the ultra funky part... You take something unique and constant for each server (for example its IP address) and you pass that through the exact same algorithm. This means you also end up with a hash key (in this case a number between 0 and 100) for each server. Let's say: Server 1 gets: 12 Server 2 gets: 37 Server 3 gets: 54 Server 4 gets: 87 Now we assign each server to be responsible for caching the books with hash keys between its own hash key and that of the next neighbour (next in the upward direction). This means: Server 1 stores all the books with hash key between 12 and 37 Server 2 stores all the books with hash key between 37 and 54 Server 3 stores all the books with hash key between 54 and 87 Server 4 stores all the books with hash key between 87 and 100 and 0 and 12. If you are still with me... great. Because now we are going to scale. We are going to add two more servers. Lets say server 5 is added and gets the hash key 20. And server 6 is added and gets the hash value 70. This means: Server 1 will now only store books with hash key between 12 and 20 Server 5 will stores the books with hash key between 20 and 37. Server 3 will now only store books with hash key between 54 and 70. Server 6 will stores books with the hash key between 70 and 87. Server 2 and Server 4 are completly unaffected. Ok so this means: All books still get the same hash key. Their hash keys are consistent. Books with hash keys between 20 and 37 and between 70 and 87 are now sought from new servers. The first time they are sought they won't be there and they will be re-read from the system and then cached in the respective servers. This is ok as long as it's only for a small amount of books. There is a small initial impact to the system but its managable. Now, you're probably saying: "I get all this but I'd like to see some better distribution. When you added two servers, only two servers got their load lessoned. Could you share the benefits please?" Of course. To do that, we allocate each server a number of small ranges rather than just one large range. So, instead of server 2 getting one large range between 37 and 54. It gets a number of small ranges. So for example, if could get: 5 - 8, 12 - 17, 24 - 30, 43 - 49, 58 - 61, 71 - 74, 88 - 91. Same for all servers. The small ranges all randomly spread meaning that one server won't just have one adjacent neighbour but a collection of different neighbours for each of its small ranges. When a new server is added it will also get a number if ranges, and number of different neighbours which means its benefits will be distributed more evenly. Isn't that so cool! Consistent hashing benefits aren't just limited to scaling. They also are brilliant for availability. Let's say server 2 goes offlines. What happens is the complete opposite to what happens for when a new server is added. Each one of Server 2 segments will become the responsibility of the server who is responsible for the preceeding segment. Again, if servers are getting a fair distribution of ranges they are responsible for it means when a server fails, the burden will be evenly distributed amongst the remaining servers. Again the point has to emphasised, the books never have to rehashed. Their hashes are consistent. References http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html http://www.tomkleinpeter.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/ http://michaelnielsen.org/blog/consistent-hashing/ From http://dublintech.blogspot.com/2011/06/consistent-hashing.html
December 27, 2011
by Alex Staveley
· 25,956 Views · 16 Likes
  • Previous
  • ...
  • 1576
  • 1577
  • 1578
  • 1579
  • 1580
  • 1581
  • 1582
  • 1583
  • 1584
  • 1585
  • ...
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×