十一月 28

http://codegeekz.com/jquery-mobile-plugins/

The Mobile Internet is rapidly growing and not everything which is displayed on a PC site can adequately fit onto a mobile web page. Effective design graphics for mobile devices is a challenge, and one can no longer develop for a one size ( PC ) screen resolution, since graphics on mobile devices are very different from desktop devices, and there are several complexities of working within mobile technology.

The greatest challenge which developers encounter for effective Website Design is being able to produce a “Mobile Version” of the particular website since mobile phones with internet facilities have rapidly become all too common and therefore – every mobile user wants to have web access on the go.

Developing for the mobile web has been ignited in most part by user demand and this requires that Mobile developers have to push the envelope further when it comes to applications and functionality.

User expectation for a great mobile experience is the new standard when it comes to Mobile Development – and Jquery is paving the way for UX professionals within applying their skills to cover all of the nuances of the mobile UX for the vast array of devices out there. Below is a list of 15 Jquery Plugins which are empowering the mobile environment.

1. Mobiscroll

mobile-scroll
Mobiscroll is a wheel scroller/Date and Time picker jQuery plugin for touch devices (Android phones, iPhone, iPad, Galaxy Tab). The control can easily be customized to support any custom values and can even be used as an intuitive alternative to the native select control (dropdown list). The control is themable. You can easily change the appearance of if in CSS. It also comes with pre-defined, nice looking color schemes. It has been tested on iOS4, Android 2.2, Android 2.3, Chrome, Safari, Firefox, IE9.
 
Source  

2. Ion.Sound

ionsound
Ion.Sound is a jQuery plugin for playing sounds on events. It has been tested on Google Chrome, Mozilla Firefox, Opera, Safari, IE(9.0+) and mobile browsers. Ion.Sound freely distributed under terms of MIT licence.
 
Source  

3. jQuery Mmenu

jquery mmenu
jQuery.mmenu is a slick plugin that brings the same behavior into any -mobile- web layout. It transforms unordered lists with unlimited sub-lists into menu items and has multiple options for customization. The options include the position of the menu (left/right), if a counter for the menu items will be displayed or not and more. jQuery.mmenu can also be controlled (opening, closing and toggling the menu) with simple functions.
 
Source  

4. Naver

Naver
Naver is a jQuery plugin for responsive navigation. It is an easy way to turn any navigation system into a responsive-ready, mobile-friendly toggle. The navigation states can be also be animated. It has been tested in Firefox, Chrome, Safari, IE7+. It is released under the MIT License. Feel free to use it in personal and commercial projects.
 
Source  

5. iosOverlay.js

iosOverlay
iosOverlay.js is iOS-style overlays/notifications for the web. It has been tested on IE7+, Google Chrome, Firefox, Opera, Desktop Safari, Mobile Safari — iPhone & iPad. To prevent icon flickers as they load, you have to preload image resources. Spin.js is required if you want to use a spinner object. And jQuery is required for a fallback CSS animation support.
 
Source  

6. Easy Responsive Tabs

responsive
Easy responsive tabs is a lightweight jQuery plugin which optimizes normal horizontal or vertical tabs to accordion on multi devices like: web, tablets, Mobile (IPad & IPhone). This plugin adapts the screen size and changes its form accordingly. It supports Horizontal / Vertical Tabs to Accordion. Tabs and accordion are created entirely with jQuery. It supports multiple sets of tabs on same page. It has been tested on IE7+, Chrome, Firefox, Safari and Opera. It is released under MIT License.
 
Source  

7. HideShow Password

hide-show-password-plugin
Hide/show Password plugin lets you easily hide and reveal the contents of a password input field. The coolest part about this plugin is the “innerToggle” option. When true, it will create a nifty hide/show control you can style as you like. It even maintains the input focus when tapped in a touch browser.
 
Source  

8. Swipebox

swipebox
Swipebox is a touchable jQuery lightbox. It is a jQuery “lightbox” plugin for desktop, mobile and tablet. It supports Swipe gestures for mobile, Keyboard Navigation for desktop, CSS transitions with jQuery fallback, Retina support for UI icons, and Easy CSS customization. It has been tested on Chrome, Safari, Firefox, Opera, IE8+, IOS4+, Android, windows phone. It is released under MIT License.
 
Source  

9. App Folder

jquery-app-folder
We all know the iOS folder interface: “clicking a folder changing the opacity of other elements and displaying the contents inside a sliding element”. App-Folders is a jQuery that mimics that behavior and works on both desktop + mobile browsers. Folders can include any HTML element (images, text, video ,etc.) and each folder gets its own URL that makes direct-linking possible. The look/feel doesn’t have to be iOS-like but it can be themed completely for creating attractive layouts.
 
Source  

10. jQuery Flip

