Sunday, 6 September 2015

Maven : Unmavenized Artifacts in Multi Module Environment

Maven's declarative behavior forces user to use managed artifacts and discourages the use of unmanaged/external/unmavenized artifacts/jars.

There are couple of workarounds to solve this problem. Some of the hacks have been described below.

Method 1 : Using 'system' scope
Maven provides scope called 'system' which expects absolute path. But using absolute path will makes build user specific which should not happen in automation tools. This can be avoided using ${basedir} variable. This variable provides the absolute path of current module and hence jar put in relative with the current module can be relatively accessed with ${basedir} variable.
  • Create a folder(say lib) and keep external jars into lib folder. 
  • These jars can be accessed as shown below. 
  <dependency>
        <groupId>com.bala</groupId>
        <artifactId>test-artifact</artifactId>
        <version>1.0</version>
        <scope>system</scope>
        <systemPath>${basedir}/lib/test-artifact.jar</systemPath>
    </dependency>
Pros : Easy to implement
Cons : In case of modularized project, if same jar is being used in multiple modules, this jar should be duplicated in all those modules. (You may get a thought that why can't we keep it in parent pom, but child modules cannot access parent's absolute path. Maven 3+ doesn't support accessing parent's properties from child module.)

Method 2 : Using file based repository
  • Create a local repo(say lib and commit this lib along with the external jars, if you use version control). 
  • Identify all the external jars and install them using following command. 
mvn install:install-file -Dfile=<path-to-file> -DgroupId=<custom-group-id> -DartifactId=<custom-artifact-id> -Dversion=<custom-version> -DlocalRepositoryPath=<path-to-local-repo-folder>
  • Specify file based local repository in your pom as shown below. 
<repositories>
    <repository>
        <id>custom-repo-id</id>
        <name>custom-repo-name</name>
        <url>file:${basedir}/lib</url>
    </repository>
</repositories>
  • Now external dependencies can be used with the help of minimal pom in dependencies section. 
<dependency>
    <groupId>custom-group-id</groupId>
    <artifactId>custom-artifact-id</artifactId>
    <version>custom-version</version>
</dependency>
Pros : Better than using system scope.
Cons : In case of modularized project, if same jar is being used in multiple modules, this jar should be installed in all modules' repo. (You may get a thought that why can't we keep it in parent pom, but child modules cannot access parent's absolute path. Maven 3+ doesn't support accessing parent's properties from child module.). Moreover this method adds unnecessary files and commits to version control's repository which is not desirable.

Method 3(Recommended):
Method 2 can be enhanced by applying a bit of intelligence using maven plugin capability. In the preceding method, external jar is being installed into file based repo which is going to be existed in version conrol's repo. Instead, if you can install jar into user's local repository as soon as user ran clean or compile then it will automatically be installed into user's local repository. Now this can be accessed using minimal pom. I advice to go by following steps.
  • Create a folder(say lib) in the current project and keep all the jars into that folder. In case of modularized project, create a module, say external-jar-installer and copy lib folder along with the jars into the module. Make sure that these jars should be checked in. 
  • Now use maven maven install plugin and configure all the jars in clean phase as shown below. 

  • As soon as we run mvn clean, all the jars will be fetched from lib folder and be installed into user's local repo. Hence minmal pom will becom valid for the user whoever is executing rest of the the mvn commands.

Pros : This will be a cleaner way, even in case of modularized project. Dedicatedly one module can be allocated to install these jars and plugin. Rest of the modules will be ignorant of external jars and they will just use them as if they were fetched from repository.

Monday, 18 May 2015

How to delete a file in Windows with a long filename

Windows has a restriction on length of the filename. But sometimes, you may end-up with files which are having larger than 250 characters and windows will not allow us to delete them. 
Windows 7 has come up with a tool called robocopy. We can delete long named files with the help of this tool. 

Robocopy has an option called mirror copy which will create a mirror of source in destination folder. 
  • Create an empty folder. 
  • robocopy empty_folder long_named_directory /s /mir
  • Now it will create mirror of empty folder in destination folder leaving bot the folders empty. 
  • You can happily delete both of them. 

Monday, 30 March 2015

Maven : Creating jar with dependencies

While working with the maven, it is a case that all the dependent jars will not be packed into the jar, whereas in case of war, all the dependent jars wil be packed into web/lib folder. If you want to create a simple jar with all its dependency jars then you need to create uber jar.(Uber means Super, extreme or outstanding). Here are the steps to create uber jar using maven.


  • Step 1 : Create an assembly xml and put it into your resources folder.
  • Step 2 : Include assembly.xml in your pom in the plugin-configuration node along with the manifest-mainclass.
  • Step 3 : Fire mvn assembly:assembly, it will create simple and uber jar in your target folder. 

Friday, 13 February 2015

Sencha Touch, ExtJS Offline Docs and GPL Source


Sencha Touch Offline Documentation Bundle

http://cdn.sencha.com/downloads/docs/touch-docs-2.3.0.zip
http://cdn.sencha.com/downloads/docs/touch-docs-2.3.1.zip
http://cdn.sencha.com/downloads/docs/touch-docs-2.4.0.zip
http://cdn.sencha.com/downloads/docs/touch-docs-2.4.1.zip

