tag:blogger.com,1999:blog-43931853928052264802024-03-05T11:41:48.707-08:00pointcutAnonymoushttp://www.blogger.com/profile/14769628992288331352noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-4393185392805226480.post-70348978780155435782015-08-18T15:54:00.003-07:002015-08-18T18:27:03.473-07:00TDD Kickstart with Spring 4.x + Maven 3.x + MongoDB 3.x - PART 1<div dir="ltr" style="text-align: left;" trbidi="on">
I guess my TDD skills has slowly melted down as I was not actively programming more than six f*king months! I need a kickstart to refresh my laggy old brain and naggy Macbook Pro Yosemite OSX (upgrades needed).<br />
<h3 style="text-align: left;">
What do you need?</h3>
<ul style="text-align: left;">
<li>Maven 3.x</li>
<li>MongoDB 3.x</li>
<li>Java JDK 1.7.x</li>
<li>Eclipse IDE Java EE Developer (mine is Luna with m2e plugin installed)</li>
</ul>
OK assuming you've all of these installed and working, let gets dirty (I mean hands).<br />
<h3 style="text-align: left;">
What are the steps?</h3>
<ul style="text-align: left;">
<li>Create a mongodb collection & document</li>
<li>Create a java web project And Import to Eclipse IDE</li>
<li>Add project dependencies: Spring core, Spring test, Spring data mongo etc...</li>
<li>Write you TDD code. "Red -> Green -> Refactor" cycle.</li>
</ul>
<h4 style="text-align: left;">
A. Create a mongodb collection & document</h4>
<ol style="text-align: left;">
<li>Start your mongod: <i>mongodb -dbpath <choose your db path i.e.: /usr/local/var/mongodb/data> &</i></li>
<li>Start your mongo shell, type:<b> </b><i>mongo --shell</i></li>
<li>In shell, create your db collection, type: <i>use <choose your db i.e.: demo></i></li>
<li>In shell, create one entry, type:<i> db.demo.insert({name: "hamid", socialSecurity: 1234567890})</i></li>
<li>In shell, verify your entry, type:<i> db.demo.find()</i></li>
</ol>
<h4 style="text-align: left;">
B. Create java web project (please make sure you're connected to the internet)</h4>
<ol style="text-align: left;">
<li>In command line, navigate to your eclipse workspace folder. If there isn't existing, create one.</li>
<li>Create java web project (just hit enter on interactive prompt), type: <i>mvn archetype:generate -DgroupId=<choose one i.e.: com.pointcut.demo> -DartifactId=<choose one i.e.: springmongo> -DarchetypeArtifactId=maven-archetype-webapp</i></li>
<li>On "BUILD SUCCESS" (after a long while), navigate to your project folder (i.e.: springmongo) to get your project eclipse ready, type:<b> </b><i>mvn eclipse:clean eclipse:eclipse</i></li>
<li>Import into eclipse IDE: <i>Goto menu File->Import->Maven->Existing Maven Projects and locate your project in your workspace folder.</i></li>
<li>Make sure you project points to the right JDK runtime in Java Build Path: <i>Right click on project name->Build Path->Configure Build Path...</i></li>
</ol>
<h4 style="text-align: left;">
C. Add project dependencies: Spring core, Spring test, Spring data mongo</h4>
<ol style="text-align: left;">
<li>Add project dependencies:<i> Right click on project name->Maven->Add Dependency</i></li>
<li>In "Add Dependency" window, type "spring-core" in "Enter groupId, artifactId or sha1 prefix or pattern (*)" field</li>
<li>Choose related library from "Search Results" list choose "org.springframework spring-core"-> 4.0.2.RELEASE version</li>
<li>Repeat previous two (2) steps for spring-test (4.0.2.RELEASE), spring-context (4.0.2.RELEASE), spring-context-support (4.0.2.RELEASE), spring-beans (4.0.2.RELEASE), spring-data-mongodb (1.2.0.RELEASE), spring-beans (4.0.2.RELEASE), mongo-java-driver (2.9.1)</li>
<li>Update your maven project: <i>Right click on project name ->Maven->Update Project...</i></li>
</ol>
<br />
<h4 style="text-align: left;">
What's next? checkout PART 2 coming soon...</h4>
<br />
<div style="text-align: center;">
-----------------------------✄----------------------------</div>
<h3 style="text-align: left;">
<a href="https://www.blogger.com/blogger.g?blogID=4393185392805226480#install">Installation Guide</a></h3>
How to install? I love using command line if all possible. ok briefly this is what I did via command line, at least.<br />
<h4 style="text-align: left;">
For Maven 3.x</h4>
<div style="text-align: left;">
</div>
<ol style="text-align: left;">
<li>Download the archive from <a href="https://maven.apache.org/download.cgi" target="_blank">here</a>. In command line, wget <archive url address></li>
<li>Unzip it. For my case at /usr/local. Depending on your archive (.zip or tar.gz) u may want to user unzip or tar zxvf in command line.</li>
<li>Set the home var and path. Update your .bash_profile (I use vi), scroll all the way down and insert the following lines: </li>
</ol>
<i> export M2_HOME=/usr/local/<Maven Extracted Folder><br /> export PATH=$PATH:$MAVEN_HOME/bin</i><br />
<h4 style="text-align: left;">
For Mongo DB 3.x (recommend 64-bit)</h4>
<ol style="text-align: left;">
<li>Download the archive from <a href="https://www.mongodb.org/downloads" target="_blank">here</a>. Again, in command line wget <archive url address></li>
<li>Unzip it. For my case at /usr/local. Depending on your archive (.zip or tar.gz) u may want to user unzip or tar zxvf in command line.</li>
<li>Set the home var and path. Update your .bash_profile (I use vi), scroll all the way down and insert the following:</li>
</ol>
<br />
<i> export MONGO_HOME=/usr/local/<Mongo Extracted Folder></i><br />
<i> export PATH=$PATH:$MONGO_HOME/bin</i><br />
<h4 style="text-align: left;">
For Java JDK 1.7 <a href="http://docs.oracle.com/javase/7/docs/webnotes/install/mac/mac-jdk.html">here</a> for Mac</h4>
<h4 style="text-align: left;">
For Eclipse Luna Java EE <a href="http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/keplersr2">here</a> </h4>
<br /></div>
Anonymoushttp://www.blogger.com/profile/14769628992288331352noreply@blogger.com0tag:blogger.com,1999:blog-4393185392805226480.post-23810057482200974242015-08-17T07:37:00.000-07:002015-08-17T07:37:22.575-07:00Class not found: com.mchange.v2.ser.Indirector<div dir="ltr" style="text-align: left;" trbidi="on">
I was trying to setup CAS server for Liferay CE 6.2 based on "<span style="font-size: 18px;">Liferay 6.x Portal Enterprise Intranets Cookbook" </span>but stumbled with the above error. I did follow all the steps diligently, but I guess the author might have missed additional library to add to<span style="font-size: 18px;"> </span><span style="background-color: white; color: blue; font-family: 'Droid Sans Mono', Courier, monospace; font-size: 16px; line-height: 26.3999996185303px;">${TOMCAT_HOME}/webapps/cas-server-webapp-4.0.0/WEB-INF/lib </span>that is "mchange-commons-java".<br /><br />I quickly search for this library in my machine if any as I was so lazy to search in out in google and found it in Liferay's tomcat bundle under webapps/ROOT/WEB-IF/lib folder.<br />
<br />
<i><b>Tips: </b>You may want to use find command in Centos (or any linux-based OS) search by filename with "sudo find / -name 'mchange-commons-java*' -print".</i><br /><br /><br />I hope that helps someone outthere.<br />
<br />
Happy Godek'king!</div>
Anonymoushttp://www.blogger.com/profile/14769628992288331352noreply@blogger.com0tag:blogger.com,1999:blog-4393185392805226480.post-42771425358471159922015-08-17T02:47:00.001-07:002015-08-17T07:14:52.984-07:00Remote JMX Connection Issue<div dir="ltr" style="text-align: left;" trbidi="on">
Recently I tried to remotely connect to Liferay 6.2 's tomcat bundle on JMX via JConsole and JVisualVM with no success. Both applications repeatedly unable to connect via rmi. This boggled me as this never happened to me if the same to be done on Windows or my OSX macbook.<br />
<br />
The only difference this time is I have Centos 7 running on my macbook. Yes, Centos 7, trying to get my hands dirty back on Linux. Installing Centos 7 on Macbook is another story. It took me a few days of misery and frustration until LiveCD saved me. OK, enough about me.<br />
<br />
So, as usual you would need to supply VM arguments as follow:<br />
<div>
<br /></div>
<div>
-Dcom.sun.management.jmxremote </div>
<div>
-Dcom.sun.management.jmxremote.port=9999</div>
<div>
-Dcom.sun.management.jmxremote.ssl=false</div>
<div>
-Dcom.sun.management.jmxremote.authenticate=false</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<i><b>Tips: </b>You can quickly kill the process that is listening to port 9999 with "fuser -k 9999/tcp" command.</i></div>
<div>
<br /></div>
<div>
Normally this is would suffice, but not this time. <br />
Further tests to narrow down to possible root cause includes:<br />
<br />
1. Telnet to port - OK<br />
# telnet <host-ip> 9999<br />
<br />
2. Run local JConsole and JVisualVM - OK (although unneccessary)<br />
<br />
<i><b>Tips: </b>You may completely disable firewall in Centos 7 with "sudo systemctl disable firewall-d" or</i><br />
<i>open up specific port with "sudo firewall-cmd --zone=public --add-port=9999/tcp && sudo firewall-cmd --reload"</i><br />
<i><br /></i>
After exhaustively searching through google and stackoverflow finally I found a blog page that suggest additional argument. Ironically, the blog post entry has nothing to do with my problem, duhh...additionally I found this via a comment in stackoverflow entry.<br />
<br />
So, the additional argument that make it work is -Dcom.sun.management.jmxremote.<b>rmi</b>.port=9999<br />
Feel me? yeah, how silly is that and I don't know why and how that works. So, help me god if anyone would generously want to explain.</div>
<div>
'</div>
<div>
<div>
-Dcom.sun.management.jmxremote </div>
<div>
-Dcom.sun.management.jmxremote.port=9999</div>
<div>
-Dcom.sun.management.jmxremote.rmi.port=9999</div>
<div>
-Dcom.sun.management.jmxremote.ssl=false</div>
<div>
-Dcom.sun.management.jmxremote.authenticate=false</div>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Made the changes then, I fired JConsole/JVisualVM and it works!<br />
<br />
I hope that helps some one outthere.</div>
<div>
<br /></div>
<div>
Happy Godek'king!!</div>
<div>
<br /></div>
<div>
FYI "Godek" slang means "hack" in Malay :)<br />
<br /></div>
<div>
<br />
<br />
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/14769628992288331352noreply@blogger.com0tag:blogger.com,1999:blog-4393185392805226480.post-51646381898406955722015-08-17T01:54:00.000-07:002015-08-17T02:48:47.282-07:00java.io.IOException: Cannot recover key<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: justify;">
For those who are NOT familiar with configuring tomcat HTTPS connector (I had apache-tomcat-7.0.34), like me, this error can be frustrating. It turned out to be a simple fix. I am assuming you have properly generated a tomcat key, a keystore and imported them successfully into JAVA <b>cacerts</b> keystore. As for my case I chose my own keystore filename, my own kesytore pass(word) and my own tomcat key pass(word). Unfortunately, these require explicitly be entered in your tomcat's server.xml. </div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Consider the following template in the tomcat's server.xml file after you uncommented it.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihU8d7XYFricU8HGgCziCmpirYxjrPsgeUUY-bIcFPDYoH0f4fXSB-rTemve7pYht5yoT4ZRn_w-mysdF-W8aOjWCDjB1wQ8zwATzvXvIDGXVsP5N-C4B4YWQdOrX-6iDpgy_Dm6Iom7c/s1600/Screen+Shot+2015-08-17+at+4.15.51+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihU8d7XYFricU8HGgCziCmpirYxjrPsgeUUY-bIcFPDYoH0f4fXSB-rTemve7pYht5yoT4ZRn_w-mysdF-W8aOjWCDjB1wQ8zwATzvXvIDGXVsP5N-C4B4YWQdOrX-6iDpgy_Dm6Iom7c/s640/Screen+Shot+2015-08-17+at+4.15.51+PM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
If you named your keystore as "<b>.keystore</b>" with key and keystore pass(word) as "<b>changeit</b>" and left it reside in your home dir (i.e.: <b>/home/hamid</b>) , then above setup would work happily just like that.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Unfortunately, for most of the time it is not the case as you would name your keystore to some other name, located to some other location (folder) and both key & keystore with some other pass(word).</div>
<div class="separator" style="clear: both; text-align: justify;">
For example:</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Keystore name: <b>keystore.jks</b></div>
<div class="separator" style="clear: both; text-align: justify;">
Keystore folder: <b>/home/hamid/secret/store</b></div>
<div class="separator" style="clear: both; text-align: justify;">
Keystore password: <b>password1</b></div>
<div class="separator" style="clear: both; text-align: justify;">
Key password: <b>password2</b></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Then you would want to do the following:</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1UKJz8KrHFU7Bh_n-L0d0a2oqSDWC2fKQWTM-i7hPgjPuV8BEz1M8-q6wwhDaJZ9eoQNDGc75sp4q55YxCuFy8-HM4ZsTVyFBvf7D5Bf2qeDiNkSYfkMbaOQcV4EtwEwJt5XFQFSfLSQ/s1600/Screen+Shot+2015-08-17+at+4.28.12+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1UKJz8KrHFU7Bh_n-L0d0a2oqSDWC2fKQWTM-i7hPgjPuV8BEz1M8-q6wwhDaJZ9eoQNDGc75sp4q55YxCuFy8-HM4ZsTVyFBvf7D5Bf2qeDiNkSYfkMbaOQcV4EtwEwJt5XFQFSfLSQ/s640/Screen+Shot+2015-08-17+at+4.28.12+PM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
I hope that helps.<br />
<br />
Happy Godek'king!<br />
<br />
FYI "Godek" slang means "hack" in Malay :)<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/14769628992288331352noreply@blogger.com0tag:blogger.com,1999:blog-4393185392805226480.post-1078359239706993812014-07-19T22:22:00.000-07:002014-07-20T00:56:59.533-07:00moiblogstore<script type="text/javascript">
jQuery(document).ready(function() {
jQuery.ajax({
dataType: "text",
url: "http://moiblogstore-env-xvvfp32jiu.elasticbeanstalk.com/api/v1/products.json"
//url: "http://localhost:3000/api/v1/products.json"
}).then(function(data) {
x = jQuery.parseJSON(data);
jQuery.each(x, function(index, data){
jQuery("#product-list").append("<li><div><img src=\"http://moiblogstore-env-xvvfp32jiu.elasticbeanstalk.com/attachment/" + data.default_image.token + "/" + data.default_image.file_name + "\" width=100 height=100/></div><span><ul><li>Product Name: " + data.name + "</li><li>Price: RM"+ data.price +"0</li><li>Availability: Limited</li><li><a href=\"#\"> Add to Cart</a></li></ul></span> </li>");
});
});
});
</script>
<div>List of products</div>
<ul id="product-list">
</ul>
Anonymoushttp://www.blogger.com/profile/14769628992288331352noreply@blogger.com0tag:blogger.com,1999:blog-4393185392805226480.post-16732903432877820212014-06-13T03:39:00.001-07:002014-06-13T03:39:43.021-07:00Enabling Spring Security ACL into plain Spring MVC-based AppFuse 3.0.1-SNAPSHOT Web Application Stack <div dir="ltr" style="text-align: left;" trbidi="on">
Hello again!<br />
In the last <a href="http://pointcut.blogspot.com/2014/06/jrebel-553-jboss-eap-61-eclipse-juno.html" target="_blank">blog entry</a>, I described on how to get Spring MVC flavor of AppFuse 3.0 Web Application Stack into your Eclipse IDE ready for development. In this tutorial, I will describe how to enable Spring ACL to control access to your web resources as fine-grained as to method level.<br />
<br />
First of, I owed a lot of contents and references to Krams Tutorial on Spring Security to get up and running almost immediately. Thanks Krams. I highly recommend anyone who are starting out using Spring Security ACL to review Krams tutorial. To learn more, <a href="http://krams915.blogspot.com/2011/01/spring-security-3-full-acl-tutorial.html" rel="nofollow" target="_blank">click on</a>.<br />
<br />
Why Spring Security ACL? Spring Security ACL provides a mechanism to protect your web resources way down to micro level such as your methods. This definitely is very nice feature if you have or wanted to have multi-tenanted web application such as gmail where multiple organisations may use single application without "knowing" they're sharing the same software platform with the rest of the world or in other term, SaaS (Software As A Service). Futhermore, our "myproject" is already using Spring Security but with ACL disabled by default. Therefore, protected resources are ONLY currently secured by their url patterns. Please take a look at src/main/webapp/WEB-INF/security.xml to learn more.<br />
<br />
And being said that, let's get back to our last "myproject" web app to continue on. In brief, the starter kit already has user management module with two roles ROLE_ADMIN and ROLE_USER. Users with role ROLE_ADMIN can perform all administrative tasks like creating, editing, deleting existing users. While the users with ROLE_USER limited to editing their own profile.<br />
<br />
Now, we will enable our "myproject" web application is the following<span style="color: #0b5394;"> 5 steps</span>:<br />
<br />
<span style="color: #0b5394; font-size: large;">Step 1: Creating ACL tables</span><br />
Firstly, we need to create four (4) acl related tables:<br />
i. acl_class<br />
ii. acl_sid<br />
iii. acl_object_identity<br />
iv. acl_entry<br />
<br />
In brief:<br />
- <b><i>acl_class</i></b> table stores fully qualified Class name to be secured and referenced as unique numeric id.<br />
- <b><i>acl_sid</i></b> stores table user id or role (actors) and referenced as numeric id.<br />
- <b><i>acl_object_identity</i></b> table stores fully qualified class to its existing instance/object/record mapping.<br />
- <b><i>acl_entry</i></b> table stores permissions mapping (READ/WRITE etc) between actors and existing instance/object/record.<br />
<br />
Now that we know a little bit about the tables, we need to create them. In order to do so, we need a DDL. Luckily, Spring supplies them within the jar itself as shown in the image below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSDV-THvkFM9q5AfjoEzfmGJRvMcxqewmhZteAblJTatByfviA8mKkDjHIsuxo283pGg-irX0-jtCvKvzwTyphtzayAz1T15dF8ebs1t6Mvm4ESknuz9UgMGDMvwUeZYC_YMrk5Mgohso/s1600/Screen+Shot+2014-06-13+at+1.48.36+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSDV-THvkFM9q5AfjoEzfmGJRvMcxqewmhZteAblJTatByfviA8mKkDjHIsuxo283pGg-irX0-jtCvKvzwTyphtzayAz1T15dF8ebs1t6Mvm4ESknuz9UgMGDMvwUeZYC_YMrk5Mgohso/s1600/Screen+Shot+2014-06-13+at+1.48.36+PM.png" height="240" width="320" /></a></div>
<br />
<br />
Go ahead copy and paste "createAclSchemaMySQL.sql" into your project main resource folder (src/main/resources)<br />
<br />
Now, we have choices either to run them in MySQL admin or console but I chose to use maven plugin called SQL Maven Plugin instead. You may learn more <a href="http://mojo.codehaus.org/sql-maven-plugin/index.html" rel="nofollow" target="_blank">here</a>.<br />
<br />
Add the following snippet to your pom.xml after "<span class="s1">maven</span>-compiler-<span class="s1">plugin</span>" </plugin> entry within<br />
<plugins>...</plugins><br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSbumBiWvlrCfuErSMkXrET9Rog-1ClFnojIngwJQtYPk0UCnad7irzKaD-TZBNq6XRQv8dv_85T0En90b2L3RaWP5WoREJIm-RVGrUXBXNc5pz5KeX0QMsj6XQB6GeSKccdzHD_ADeeXz/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <!-- Maven SQL Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>${jdbc.groupId}</groupId>
<artifactId>${jdbc.artifactId}</artifactId>
<version>${jdbc.version}</version>
</dependency>
</dependencies>
<configuration>
<driver>${jdbc.driverClassName}</driver>
<url>${jdbc.url}</url>
<username>${jdbc.username}</username>
<password>${jdbc.password}</password>
<settingsKey>sensibleKey</settingsKey>
<skip>${maven.test.skip}</skip>
</configuration>
<executions>
<execution>
<id>default-cli</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<url>${jdbc.url}</url>
<autocommit>true</autocommit>
<sqlCommand> </code></pre>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSbumBiWvlrCfuErSMkXrET9Rog-1ClFnojIngwJQtYPk0UCnad7irzKaD-TZBNq6XRQv8dv_85T0En90b2L3RaWP5WoREJIm-RVGrUXBXNc5pz5KeX0QMsj6XQB6GeSKccdzHD_ADeeXz/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> USE myproject;
DROP TABLE IF EXISTS acl_entry;
DROP TABLE IF EXISTS acl_object_identity;
DROP TABLE IF EXISTS acl_sid;
DROP TABLE IF EXISTS acl_class;
</sqlCommand>
<srcFiles>
<srcFile>src/main/resources/createAclSchemaMySQL.sql</srcFile>
</srcFiles>
<onError>abort</onError>
</configuration>
</execution>
</executions>
</plugin>
</code></pre>
<br />
<div class="p1">
Next, in command line window, execute the following:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">mvn sql:execute</span><br />
<br />
If you have properly followed this step, you should be getting the same result shown below:<br />
<br />
[INFO] ------------------------------------------------------------------------<br />
[INFO] Building AppFuse Spring MVC Application 1.0-SNAPSHOT<br />
[INFO] ------------------------------------------------------------------------<br />
[INFO]<br />
[INFO] --- sql-maven-plugin:1.5:execute (default-cli) @ myproject ---<br />
[INFO] Executing commands<br />
[INFO] Executing file: /var/folders/l3/1vl9ht9j2wg56dzvv_69lk6m0000gp/T/createAclSchemaMySQL.194031581sql<br />
[INFO] 9 of 9 SQL statements executed successfully<br />
[INFO] ------------------------------------------------------------------------<br />
[INFO] BUILD SUCCESS<br />
[INFO] ------------------------------------------------------------------------<br />
[INFO] Total time: 1.525s<br />
[INFO] Finished at: Fri Jun 13 17:56:55 MYT 2014<br />
[INFO] Final Memory: 16M/230M<br />
[INFO] ------------------------------------------------------------------------<br />
<br />
To verify, while in command line windows, issue the following:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">mysql -u root -e 'use myproject; show tables;'</span><br />
<br />
You should be seeing additional four (4) tables listed out in the output.<br />
<br /></div>
<span style="color: #0b5394; font-size: large;">Step 2: Add ACL Sample-data</span><br />
Currently this stack has a set of sample data populated from a file called sample-data.xml in src/test/resources folder. Primarily, it contains seed data for users (admin, user, two_roles_user) and role (ROLE_ADMIN, ROLE_USER) tables. This seed data is populated using the following command line:<br />
<span style="font-family: Courier New, Courier, monospace;">mvn dbunit:operation</span><br />
<br />
Now, we need to seed acl tables the same way. For simplicity (the better way is create separate file but require more steps), we will use the same file to seed with the following entries by copy and paste them right before </dataset> element in src/test/resources/sampe-data.xml file:<br />
<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSbumBiWvlrCfuErSMkXrET9Rog-1ClFnojIngwJQtYPk0UCnad7irzKaD-TZBNq6XRQv8dv_85T0En90b2L3RaWP5WoREJIm-RVGrUXBXNc5pz5KeX0QMsj6XQB6GeSKccdzHD_ADeeXz/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <table name="acl_class">
<column>id</column>
<column>class</column>
<row>
<value description="id">1</value>
<value description="class">com.mycompany.model.User</value>
</row>
<row>
<value description="id">2</value>
<value description="class">com.mycompany.model.Role</value>
</row>
</table>
<table name="acl_sid">
<column>id</column>
<column>principal</column>
<column>sid</column>
<row>
<value description="id">1</value>
<value description="principal">false</value>
<value description="sid">ROLE_ADMIN</value>
</row>
<row>
<value description="id">2</value>
<value description="principal">true</value>
<value description="sid">user</value>
</row>
<row>
<value description="id">3</value>
<value description="principal">true</value>
<value description="sid">two_roles_user</value>
</row>
</table>
<table name="acl_object_identity">;
<column>id</column>
<column>object_id_class</column>
<column>object_id_identity</column>
<column>parent_object</column>
<column>owner_sid</column>
<column>entries_inheriting</column>
<!-- com.mycompany.model.User -->
<row>
<value description="id">1</value>
<value description="object_id_class">1</value><!-- com.mycompany.model.User -->
<value description="object_id_identity">-1</value><!-- user -->
<null/>
<value description="owner_sid">1</value>
<value description="entries_inheriting">false</value>
</row>
<row>
<value description="id">2</value>
<value description="object_id_class">1</value><!-- com.mycompany.model.User -->
<value description="object_id_identity">-2</value><!-- admin -->
<null/>
<value description="owner_sid">1</value>
<value description="entries_inheriting">false</value>
</row>
<row>
<value description="id">3</value>
<value description="object_id_class">1</value><!-- com.mycompany.model.User -->
<value description="object_id_identity">-3</value><!-- two_roles_user -->
<null/>
<value description="owner_sid">1</value>
<value description="entries_inheriting">false</value>
</row>
<!-- com.mycompany.model.Role -->
<row>
<value description="id">4</value>
<value description="object_id_class">2</value><!-- com.mycompany.model.Role -->
<value description="object_id_identity">-1</value><!-- ROLE_ADMIN -->
<null/>
<value description="owner_sid">1</value>
<value description="entries_inheriting">false</value>
</row>
<row>
<value description="id">5</value>
<value description="object_id_class">2</value><!-- Role Model -->
<value description="object_id_identity">-2</value><!-- ROLE_USER -->
<null/>
<value description="owner_sid">1</value>
<value description="entries_inheriting">false</value>
</row>
</table>
<table name="acl_entry">;
<column>id</column>
<column>acl_object_identity</column>
<column>ace_order</column>
<column>sid</column>
<column>mask</column>
<column>granting</column>
<column>audit_success</column>
<column>audit_failure</column>
<!-- admin ACL ENTRIES -->
<row>
<value description="id">1</value>
<value description="acl_object_identity">1</value><!-- user -->
<value description="ace_order">1</value>
<value description="sid">1</value><!-- admin -->
<value description="mask">1</value><!-- READ -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
<row>
<value description="id">2</value>
<value description="acl_object_identity">1</value><!-- user -->
<value description="ace_order">2</value>
<value description="sid">1</value><!-- admin -->
<value description="mask">2</value><!-- WRITE -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
<row>
<value description="id">3</value>
<value description="acl_object_identity">2</value><!-- admin -->
<value description="ace_order">1</value>
<value description="sid">1</value><!-- admin -->
<value description="mask">1</value><!-- READ -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
<row>
<value description="id">4</value>
<value description="acl_object_identity">2</value><!-- admin -->
<value description="ace_order">2</value>
<value description="sid">1</value><!-- admin -->
<value description="mask">2</value><!-- WRITE -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
<row>
<value description="id">5</value>
<value description="acl_object_identity">3</value><!-- two_roles_user -->
<value description="ace_order">1</value>
<value description="sid">1</value><!-- admin -->
<value description="mask">1</value><!-- READ -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
<row>
<value description="id">6</value>
<value description="acl_object_identity">3</value><!-- two_roles_user -->
<value description="ace_order">2</value>
<value description="sid">1</value><!-- admin -->
<value description="mask">2</value><!-- WRITE -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
<!-- user ACL ENTRIES -->
<row>
<value description="id">7</value>
<value description="acl_object_identity">1</value><!-- user -->
<value description="ace_order">3</value>
<value description="sid">2</value><!-- user -->
<value description="mask">1</value><!-- READ -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
<row>
<value description="id">8</value>
<value description="acl_object_identity">1</value><!-- user -->
<value description="ace_order">4</value>
<value description="sid">2</value><!-- user -->
<value description="mask">2</value><!-- WRITE -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
<!-- two_roles_user ACL ENTRIES -->
<row>
<value description="id">9</value>
<value description="acl_object_identity">3</value><!-- two_roles_user -->
<value description="ace_order">3</value>
<value description="sid">3</value><!-- two_roles_user -->
<value description="mask">1</value><!-- READ -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
<row>
<value description="id">10</value>
<value description="acl_object_identity">3</value><!-- two_roles_user -->
<value description="ace_order">4</value>
<value description="sid">3</value><!-- two_roles_user -->
<value description="mask">2</value><!-- WRITE -->
<value description="granting">true</value><!-- Granting Mask -->
<value description="audit_success">true</value><!-- Audit every success permission -->
<value description="audit_failure">true</value><!-- Audit every failure permission -->
</row>
</table>
</code></pre>
<br />
<br />
Once copied and saved. Apply them to database by issuing the following in the command line window:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">mvn dbunit:operation</span><br />
<br />
To verify, while in command line windows, issue the following:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">mysql -u root -e "use myproject; select count(*) from acl_entry"</span><br />
<br />
You should be seeing ten (10) records count listed out in the output.<br />
<br />
<span style="color: #0b5394; font-size: large;">Step 3: Set ACL data source and add Spring ACL Configuration and import them into applicationContext.xml</span><br />
Let's set ACL data source by riding on the existing data source in all the way at the bottom file of src/main/resources/applicationContext-resources.xml (just before </beans> element):<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSbumBiWvlrCfuErSMkXrET9Rog-1ClFnojIngwJQtYPk0UCnad7irzKaD-TZBNq6XRQv8dv_85T0En90b2L3RaWP5WoREJIm-RVGrUXBXNc5pz5KeX0QMsj6XQB6GeSKccdzHD_ADeeXz/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <alias name="dataSource" alias="aclDataSource"/>
</code></pre>
<br />To avoid test failures, please add the same in src/test/resources/applicationContext.-resources.xml as well.<br />
<br />
Next, in order Spring Security ACL to work properly in a basic configuration must be in place.<br />
Go ahead copy and paste the following file and named them as acl-context.xml in<br />
src/main/webapp/WEB-INF now.<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSbumBiWvlrCfuErSMkXrET9Rog-1ClFnojIngwJQtYPk0UCnad7irzKaD-TZBNq6XRQv8dv_85T0En90b2L3RaWP5WoREJIm-RVGrUXBXNc5pz5KeX0QMsj6XQB6GeSKccdzHD_ADeeXz/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
<!-- See 15.3.2 Built-In Expression @http://static.springsource.org/spring-security/site/docs/3.0.x/reference/el-access.html#el-permission-evaluator -->
<bean id="expressionHandler"
class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<!-- To use hasPermission() in expressions, configure a PermissionEvaluator -->
<property name="permissionEvaluator" ref="permissionEvaluator" />
<property name="roleHierarchy" ref="roleHierarchy" />
</bean>
<!-- Declare a custom PermissionEvaluator We'll rely on the standard AclPermissionEvaluator
implementation -->
<bean class="org.springframework.security.acls.AclPermissionEvaluator"
id="permissionEvaluator">
<constructor-arg ref="aclService" />
</bean>
<!-- Declare an acl service -->
<bean class="org.springframework.security.acls.jdbc.JdbcMutableAclService"
id="aclService">
<constructor-arg ref="aclDataSource" />
<constructor-arg ref="lookupStrategy" />
<constructor-arg ref="aclCache" />
</bean>
<!-- Declare a lookup strategy -->
<bean id="lookupStrategy"
class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
<constructor-arg ref="aclDataSource" />
<constructor-arg ref="aclCache" />
<constructor-arg ref="aclAuthorizationStrategy" />
<constructor-arg ref="auditLogger" />
</bean>
<!-- Declare an acl cache -->
<bean id="aclCache"
class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
<constructor-arg>
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:shared="true"/>
</property>
<property name="cacheName" value="aclCache" />
</bean>
</constructor-arg>
</bean>
<!-- Declare an acl authorization strategy -->
<bean id="aclAuthorizationStrategy"
class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<constructor-arg>
<list>
<bean
class="org.springframework.security.core.authority.GrantedAuthorityImpl">
<constructor-arg value="ROLE_ADMIN" />
</bean>
<bean
class="org.springframework.security.core.authority.GrantedAuthorityImpl">
<constructor-arg value="ROLE_USER" />
</bean>
<bean
class="org.springframework.security.core.authority.GrantedAuthorityImpl">
<constructor-arg value="ROLE_USER" />
</bean>
</list>
</constructor-arg>
</bean>
<!-- Declare an audit logger -->
<bean id="auditLogger"
class="org.springframework.security.acls.domain.ConsoleAuditLogger" />
<!-- http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/access/hierarchicalroles/RoleHierarchyImpl.html -->
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
<value>
ROLE_ADMIN > ROLE_USER
</value>
</property>
</bean>
</beans>
</code></pre>
<br />
Then import it as resource in all the way at the bottom file of src/main/webapp/applicationContext.xml as follows (just before </beans> element):<br />
<span style="font-family: Courier New, Courier, monospace;"></span><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSbumBiWvlrCfuErSMkXrET9Rog-1ClFnojIngwJQtYPk0UCnad7irzKaD-TZBNq6XRQv8dv_85T0En90b2L3RaWP5WoREJIm-RVGrUXBXNc5pz5KeX0QMsj6XQB6GeSKccdzHD_ADeeXz/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><span style="font-family: Courier New, Courier, monospace;"><code style="color: black; word-wrap: normal;"> <import resource="acl-context.xml"/>
</code></span></pre>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">Don't forget to save the file.</span></div>
<br />
<span style="color: #0b5394; font-size: large;">Step 4: Enable Spring ACL expression and set filtering annotation</span><br />
Up to this point, the ACL setup won't take effect and our application "myproject" would run as of nothing have been added or changed since. In order to enable, edit src/main/webapp/security.xml as follows:<br />
<br />
Look for the following entry in the file:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSbumBiWvlrCfuErSMkXrET9Rog-1ClFnojIngwJQtYPk0UCnad7irzKaD-TZBNq6XRQv8dv_85T0En90b2L3RaWP5WoREJIm-RVGrUXBXNc5pz5KeX0QMsj6XQB6GeSKccdzHD_ADeeXz/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <global-method-security>
<protect-pointcut expression="execution(* *..service.UserManager.getUsers(..))" access="ROLE_ADMIN"/>
<protect-pointcut expression="execution(* *..service.UserManager.removeUser(..))" access="ROLE_ADMIN"/>
</global-method-security>
</code></pre>
<br />
and replace them with the following:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSbumBiWvlrCfuErSMkXrET9Rog-1ClFnojIngwJQtYPk0UCnad7irzKaD-TZBNq6XRQv8dv_85T0En90b2L3RaWP5WoREJIm-RVGrUXBXNc5pz5KeX0QMsj6XQB6GeSKccdzHD_ADeeXz/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> <global-method-security pre-post-annotations="enabled">
<expression-handler ref="expressionHandler" />
</global-method-security>
</code></pre>
<br />
then, don't for get to save the file.<br />
<br />
Next, we need to set filtering annotation in our service interface file, src/main/java/com/mycompany/service/UserManager.java in two method signatures:<br />
<br />
From<br />
<div class="p1">
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace;">List<User> search(String searchTerm);</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace;">...</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace;">List<User> getUsers();</span></div>
<div class="p1">
<br /></div>
<br />
to<br />
<br />
<br />
<div class="p1">
<span style="color: red; font-family: Courier New, Courier, monospace;"><span class="s2">@PostFilter</span><span class="s1">(</span>"hasPermission(filterObject, 'READ')"<span class="s1">)</span></span></div>
<div class="p1">
</div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace;">List<User> search(String searchTerm);</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace;">....</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div class="p1">
<span style="color: red; font-family: Courier New, Courier, monospace;"><span class="s2">@PostFilter</span><span class="s1">(</span>"hasPermission(filterObject, 'READ')"<span class="s1">)</span></span></div>
<div class="p2">
</div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace;">List<User> getUsers();</span></div>
<br />
The above annotation simply reads as right after returning from execution of the annotated method, filter out records in the result list the current user does NOT have READ access to, hence "POST" and "FILTER" in @PostFilter annotation.<br />
<br />
<span style="color: #0b5394; font-size: large;">Step 5: Start up our "myproject" web application and see them in action!</span><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
As precaution, please start your app by skipping on the test, as it will probably throw test failures because we have NOT yet refactor our test code to adapt to these changes. In the command line, issue the following:<br /><br /><span style="font-family: Courier New, Courier, monospace;">mvn -Dmaven.test.skip=true jetty:run</span><br />
<br />
<i>(but as tested, it did not produce any test failures thus you may not skip the test if you wish so)</i><br />
<br />
So, in this tutorial we have filtered out user listing in Administration -> Manage Users.<br />
By default, URL to this page has been restricted to users with ROLE_ADMIN only, thus only accessible by 'admin' and 'two_roles_user'. If you add ROLE_USER next to ROLE_ADMIN separated by a comma in security.xml file and manually navigate to http://localhost:8080/admin/users, all users will be listed and seen by user with ROLE_USER as well. Go ahead and play around with it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9cU92QADB93JzVR7ARH4F94dOEOrcnS4UoTcL6ErwZjq_ftcs9Y5rRK0qd-jRVRekW7D1Mcs-rJON6JqyAyi_qtauH4odw6gDMxdiRgaj27WUfnDE2TK-MvBYIMvcBMyQgaRtddScTZI/s1600/security-xml.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9cU92QADB93JzVR7ARH4F94dOEOrcnS4UoTcL6ErwZjq_ftcs9Y5rRK0qd-jRVRekW7D1Mcs-rJON6JqyAyi_qtauH4odw6gDMxdiRgaj27WUfnDE2TK-MvBYIMvcBMyQgaRtddScTZI/s1600/security-xml.png" height="115" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">src/main/webapp/security.xml</span></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
You should be seeing the following (BEFORE the ACL Expression is enabled)</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh39wCqNuxHSIoqsR52odUAHMM_Rcri9dOaSVmBxLPMVYGqbjwAkZy8cSEkm4vRphx5gm1L3nYaJPB9SCbZW9bAJSciE-OJRgBnX2btqH6TajNA0DA5XqBN0OHkw22c17bokW9ebtMqFz8/s1600/users-not-filtered.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh39wCqNuxHSIoqsR52odUAHMM_Rcri9dOaSVmBxLPMVYGqbjwAkZy8cSEkm4vRphx5gm1L3nYaJPB9SCbZW9bAJSciE-OJRgBnX2btqH6TajNA0DA5XqBN0OHkw22c17bokW9ebtMqFz8/s1600/users-not-filtered.png" height="438" width="640" /></a></div>
<br />
<br />
Now, filtered users are gone (AFTER the ACL Expression is enabled)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF9uTv-h-hYbMfjwSSsETS32aCsyOEJhzdVWhme9nMo1nF3PZxSrzQJkGl16OXtSp4XQSotmNl7FLt9wJsmVEXXNziOxwKjpT5BE3ivXj9vFRlsxrHbFsQF6mGeyhMEgUOu2h7dJL4xHY/s1600/users-filtered.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF9uTv-h-hYbMfjwSSsETS32aCsyOEJhzdVWhme9nMo1nF3PZxSrzQJkGl16OXtSp4XQSotmNl7FLt9wJsmVEXXNziOxwKjpT5BE3ivXj9vFRlsxrHbFsQF6mGeyhMEgUOu2h7dJL4xHY/s1600/users-filtered.png" height="424" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
There you have it.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: red; font-size: large;">Next Step:</span> Play around with the application and apply more filtering options to the controllers and services on your own! You may learn more <a href="http://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/el-access.html" rel="nofollow" target="_blank">here</a>.</div>
<br />
That's it. Now that you have successfully secured in fine-grained'ly manner, it is time to do something even more exciting like having a multi-tenanted web application. Until next time....<br />
<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/14769628992288331352noreply@blogger.com0Kuala Lumpur, Federal Territory of Kuala Lumpur, Malaysia3.139003 101.686854999999922.885326 101.36413149999993 3.3926800000000004 102.00957849999992tag:blogger.com,1999:blog-4393185392805226480.post-25790633239836981912014-06-12T19:03:00.001-07:002014-06-13T01:54:57.156-07:00Setting up Spring MVC flavor of AppFuse 3.0.1-SNAPSHOT stack in Eclipse IDE<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Hello again! I was lucky enough to review some of the web application stacks and have found AppFuse Stack a comprehensive starter kit with well-written tutorials to continue with. I have used them in couple of projects in past successfully especially with Spring MVC Flavor and I thought I would write some tutorials dedicated to this Stack. To learn more on AppFuse, <a href="http://appfuse.org/display/APF/AppFuse+QuickStart" rel="nofollow" target="_blank">click on</a>.<br />
<br />
In this tutorial, I will show in <span style="color: #0b5394;"><b>5 steps</b></span> to generate, import and start up Spring MVC flavor of AppFuse ready for development in your Eclipse IDE with the following pre-requisites:<br />
<br />
1. <a href="http://www.eclipse.org/downloads/" rel="nofollow" target="_blank">Eclipse IDE</a> (JUNO or later) with m2e plugin installed.<br />
2. <a href="http://maven.apache.org/download.cgi?Preferred=ftp://mirror.reverse.net/pub/apache/" rel="nofollow" target="_blank">Maven 3.x</a><br />
3. MySQL 5.x<br />
4. JDK 7.x<br />
5. An awesome Macbook Pro on Maverick OSX or whatever OSX Version you currently have.<br />
6. and of course Internet Connection<br />
<br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;"><b><span style="color: #0b5394;">Step 1:</span> </b></span>Generate your choice of stack with AppFuse QuickStart<br />
If you have read <a href="http://appfuse.org/display/APF/AppFuse+QuickStart" rel="nofollow" target="_blank">AppFuse QuickStart</a> and chosen your stack as Spring MVC you will end up with the following command line to generate your stack.<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-spring-archetype -DarchetypeVersion=3.0.1-SNAPSHOT -DgroupId=com.mycompany -DartifactId=myproject -DarchetypeRepository=http://oss.sonatype.org/content/repositories/appfuse</span><br />
<br />
Go ahead and paste them into you chosen working (workspace) folder in the command line window.<br />
It will goes on generating about sometimes and mostly downloading the required java libraries.<br />
Once done, depending your choice of "ArtifactId" a folder with that name will be created. In this case, "<span style="font-family: "Courier New",Courier,monospace;">myproject</span>". <br />
<br />
[INFO] project created from Archetype in dir: /Users/hamid/Documents/workspace/myproject<br />
[INFO] ------------------------------------------------------------------------<br />
[INFO] BUILD SUCCESS<br />
[INFO] ------------------------------------------------------------------------<br />
[INFO] Total time: 2.162s<br />
[INFO] Finished at: Fri Jun 13 08:54:43 MYT 2014<br />
[INFO] Final Memory: 18M/228M<br />
[INFO] ------------------------------------------------------------------------<br />
<br />
<span style="color: #0b5394;"><br /></span>
<span style="font-size: large;"><span style="color: #0b5394;"><b>Step 2:</b></span> </span>Generate Full Source (Service Layer modules - models, daos, managers, tests) of your stack<br />
I like my stack as verbose as possible especially when it comes to service layer and AppFuse has plugin called appfuse to do as such. Now that you have generated your stack, navigate to "<span style="font-family: "Courier New",Courier,monospace;">myproject</span>" folder in your command line tool and executed the following command:<br />
<span style="font-family: "Courier New",Courier,monospace;"><br />mvn appfuse:full-source</span><br />
<br />
During this process you will see the following output to confirm that your service layer is being generated...<br />
<br />
[INFO] --- appfuse-maven-plugin:3.0.0:full-source (default-cli) @ myproject ---<br />
[INFO] [AppFuse] Installing source from data-common module...<br />
[INFO] [AppFuse] Installing source from hibernate module...<br />
[INFO] [AppFuse] Installing source from service module...<br />
[INFO] [AppFuse] Source successfully exported, modifying pom.xml...<br />
[INFO] [AppFuse] Adding dependencies from root module...<br />
<br />
<span style="color: #0b5394;"><span style="font-size: large;"><b>Step 3:</b> </span></span>Import into Eclipse IDE<br />
Importing into Eclipse is easy, go ahead startup your eclipse IDE.<br />
Now that your IDE is ready, click on <i>File -> Import -> Maven -> Existing Maven Projects -> [Browse to your project folder with Browse button] -> Finish</i></div>
<br />
Yep I know, the are some errors, we will get to that in the next steps.<br />
<span style="color: #0b5394;"><span style="font-size: large;"><br /></span></span>
<span style="color: #0b5394;"><span style="font-size: large;"><b>Step 4: </b></span></span>Quick and dirty way clearing off the errors in Eclipse IDE<br />
I have identified few errors in the imported maven projects and let clear them one by one:<br />
<span style="background-color: red;"><span style="background-color: white;"></span><br /></span>
<span style="background-color: white;">1. JavaScript Source error - Exclude them!</span><br />
Navigate to "Include Path" from your project.<br />
Right Click on your project root <i>myproject -> Properties -> JavaScript -> Include Path</i>.<br />
Then under "Source" tab, select "Excluded:" and then click "Edit" button.<br />
Add "src/main/webapp/scripts" folder in the "Exclusion Pattern" using Add -> Browse button.<br />
<br />
2. Replace the "ne" to != in src/main/webapp/decorators/default.jsp file<br />
<br />
3. pom.xml error<br />
Enclose <plugins>..</plugins> node with <pluginManagement> element, like the following:<br />
<br />
<pluginManagement><br />
<plugins><br />
....<br />
</plugins><br />
</pluginManagement><br />
<br />
4. sample-data.xsd error<br />
Open the same file of src/rest/resources/sample-data.xsd in your favorite text editor (mine is textmate),<br />
select all, copy and paste them in the same file in your IDE.<br />
<br />
Rebuild your project with Project -> Clean or if you have the "Build Automatically" selected, your project should been instantenously re-built and the errors should have been gone.<br />
<span style="color: #0b5394;"><span style="font-size: large;"><br /></span></span>
<span style="color: #0b5394;"><span style="font-size: large;"><b>Step 5: </b></span></span>First run of your stack<br />
Now that the errors have disappeared, it is time to maiden run of your stack.<br />
before that, just make sure your MySQL 5.x Server is installed and running<br />
In the command line window execute the following:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">mvn jetty:run</span><br />
<br />
for, the eager beavers who don't want to wait for all tests to be completed, you may run with skipped test as the following:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">mvn -Dmaven.test.skip=true jetty:run</span><br />
<br />
<span style="color: red;"><span style="font-size: large;"><b>Next : </b></span></span>Continue on your development...<br />
Extends the stack with exciting frameworks such as Spring Security ACL for fine-grained access to your web resources or whatever your have in mind.<br />
<br />
That's it! I hope you have had a perfect run of your first stack and until next time...</div>
Anonymoushttp://www.blogger.com/profile/14769628992288331352noreply@blogger.com0Klang Valley, Malaysia3.1949981622622916 101.714172363281252.9413211622622915 101.39144886328125 3.4486751622622918 102.03689586328125tag:blogger.com,1999:blog-4393185392805226480.post-84147655537790855182014-06-01T04:31:00.000-07:002014-06-01T04:35:50.752-07:00JRebel 5.5.3 + JBoss EAP 6.1 + Eclipse Juno + Maven 3 + Jboss-as Plugin<div dir="ltr" style="text-align: left;" trbidi="on">
<div>
I was excited to be handed over a 14 days extension on JRebel licence as the previous 14 days trial license was doomed to expire by misconfiguration in my project's springframework. Glad that one of the JRebel online representative was kind enough to grant my wish. I really need this trail licence before I bleed my wallet of USD365 for single user licence, anually. This decision was after all my attempts on JRebel alternative were unsatisfactorily successful. </div>
<div>
<br /></div>
<div>
I did search around the web and found DCEVM and HotswapAgent (<a href="https://github.com/HotswapProjects/HotswapAgent">https://github.com/HotswapProjects/HotswapAgent</a>). </div>
<div>
I did try the latest binaries for jdk1.7/jdk1.8 (<a href="https://github.com/dcevm/dcevm">https://github.com/dcevm/dcevm</a>) and jdk1.6 soylatte (<a href="http://landonf.bikemonkey.org/static/soylatte/">http://landonf.bikemonkey.org/static/soylatte/</a>).</div>
<div>
Those binaries work just fine but, as claimed, it was limited to existing class swap and etc. </div>
<div>
furthermore I need patched jdk1.6 with the latest update which soylatte are not (update 3) and I am hopeless with building my own binary. As for the HotswapAgent, it look very promising with Spring context reload but hibernate was not getting session manager or something and I don't have much time to investigate. Probably I will when I have time to spare.</div>
<div>
What feature I really in dire need is the ability to reload Spring and hibernate context flawlessly. JRebel did very well as seen in the videos. I am impressed. and then there goes my weekends in front of my macbook.</div>
After tirelessly spending my hours of my weekends on JRebel setup, finally got JRebel working with Jboss EAP 6.1!<br />
<div>
<br /></div>
<div>
I was targetting to get all these setup working:</div>
<div>
<div>
A. Embedded Jetty 8.x (local)</div>
<div>
B. Embedded Jetty 8.x (remote)<br />
C. Jboss EAP 6.1 (local)</div>
<div>
D. Jboss EAP 6.1 (remote) </div>
</div>
<div>
<br />
Currently I've gotten A, B and C working properly. As of now, I am positive I will nail the remote Jboss. Wait till I nail down my next target, I will lay out the steps to get them working, of course if above stuff are in interest of anyone, otherwise it would just be my own note which I hope to save hours of my time in the future.</div>
<div>
<div>
<br /></div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/14769628992288331352noreply@blogger.com0