Jquery flip
jQuery/jQuery mobile plugin to give Flipboard app like effect. Flip effect uses css 3d transform. Flip effect currently works on WebKit browsers (e.g. Chrome, Safari, including iOS mobile safari) or Firefox 11. It still works with other browsers but the “slide” effect will be selected forecely.
 
Source  

11. Google Maps

googlemap
The Google Map version 3 plugin for jQuery and jQM takes away some of the head aches from working with the Google Map API. Instead of having to use Google event listeners for simple events like click, you can use jQuery click events on the map and markers. It is also very flexible, highly customizable, lightweight (3.2kB or 3.9kB for the full) and works out of the box with jQuery mobile. But one of its best features (atleast for SEO people) is that you can populate a map from microformats, RDFa or microdata on your site, which can be used as a fallback when a user doesn’t have javascript enabled.
 
Source  

12. gShake

gshake
This is a jQuery Plugin that enables you to attach a function to a “Shake Event” for devices with iOS 4.2+
 
Source  

13. jQTouch

jqtouch
jQTouch is a jQuery plugin for mobile web development on forward-thinking devices. You can create powerful mobile apps with just HTML, CSS, and jQuery. It supports native animations, automatic navigation, and themes for mobile WebKit browsers like iPhone, G1, and Pre. jQTouch requires one basic theme to make page transitions work which is very small. One could use just the core CSS file to build a completely custom UI. Themes are additional CSS files which provide native-looking styles, mostly centered around the iPhone OS. Themes included are: Apple, jQT and Vanilla.
 
Source  

14. PhotoSwipe

PhotoSwipe
PhotoSwipe is a free and full-featured image gallery for mobile and touch devices. It is built with HTML, CSS + JavaScript and doesn’t depend on any frameworks. The interface is native-like and offers a similar experience with the ability of swiping items and support for orientation (also, resizes images automatically). PhotoSwipe works in iPhone, iPad, Android, Blackberry + desktop browsers and there is an optional jQuery implementation for the users of this framework.
 
Source  

15. Touch Gallery

touch-gallery
Touch Gallery is a jQuery image gallery plugin which brings the native look and feel of native photo-viewing applications to the mobile browsers. It supports browsing through the images with gestures and also works with desktop browsers with limited functionality. The gallery depends on two other plugins: transform and activity-indicator where both is included in the download package.
 
Source

十一月 22

http://java.dzone.com/articles/enterprise-spring-best?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+javalobby%2Ffrontpage+%28Javalobby+%2F+Java+Zone%29

Project Directories

Production

  • src/main/java – Java Source code packages and classes
  • src/main/resources – NON-Java Resources, such as property files and Spring configuration

Test

  • src/test/java – Test Source code packages and classes
  • src/test/resources – NON-Java Resources, such as property files and Spring configuration

Project Structure Example

01.── pom.xml
02.└── src
03.├── main
04.│   ├── java
05.│   │   └── com
06.│   │       └── gordondickens
07.│   │           └── sample
08.│   │               ├── domain
09.│   │               │   └── MyDomain.java
10.│   │               ├── repository
11.│   │               │   └── MyDomainRepository.java
12.│   │               ├── service
13.│   │               │   ├── MyDomainService.java
14.│   │               │   └── internal
15.│   │               │       └── MyDomainServiceImpl.java
16.│   │               └── web
17.│   │                   └── MyDomainController.java
18.│   ├── resources
19.│   │   ├── META-INF
20.│   │   │   └── spring
21.│   │   │       ├── applicationContext.xml
22.│   │   │       └── database.properties
23.│   │   ├── logback-access.xml
24.│   │   └── logback.xml
25.│   └── webapp
26.│       ├── WEB-INF
27.│       │   ├── classes
28.│       │   ├── i18n
29.│       │   ├── layouts
30.│       │   ├── spring
31.│       │   │   └── webmvc-config.xml
32.│       │   ├── views
33.│       │   │   ├── myDomain
34.│       │   │   │   ├── create.jsp
35.│       │   │   │   ├── list.jsp
36.│       │   │   │   ├── show.jsp
37.│       │   │   │   └── update.jsp
38.│       │   │   ├── dataAccessFailure.jsp
39.│       │   │   ├── index.jsp
40.│       │   │   ├── resourceNotFound.jsp
41.│       │   │   ├── uncaughtException.jsp
42.│       │   │   └── views.xml
43.│       │   └── web.xml
44.│       ├── images
45.│       └── styles
46.├── site
47.│   ├── apt
48.│   ├── fml
49.│   ├── site.xml
50.│   └── xdoc
51.└── test
52.├── java
53.│   └── com
54.│       └── gordondickens
55.│           └── sample
56.│               └── service
57.│                   └── MyDomainServiceTests.java
58.└── resources
59.├── com
60.│   └── gordondickens
61.│       └── sample
62.│           └── service
63.│               └── MyDomainServiceTests-context.xml
64.└── logback-test.xml

 