ExtJS Offline Documentation Bundle
http://cdn.sencha.com/downloads/docs/extjs-docs-4.2.1.zip
http://cdn.sencha.com/downloads/docs/extjs-docs-4.2.2.zip
http://cdn.sencha.com/downloads/docs/extjs-docs-4.2.3.zip

http://cdn.sencha.com/downloads/docs/ext-docs-5.0.zip
http://cdn.sencha.com/downloads/docs/ext-docs-5.1.0.zip


Sencha Touch GPL bundle
http://cdn.sencha.io/touch/sencha-touch-2.3.0-gpl.zip
http://cdn.sencha.io/touch/sencha-touch-2.3.1-gpl.zip
http://cdn.sencha.io/touch/sencha-touch-2.4.0-gpl.zip

ExtJS GPL Bundle
http://cdn.sencha.io/ext/gpl/ext-5.0.1-gpl.zip
http://cdn.sencha.io/ext/gpl/ext-5.0.0-gpl.zip
http://cdn.sencha.io/ext/gpl/ext-4.2.0-gpl.zip
http://cdn.sencha.io/ext/gpl/ext-4.2.1-gpl.zip
http://cdn.sencha.io/ext/gpl/ext-4.2.2-gpl.zip
http://cdn.sencha.io/ext/gpl/ext-4.2.3-gpl.zip

http://cdn.sencha.io/ext/gpl/ext-5.0.0-gpl.zip
http://cdn.sencha.io/ext/gpl/ext-5.0.1-gpl.zip
http://cdn.sencha.io/ext/gpl/ext-5.1.0-gpl.zip

Sunday, 25 January 2015

ExtJS5 - Codemirror Integration

Being one of the leading frameworks for RIA, I was expecting ExtJS 5 with an inbuilt code editor. There are some add-ons available for ExtJS3 and ExtJS4 by extending form field base so that they can make it in par with form. But it is more restricted using in that way. We need to compromise with the layout if you are not using it on any other component. Instead we can use a simple hack to make it work seamlessly on any ExtJS components.

Since code mirror requires div or textarea, we can make use of ExtJS' 'box' to get handle of div. Next level complexity comes with form support and layouting. Here is the idea

  • Create a custom component by extending container of panel(As per requirement)
  • Use codemirror's configs as configs of custom component
  • Add following components as items
    • box : Since it provides a div, we can use it to render code mirror component
    • field: Add this item to your custom component and make it hidden. Replicate all the changes/actions on this field component whenever there are changes/actions on the codemirror. 
  • Initialize codemiror field 'afterrender' of custom component with the configs that are defined on it. 
Form Support
ExtJS form comes with the additional properties like dirty change, load/get/update Record features  so that we can load the model into the form and work with it. Whenever we add our custom component to form, form will be able to identify the field item which is the part of our custom component. Since ExtJS form fires every action on our field, we can get the handle form actions. 

For example if there is a change event on code mirror, we will be able to find out whether its a dirty or not but how can we tell form that it is dirty? Thats where we bring our field into action. Call setDirty function of field and fire dirty change event from that. Rest will be taken care by form. Sam e applies with the other actions. 

Layout Support
Since it is our custom component, we don't need to worry much. 

Controlling Size
Code mirror has a pre-configured height(300) in its css and there is a method to set custom height and width. We can pass these values as configs to our custom component and call setSize method of codemirror. 


I have tried a custom component with remote validation features. You can find source code at the following location. This is just a prototype code to show how we can make codemirror work with ExtJS without affecting much from its version changes. You can take the idea and customize it as per your needs. 



Tuesday, 20 January 2015

Selection of Div Content on ExtJS(Select ALL)

Here is a simple code snippet to show data on view with select all enabled container.



Sunday, 11 January 2015

Workaround : Ext JS 5.1.0 checkboxmodel 'deselect' defect

ExtJS 5.1.0 is having a bug in checkboxmodel. While using checkbox model, it is not firing deselect/selection change when the model is 'MULTI' which is a default value.

Use following snippet to make it work.

 selModel: {
          selType: 'checkboxmodel' 
          model : 'SIMPLE'

}

Thursday, 1 January 2015

model Deletion in ExtJS 5

While I was working with ExtJS 5, I faced a problem in deleting a record. 'erase' is a method in ExtJS 5 to delete a model, which is a counter part of 'destroy' method in ExtJS 4. I tried 'erase' method on model to delete it using rest and it was not sending any DELETE request to the server. Here is the sample code snippet
var user = Ext.create('User', {
   extend : 'Ext.data.Model',
   fields : ['id', 'name', 'email'],

   proxy : {
    type : 'rest',
    url : '/users'
   }
  });

user.set('id', '12345');
user.erase();

In the preceding function call, will not be any XHR request with 'DELETE' method as we expect, if you are using ExtJS-5.1.0. In ExtJS 4, if there is any change in the ID property, it calls a function(changeId) that does house keeping of a model hence, model's phantom becomes false whereas in ExtJS5, user.set('id','12345') will not change user's phantom to false(When we create model using Ext.create, default phantom value will be true). Since it is a phantom record(new record), it will not call any 'DELETE' request.

Here is a simple hack to handle this problem. We hope there will be a fix in their future releases.

user.set('id','12345');
user.commit(); // user.phantom becomes false
user.erase();
or
user.set('id','12345');
user.phantom = false; //Make phantom as false manually
user.erase();