Project Dependencies


I am a big fan of Maven, it provides a consistent build structure and numerous plugins. Gradle is emerging as an alternative Groovy-based build tool, which supports the Maven structure. If you are still using Ant, I urge you to move to a more robust build tool such as Maven or Gradle. One of the challenges of enterprise build tools is managing transitive dependencies, here are some recommendations to ease these challenges. Dependency Versions

  • DO NOT put version numbers below the <properties/> section, this will make it easier to upgrade and test newer versions.
  • DO include version numbers for ALL plugins! Do not rely on Maven’s built in Super Pom plugin versions!

Dependency Management

  • USE Maven’s <DependencyManagement> section to control implicit and explicit versions! Transitive dependencies will be resolved by those included in this section.

Enforcer Plugin

Prohibit the direct or indirect inclusion of incompatible and/or legacy jars. For example, SLF4J 1.5 and SLF4J 1.6 do not work together, therefore we need to prohibit the project from building with mixed dependency versions. Spring is used by many open source projects, some reference older versions of Spring jars, so we want to control which Spring jar versions are inluded in our build.

Enforcer Example

  • Ensures Java 1.6
  • Ensures Maven 2.2.1 to 3.0.x
  • Ensures Spring Jars 3.1 or greater
  • Prohibits old javassist, should be org.javassist
  • Ensures no commons-logging, use SLF4J and Logback
  • Ensures no log4j, use SLF4J and Logback
  • Ensures no SLF4J 1.5, use SLF4J 1.6 and Logback
  • Prohibits old hsqldb, should be org.hsqldb
  • Prohibits old aspectj, should be org.aspectj
01.<properties>
02....
03.<java.version>1.6</java.version>
04....
05.<maven.enforcer.plugin>1.0.1</maven.enforcer.plugin>
06.<maven.version.range>[2.2.1,3.1.0)</maven.version.range>
07....
08.</properties>
09. 
10.<plugin>
11.<groupId>org.apache.maven.plugins</groupId>
12.<artifactId>maven-enforcer-plugin</artifactId>
13.<version>${maven.enforcer.plugin}</version>
14.<executions>
15.<execution>
16.<id>enforce-banned-dependencies</id>
17.<goals>
18.<goal>enforce</goal>
19.</goals>
20.<configuration>
21.<rules>
22.<bannedDependencies>
23.<searchTransitive>true</searchTransitive>
24.<excludes>
25.<exclude>javassist:javassist</exclude>
26.<exclude>commons-logging</exclude>
27.<exclude>aspectj:aspectj*</exclude>
28.<exclude>hsqldb:hsqldb</exclude>
29.<exclude>log4j:log4j</exclude>
30.<exclude>org.slf4j:1.5*</exclude>
31.<exclude>org.springframework:2.*</exclude>
32.<exclude>org.springframework:3.0.*</exclude>
33.</excludes>
34.</bannedDependencies>
35.<requireMavenVersion>
36.<version>${maven.version.range}</version>
37.</requireMavenVersion>
38.<requireJavaVersion>
39.<version>${java.version}</version>
40.</requireJavaVersion>
41.</rules>
42.<fail>true</fail>
43.</configuration>
44.</execution>
45.</executions>
46.</plugin>

 

Smart Logging

  • NEVER use System.out
  • NEVER use System.err
  • ALWAYS use SLF4J
  • ALWAYS use Logback
  • Prohibit Apache Commons Logging (JCL) aka Jakarta Commons Logging
  • Prohibit Java Util Logging (JUL)

Classes that use logging should include the following config for SLF4J (not log4j, not jcl, not jul, not logback):

1.import org.slf4j.Logger;
2.import org.slf4j.LoggerFactory;
3....
4.public class MyClass {
5.private static final Logger logger =
6.LoggerFactory.getLogger(MyClass.class);
7....
8.}

In the example below, SLF4J provides jars to route JCL and JUL logging through jcl-over-slf4j and jul-to-slf4j. Spring uses JCL, so we need to use jcl-over-slf4j to handle Spring specific logged messages.

01.<properties>
02....
03.<logback.version>1.0.6</logback.version>
04....
05.<slf4j.version>1.6.6</slf4j.version>
06....
07.</properties>
08. 
09....
10. 
11.<dependencies>
12....
13.<dependency>
14.<groupId>org.slf4j</groupId>
15.<artifactId>jcl-over-slf4j</artifactId>
16.</dependency>
17.<dependency>
18.<groupId>org.slf4j</groupId>
19.<artifactId>jul-to-slf4j</artifactId>
20.</dependency>
21.<dependency>
22.<groupId>ch.qos.logback</groupId>
23.<artifactId>logback-classic</artifactId>
24.</dependency>
25....
26.</dependencies>
27. 
28....
29. 
30.<dependencyManagement>
31.<dependencies>
32....
33.<!-- Logging with SLF4J & LogBack -->
34.<dependency>
35.<groupId>org.slf4j</groupId>
36.<artifactId>jcl-over-slf4j</artifactId>
37.<version>${slf4j.version}</version>
38.</dependency>
39.<dependency>
40.<groupId>org.slf4j</groupId>
41.<artifactId>slf4j-api</artifactId>
42.<version>${slf4j.version}</version>
43.</dependency>
44.<dependency>
45.<groupId>org.slf4j</groupId>
46.<artifactId>jul-to-slf4j</artifactId>
47.<version>${slf4j.version}</version>
48.</dependency>
49.<dependency>
50.<groupId>ch.qos.logback</groupId>
51.<artifactId>logback-classic</artifactId>
52.<version>${logback.version}</version>
53.</dependency>
54.<dependency>
55.<groupId>ch.qos.logback</groupId>
56.<artifactId>logback-core</artifactId>
57.<version>${logback.version}</version>
58.</dependency>
59.<dependency>
60.<groupId>ch.qos.logback</groupId>
61.<artifactId>logback-access</artifactId>
62.<version>${logback.version}</version>
63.</dependency>
64....
65.</dependencies>
66.</dependencyManagement>

Logging Configuration Files

  • src/main/resources/logback.xml
    01.<?xml version="1.0" encoding="UTF-8"?>
    02.<configuration>
    03. 
    04.<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
    05.<resetJUL>true</resetJUL>
    06.</contextListener>
    07. 
    08.<!-- To enable JMX Management -->
    09.<jmxConfigurator/>
    10. 
    11.<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    12.<encoder>
    13.<pattern>%.-1level|%-40.40logger{0}|%msg%n</pattern>
    14.</encoder>
    15.</appender>
    16. 
    17.<logger name="com.mycompany.myapp" level="debug" />
    18.<logger name="org.springframework" level="info" />
    19. 
    20.<logger name="org.springframework.beans" level="debug" />
    21. 
    22.<root level="warn">
    23.<appender-ref ref="console" />
    24.</root>
    25.</configuration>
  • src/main/resources/logback-access.xml

Configuration for server access logs. HTTPRequest and HTTPResponses messages can be displayed and/or logged When used with Logback TeeFilter in web.xml – GREAT for RESTful testing.

NOTE: Using ${user.dir}, the log files will be created in the root of the project. We will want to configure this differently for production.

01.<?xml version="1.0" encoding="UTF-8"?>
02.<configuration>
03.<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
04. 
05.<filter class="ch.qos.logback.access.filter.CountingFilter">
06.<name>countingFilter</name>
07.</filter>
08. 
09.<appender name="accessfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
10.<file>${user.dir}/logs/app-access.log</file>
11.<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
12.<fileNamePattern>${user.dir}/logs/app-access.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
13.</rollingPolicy>
14. 
15.<encoder>
16.<pattern>combined</pattern>
17.</encoder>
18.</appender>
19. 
20.<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
21.<encoder>
22.<pattern>%n%fullRequest%n%fullResponse%n</pattern>
23.</encoder>
24.</appender>
25. 
26.<appender name="reqrespfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
27.<file>${user.dir}/logs/app-req-resp.log</file>
28.<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
29.<fileNamePattern>${user.dir}/logs/app-req-resp.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
30.</rollingPolicy>
31. 
32.<encoder>
33.<pattern>%n%fullRequest%n%fullResponse%n</pattern>
34.</encoder>
35.</appender>
36. 
37.<appender-ref ref="accessfile" />
38.<appender-ref ref="reqrespfile" />
39.<appender-ref ref="console" />
40.</configuration>

 

Running with Jetty and Tomcat


Developers can run Jetty or Tomcat for testing with the following Maven plugin configuration. The plugin configuration below configures the servers for JMX, SLF4J, Logback and Logback Access. Running Jetty

1.$ mvn clean install jetty:run

Running Tomcat 7

1.$ mvn clean install tomcat7:run

NOTE: DO NOT use tomcat:run, this is the old Tomcat plugin.

001.<properties>
002....
003.<maven.jetty.plugin>8.1.3.v20120416</maven.jetty.plugin>
004....
005.<maven.tomcat.plugin>2.0-beta-1</maven.tomcat.plugin>
006....
007.</properties>
008. 
009....
010. 
011.<plugins>
012....
013.<plugin>
014.<groupId>org.apache.tomcat.maven</groupId>
015.<artifactId>tomcat7-maven-plugin</artifactId>
016.<version>${maven.tomcat.plugin}</version>
017.<configuration>
018.<systemProperties>
019.<com.sun.management.jmxremote>true</com.sun.management.jmxremote>
020.<com.sun.management.jmxremote.port>8050</com.sun.management.jmxremote.port>
021.<com.sun.management.jmxremote.ssl>false</com.sun.management.jmxremote.ssl>
022.<com.sun.management.jmxremote.authenticate>false</com.sun.management.jmxremote.authenticate>
023.<java.util.logging.manager>org.apache.juli.ClassLoaderLogManager</java.util.logging.manager>
024.<logback.ContextSelector>JNDI</logback.ContextSelector>
025.</systemProperties>
026.</configuration>
027.<dependencies>
028.<dependency>
029.<groupId>org.slf4j</groupId>
030.<artifactId>jcl-over-slf4j</artifactId>
031.<version>${slf4j.version}</version>
032.<scope>runtime</scope>
033.</dependency>
034.<dependency>
035.<groupId>org.slf4j</groupId>
036.<artifactId>slf4j-api</artifactId>
037.<version>${slf4j.version}</version>
038.<scope>runtime</scope>
039.</dependency>
040.<dependency>
041.<groupId>org.slf4j</groupId>
042.<artifactId>jul-to-slf4j</artifactId>
043.<version>${slf4j.version}</version>
044.<scope>runtime</scope>
045.</dependency>
046.<dependency>
047.<groupId>ch.qos.logback</groupId>
048.<artifactId>logback-classic</artifactId>
049.<version>${logback.version}</version>
050.<scope>runtime</scope>
051.</dependency>
052.<dependency>
053.<groupId>ch.qos.logback</groupId>
054.<artifactId>logback-access</artifactId>
055.<version>${logback.version}</version>
056.<scope>runtime</scope>
057.</dependency>
058.</dependencies>
059.</plugin>
060.<plugin>
061.<groupId>org.mortbay.jetty</groupId>
062.<artifactId>jetty-maven-plugin</artifactId>
063.<version>${maven.jetty.plugin}</version>
064.<configuration>
065.<webAppConfig>
066.<contextPath>/${project.name}</contextPath>
067.</webAppConfig>
068.<stopPort>9966</stopPort>
069.<stopKey>shutterdown</stopKey>
070.<requestLog implementation="ch.qos.logback.access.jetty.RequestLogImpl">
071.<fileName>./src/main/resources/logback-access.xml</fileName>
072.</requestLog>
073.<systemProperties>
074.<systemProperty>
075.<name>logback.configurationFile</name>
076.<value>./src/main/resources/logback.xml</value>
077.</systemProperty>
078.<systemProperty>
079.<name>com.sun.management.jmxremote</name>
080.<value>true</value>
081.</systemProperty>
082.<systemProperty>
083.<name>com.sun.management.jmxremote.port</name>
084.<value>8050</value>
085.</systemProperty>
086.<systemProperty>
087.<name>com.sun.management.jmxremote.ssl</name>
088.<value>false</value>
089.</systemProperty>
090.<systemProperty>
091.<name>com.sun.management.jmxremote.authenticate</name>
092.<value>false</value>
093.</systemProperty>
094.</systemProperties>
095.</configuration>
096.<dependencies>
097.<dependency>
098.<groupId>org.slf4j</groupId>
099.<artifactId>jcl-over-slf4j</artifactId>
100.<version>${slf4j.version}</version>
101.<scope>runtime</scope>
102.</dependency>
103.<dependency>
104.<groupId>org.slf4j</groupId>
105.<artifactId>slf4j-api</artifactId>
106.<version>${slf4j.version}</version>
107.<scope>runtime</scope>
108.</dependency>
109.<dependency>
110.<groupId>org.slf4j</groupId>
111.<artifactId>jul-to-slf4j</artifactId>
112.<version>${slf4j.version}</version>
113.<scope>runtime</scope>
114.</dependency>
115.<dependency>
116.<groupId>ch.qos.logback</groupId>
117.<artifactId>logback-classic</artifactId>
118.<version>${logback.version}</version>
119.<scope>runtime</scope>
120.</dependency>
121.<dependency>
122.<groupId>ch.qos.logback</groupId>
123.<artifactId>logback-access</artifactId>
124.<version>${logback.version}</version>
125.<scope>runtime</scope>
126.</dependency>
127.</dependencies>
128.</plugin>
129....
130.</plugins>

Logback web.xml Helpers

To see Logback status, optionally add the following Logback Status servlet.

01....
02.<servlet>
03.<servlet-name>ViewStatusMessages</servlet-name>
04.<servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
05.</servlet>
06. 
07.<servlet-mapping>
08.<servlet-name>ViewStatusMessages</servlet-name>
09.<url-pattern>/logbackStatus</url-pattern>
10.</servlet-mapping>
11....

To capture the HTTPRequest and HTTPResponse data use the Logback Tee Filter.

01....
02.<filter>
03.<filter-name>TeeFilter</filter-name>
04.<filter-class>ch.qos.logback.access.servlet.TeeFilter</filter-class>
05.</filter>
06. 
07.<filter-mapping>
08.<filter-name>TeeFilter</filter-name>
09.<url-pattern>/*</url-pattern>
10.</filter-mapping>
11....

 

Spring Configuration Files


Be consistent with naming Spring xml configuration files. Start all files with the same name such as applicationConfig*.xml.

For example: applicationConfig-bootstrap.xml, applicationConfig-jpa.xml, applicationConfig-security.xml, etc.

In the next blog, I will discuss Enterprise Spring configuration best practices.

Config Directories

  • src/main/resources/META-INF/spring – Spring XML configuration directory
  • src/main/webapp/WEB-INF/spring – Spring MVC configuration directory

 

Complete Maven Config


The Best Practices Maven Config file is tuned for Spring application dependencies, reporting and plugin support.

Features of the Best Practices Maven Config file:

  • All versions in properties section
  • Dependency Management section controls transitive dependencies
  • All plugins defined with versions in Plugin Management section
  • Enforcer plugin stops build for incompatible dependencies
  • Maven Site plugin configured for reporting, with common reporting plugins
  • Eclipse plugin uses new Eclipse brand Maven plugin, formerly Sonatype’s
  • Idea (IntelliJ) plugin, is obsolete – not included
  • Versions plugin to check for dependency and plugin updates

BEST Practices Maven Config File

 

Valuable Maven Commands

Display Dependency Updates

1.$ mvn versions:display-dependency-updates

Display Plugin Updates

1.$ mvn versions:display-plugin-updates

Display Dependency Tree

1.$ mvn dependency:tree -Ddetail

Display Dependency List

1.$ mvn dependency:list

Display Effective POM

1.$ mvn help:effective-pom

Display Project Settings

1.$ mvn help:effective-settings

Display System and Environment Variables

1.$ mvn help:system

Display Build Class Path

1.$ mvn dependency:build-classpath

 

十一月 07

http://blog.sanaulla.info/2013/03/21/introduction-to-functional-interfaces-a-concept-recreated-in-java-8/

Any java developer around the world would have used at least one of the following interfaces: java.lang.Runnable, java.awt.event.ActionListener, java.util.Comparator, java.util.concurrent.Callable. There is some common feature among the stated interfaces and that feature is they have only one method declared in their interface definition. There are lot more such interfaces in JDK and also lot more created by java developers. These interfaces are also called Single Abstract Method interfaces (SAM Interfaces). And a popular way in which these are used is by creating Anonymous Inner classes using these interfaces, something like:

01 public class AnonymousInnerClassTest {
02   public static void main(String[] args) {
03     new Thread(new Runnable() {
04       @Override
05       public void run() {
06         System.out.println("A thread created and running ...");
07       }
08     }).start();
09   }
10 }

With Java 8 the same concept of SAM interfaces is recreated and are called Functional interfaces. These can be represented using Lambda expressions, Method reference and constructor references(I will cover these two topics in the upcoming blog posts). There’s an annotation introduced- @FunctionalInterface which can be used for compiler level errors when the interface you have annotated is not a valid Functional Interface. Lets try to have a look at a simple functional interface with only one abstract method:

1 @FunctionalInterface
2 public interface SimpleFuncInterface {
3   public void doWork();
4 }

The interface can also declare the abstract methods from the java.lang.Object class, but still the interface can be called as a Functional Interface:

1 @FunctionalInterface
2 public interface SimpleFuncInterface {
3   public void doWork();
4   public String toString();
5   public boolean equals(Object o);
6 }

Once you add another abstract method to the interface then the compiler/IDE will flag it as an error as shown in the screenshot below:
Functional Interface Error
Interface can extend another interface and in case the Interface it is extending in functional and it doesn’t declare any new abstract methods then the new interface is also functional. But an interface can have one abstract method and any number of default methods and the interface would still be called an functional interface. To get an idea of default methods please read here.

1 @FunctionalInterface
2 public interface ComplexFunctionalInterface extends SimpleFuncInterface {
3   default public void doSomeWork(){
4     System.out.println("Doing some work in interface impl...");
5   }
6   default public void doSomeOtherWork(){
7     System.out.println("Doing some other work in interface impl...");
8   }
9 }

The above interface is still a valid functional interface. Now lets see how we can use the lambda expression as against anonymous inner class for implementing functional interfaces:

01 /*
02 * Implementing the interface by creating an
03 * anonymous inner class versus using
04 * lambda expression.
05 */
06 public class SimpleFunInterfaceTest {
07   public static void main(String[] args) {
08     carryOutWork(new SimpleFuncInterface() {
09       @Override
10       public void doWork() {
11         System.out.println("Do work in SimpleFun impl...");
12       }
13     });
14     carryOutWork(() -> System.out.println("Do work in lambda exp impl..."));
15   }
16   public static void carryOutWork(SimpleFuncInterface sfi){
17     sfi.doWork();
18   }
19 }

And the output would be …

1 Do work in SimpleFun impl...
2 Do work in lambda exp impl...

In case you are using an IDE which supports the Java Lambda expression syntax(Netbeans 8 Nightly builds) then it provides an hint when you use an anonymous inner class as used above
Functional Interface Hint
This was a brief introduction to the concept of functional interfaces in java 8 and also how they can be implemented using Lambda expressions.

十一月 07

http://blog.sanaulla.info/2013/03/20/introduction-to-default-methods-defender-methods-in-java-8/

We all know that interfaces in Java contain only method declarations and no implementations and any non-abstract class implementing the interface had to provide the implementation. Lets look at an example:

01 public interface SimpleInterface {
02   public void doSomeWork();
03 }
04  
05 class SimpleInterfaceImpl implements SimpleInterface{
06   @Override
07   public void doSomeWork() {
08     System.out.println("Do Some Work implementation in the class");
09   }
10  
11   public static void main(String[] args) {
12     SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
13     simpObj.doSomeWork();
14   }
15 }

Now what if I add a new method in the SimpleInterface?

1 public interface SimpleInterface {
2   public void doSomeWork();
3   public void doSomeOtherWork();
4 }

and if we try to compile the code we end up with:

1 $javac .\SimpleInterface.java
2 .\SimpleInterface.java:18: error: SimpleInterfaceImpl is not abstract and does not
3 override abstract method doSomeOtherWork() in SimpleInterface
4 class SimpleInterfaceImpl implements SimpleInterface{
5 ^
6 1 error

And this limitation makes it almost impossible to extend/improve the existing interfaces and APIs. The same challenge was faced while enhancing the Collections API in Java 8 to support lambda expressions in the API. To overcome this limitation a new concept is introduced in Java 8 called default methods which is also referred to as Defender Methods or Virtual extension methods.

Default methods are those methods which have some default implementation and helps in evolving the interfaces without breaking the existing code. Lets look at an example:

01 public interface SimpleInterface {
02   public void doSomeWork();
03    
04   //A default method in the interface created using "default" keyword
05   default public void doSomeOtherWork(){
06     System.out.println("DoSomeOtherWork implementation in the interface");
07   }
08 }
09  
10 class SimpleInterfaceImpl implements SimpleInterface{
11   @Override
12   public void doSomeWork() {
13     System.out.println("Do Some Work implementation in the class");
14   }
15   /*
16    * Not required to override to provide an implementation
17    * for doSomeOtherWork.
18    */
19  
20   public static void main(String[] args) {
21     SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
22     simpObj.doSomeWork();
23     simpObj.doSomeOtherWork();
24   }
25 }

and the output is:

1 Do Some Work implementation in the class
2 DoSomeOtherWork implementation in the interface

This is a very brief introduction to default methods. One can read in depth about default methods here.

Update:
There was a concern about a class implementing 2 interfaces with each interface declaring a default method with the same name. In such cases the compiler would flag it as an error. Let me explain it with an example:

01 public interface InterfaceWithDefaultMethod {
02   public void someMethod();
03   default public void someOtherMethod(){
04     System.out.println("Default method implementation in the interface");
05   }
06 }
07 public interface InterfaceWithAnotherDefMethod {
08   default public void someOtherMethod(){
09     System.out.println("Default method implementation in the interface");
10   }
11 }

And then a class implementing both the above interfaces.

01 public class DefaultMethodSample implements
02   InterfaceWithDefaultMethod, InterfaceWithAnotherDefMethod{
03    
04   @Override
05   public void someMethod(){
06     System.out.println("Some method implementation in the class");
07   }
08   public static void main(String[] args) {
09     DefaultMethodSample def1 = new DefaultMethodSample();
10     def1.someMethod();
11     def1.someOtherMethod();
12   
13 }

but this results in a compiler error as shown in the screenshot below and this way it avoids the confusion of which default method implementation to invoke.

十月 22

http://www.programcreek.com/2013/03/hashset-vs-treeset-vs-linkedhashset/

In a set, there are no duplicate elements. That is one of the major reasons to use a set. There are 3 implementations of Set: HashSet, TreeSet and LinkedHashSet. When and which to use is an important question. In brief, if we want a fast set, we should use HashSet; if we need a sorted set, then TreeSet should be used; if we want a set that can be read by following its insertion order, LinkedHashSet should be used.

1. Set Interface

Set interface extends Collection interface. In a set, no duplicates are allowed. Every element in a set must be unique. We can simply add elements to a set, and finally we will get a set of elements with duplicates removed automatically.

2. HashSet vs. TreeSet vs. LinkedHashSet

HashSet is Implemented using a hash table. Elements are not ordered. The add, remove, and contains methods has constant time complexity O(1).

TreeSet is implemented using a tree structure(red-black tree in algorithm book). The elements in a set are sorted, but the add, remove, and contains methods has time complexity of O(log (n)). It offers several methods to deal with the ordered set like first(), last(), headSet(), tailSet(), etc.

LinkedHashSet is between HashSet and TreeSet. It is implemented as a hash table with a linked list running through it, so it provides the order of insertion. The time complexity of basic methods is O(1).

3. TreeSet Example

TreeSet<Integer> tree = new TreeSet<Integer>();
tree.add(12);
tree.add(63);
tree.add(34);
tree.add(45);
 
Iterator<Integer> iterator = tree.iterator();
System.out.print("Tree set data: ");
while (iterator.hasNext()) {
    System.out.print(iterator.next() + " ");
}

Output is sorted as follows:

Tree set data: 12 34 45 63

Now let’s define a Dog class as follows:

class Dog {
	int size;
 
	public Dog(int s) {
		size = s;
	}
 
	public String toString() {
		return size + "";
	}
}

Let’s add some dogs to TreeSet like the following:

import java.util.Iterator;
import java.util.TreeSet;
 
public class TestTreeSet {
	public static void main(String[] args) {
		TreeSet<Dog> dset = new TreeSet<Dog>();
		dset.add(new Dog(2));
		dset.add(new Dog(1));
		dset.add(new Dog(3));
 
		Iterator<Dog> iterator = dset.iterator();
 
		while (iterator.hasNext()) {
			System.out.print(iterator.next() + " ");
		}
	}
}

Compile ok, but run-time error occurs:

Exception in thread “main” java.lang.ClassCastException: collection.Dog cannot be cast to java.lang.Comparable
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at collection.TestTreeSet.main(TestTreeSet.java:22)

Because TreeSet is sorted, the Dog object need to implement java.lang.Comparable‘s compareTo() method like the following:

class Dog implements Comparable<Dog>{
	int size;
 
	public Dog(int s) {
		size = s;
	}
 
	public String toString() {
		return size + "";
	}
 
	@Override
	public int compareTo(Dog o) {
	        return size - o.size;
	}
}

The output is:

1 2 3

4. HashSet Example

HashSet<Dog> dset = new HashSet<Dog>();
dset.add(new Dog(2));
dset.add(new Dog(1));
dset.add(new Dog(3));
dset.add(new Dog(5));
dset.add(new Dog(4));
Iterator<Dog> iterator = dset.iterator();
while (iterator.hasNext()) {
	System.out.print(iterator.next() + " ");
}

Output:

5 3 2 1 4

Note the order is not certain.

5. LinkedHashSet Example

LinkedHashSet<Dog> dset = new LinkedHashSet<Dog>();
dset.add(new Dog(2));
dset.add(new Dog(1));
dset.add(new Dog(3));
dset.add(new Dog(5));
dset.add(new Dog(4));
Iterator<Dog> iterator = dset.iterator();
while (iterator.hasNext()) {
	System.out.print(iterator.next() + " ");
}

The order of the output is certain and it is the insertion order.

2 1 3 5 4

6. Performance testing

The following method tests the performance of the three class on add() method.

public static void main(String[] args) {
 
	Random r = new Random();
 
	HashSet<Dog> hashSet = new HashSet<Dog>();
	TreeSet<Dog> treeSet = new TreeSet<Dog>();
	LinkedHashSet<Dog> linkedSet = new LinkedHashSet<Dog>();
 
	// start time
	long startTime = System.nanoTime();
 
	for (int i = 0; i < 1000; i++) {
		int x = r.nextInt(1000 - 10) + 10;
		hashSet.add(new Dog(x));
	}
	// end time
	long endTime = System.nanoTime();
	long duration = endTime - startTime;
	System.out.println("HashSet: " + duration);
 
 
 
 
	// start time
	startTime = System.nanoTime();
 
	for (int i = 0; i < 1000; i++) {
		int x = r.nextInt(1000 - 10) + 10;
		treeSet.add(new Dog(x));
	}
	// end time
	endTime = System.nanoTime();
	duration = endTime - startTime;
	System.out.println("TreeSet: " + duration);
 
 
 
 
	// start time
	startTime = System.nanoTime();
 
	for (int i = 0; i < 1000; i++) {
		int x = r.nextInt(1000 - 10) + 10;
		linkedSet.add(new Dog(x));
	}
	// end time
	endTime = System.nanoTime();
	duration = endTime - startTime;
	System.out.println("LinkedHashSet: " + duration);
 
}

From the output below, we can clearly wee that HashSet is the fastest one.

HashSet: 2244768
TreeSet: 3549314
LinkedHashSet: 2263320