tag:blogger.com,1999:blog-17703406908262144232024-03-05T15:29:00.578+01:00Web Application DeveloperEverything about developing web applications in Java.Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.comBlogger64125tag:blogger.com,1999:blog-1770340690826214423.post-34835148581739248632015-04-08T14:49:00.000+02:002015-04-08T14:49:19.873+02:00Testing Google Task Queues<a href="https://cloud.google.com/appengine/docs/java/taskqueue/" target="_blank">Google Task Queues</a> are a great way to have snippets of code be executed at a later time. They can be used to spread application load, or to have some task executed at a programatically provided timestamp. The API is easy to understand and use, and Google provides <a href="https://cloud.google.com/appengine/docs/java/tools/localunittesting#Java_Writing_task_queue_tests" target="_blank">an easy way to Unit test your code</a>.<br />
<br />
So far so good! This works perfectly when you use the default queue. If you want to use a non-default queue, however, there's a catch. The documentation prescribes that you just point your <b>LocalTaskQueueTestConfig</b> to the <i>queue.xml </i>file, and that's it. That is indeed all there is to it, but only if you have the XmlParser on your classpath (org.mortbay.xml.XmlParser). If it is not there, add this dependency to your POM:<br />
<br />
<code>
<dependency><br />
<groupid>com.google.appengine</groupid><br />
<artifactid>appengine-tools-sdk</artifactid><br />
<version>${appengine.target.version}</version><br />
</dependency>
</code>
<br />
<code><br /></code>
This provides the XmlParser you need!Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com1tag:blogger.com,1999:blog-1770340690826214423.post-10080714811002821272014-06-24T15:49:00.000+02:002014-06-24T15:49:00.586+02:00Summer of Technology 2014 @ContributeA new summer, a new <a href="http://summeroftechnology.eu/" target="_blank">Summer of Technology</a>! As <a href="http://webapplicationdeveloper.blogspot.be/2013/06/summer-of-technology-contribute.html" target="_blank">tradition prescribes</a>, there's an interesting workshop/session every Tuesday of the summer. I will be hosting a session on Google's Cloud platform, but there's a lot of other topics as well.<br />
<br />
<a href="http://summeroftechnology.eu/" target="_blank">Pick your session and subscribe!</a>Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-58359266414318185832014-02-04T08:40:00.000+01:002014-02-04T08:40:04.331+01:00XPath in Internet ExplorerEvery web developer knows how difficult it is to get things running on all browsers. Usually, Internet Explorer is doing the best it can to make your life a hell. A good example thereof, is it's lack of XPath support.<br />
<br />
In most browsers, you can use <i>document.evaluate()</i> to pass an XPath expression, and get a result. In Internet Explorer, however, this method just doesn't work. No error message, no result, just some unexpected behavior in your application. Luckily, there's an easy solution that doesn't require you to rewrite your code, or implement some ugly <i>if IE</i> hacks.<br />
<br />
The solution is called <b>Wicked Good Xpath</b>, and is an open source project maintained by Google. It's easy to use, and doesn't interfere with your existing code. You can find <a href="https://code.google.com/p/wicked-good-xpath/" target="_blank">everything you need here</a>.<br />
<br />
Basically, all you have to do is download the .js file, and add it to your page through <i>script </i>tags.<br />
<br />
<pre class="brush:javascript"><script src="wgxpath.install.js"></script>
</pre>
<br />
Then you have to call <b>wgxpath.install() </b>from your JavaScript code, and the <i>document.evaluate()</i> function will be available.Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-22726301598378572332013-10-24T13:41:00.002+02:002013-10-24T13:41:38.465+02:00Setting a timeout on an Apache CXF webservice callIn this short post, I'll provide the code for setting a timeout on a webservice call. The client has been generated by Apache CXF 2.6.1, and the webservice is accessed by an HTTP call.<br />
<br />
<pre class="brush:java">Client client = ClientProxy.getClient(yourPortType);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(5000);
httpClientPolicy.setReceiveTimeout(5000);
httpConduit.setClient(httpClientPolicy);
</pre>
<br />
You should add this chunk of code before you call the method on <i>yourPortType</i>. The <b>connectionTimeout</b> is how long it may take to connect to the service, the <b>receiveTimeout </b>is how long it may take for the webservice to respond.<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-63482151615536776512013-09-11T10:27:00.001+02:002013-09-11T10:27:47.607+02:00Web Accessibility CourseAttention fellow web developers! Google is giving a <a href="https://webaccessibility.withgoogle.com/preview" target="_blank">free online course</a> to improve the accessibility of your website/application. While this might not seem like a big issue, the World Health Organization estimates the number of people with visual impairments to be 285 million. You can save them from a lot of frustration, and offer a far better user experience by following a few guidelines.<div>
<br /></div>
<div>
Making your site more user friendly to blind or low vision people doesn't have to be 'a pain in the ass'. It should come naturally, with a minimum of extra effort. Google will provide techniques and tools, as well as expert guidance to make the world wide web a slightly better place, one site at a time.<br /><div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-73226980676260252632013-06-27T14:30:00.000+02:002013-06-27T14:30:18.675+02:00Summer of Technology @ContributeJust like <a href="http://webapplicationdeveloper.blogspot.be/2012/05/summer-of-technology-contribute.html" target="_blank">last year</a>, Contribute organizes a '<i>Summer of Technology</i>'. The concept is as simple as it is nice: free one-day workshops for everyone interested. If you're a developer, architect, ... or just a technology enthusiast, take a look at the sessions we're organizing, and register for the ones that you're interest in.<br />
<br />
You'll find the full overview at the Contribute website: <a href="http://www.contribute.be/sot">http://www.contribute.be/sot</a><br />
<br />
Topics range from Oracle Forms over BigData/NoQSL to version control. Every tuesday, this summer!Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-67393871063321506432013-06-14T08:07:00.000+02:002013-09-03T07:36:05.908+02:00Eclipse cannot run program javaw.exeYesterday, I checked out a project from SVN, I ran <i>mvn eclipse:eclipse</i> and imported it into my IDE. So far so good, everything compiled, Maven could run all the tests, all was well.<br />
<br />
But then I tried to run a JUnit test in Eclipse. I kept getting a strange error about Eclipse not being able to run javaw.exe in my project-folder. After some Googling, I found that the underlying error that causes this problem, was of an entirely different nature: Windows has a character limit to command line statements. And since Eclipse assembles the classpath itself to pass it on as a launch parameter, the command line character limit got violated.<br />
<br />
I now knew what was causing the error, but fixing it didn't seem that simple. I tried to remove all unnecessary libraries (there weren't a lot), but the problem persisted. So I changed to drastic measures: I moved my Maven repository to a folder directly at my <b>C:\</b> disk. The path was about 30 characters shorter than before, but since Eclipse was adding a whole lot of Maven libraries to my classpath, it made a huge difference.<br />
<br />
After that, I could run my JUnit test without any problems. I suppose I'm safe for now, but what will happen when we add even more libraries to the project? It's possible that at a given point, the classpath will be too long for even the shortest possible repo-path you can get. And then what? Switching to Linux could be an option, but during my quest to solve this problem, I also read that IntelliJ has better support for this. So going there could be an option too. Or I could just write/wait for an Eclipse plugin that deals with this problem...Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-67711163935668503992013-03-22T08:00:00.001+01:002013-03-22T08:00:52.132+01:00Belgium Liferay User GroupSince the Liferay community is ever growing, there are user groups being developed. One of them, is <a href="http://www.liferay.com/community/user-groups/belgium/welcome" target="_blank">BeLiUG (Belgium Liferay User Group)</a>. If you're a Liferay enthusiast, and are based in Belgium, request your membership today!<br />
<br />
Of course, if you're not based in Belgium and want to join a Liferay User Group, <a href="http://www.liferay.com/community/user-groups" target="_blank">search for the one in your country</a> and apply. The idea of <a href="http://en.wikipedia.org/wiki/Users'_group" target="_blank">User Groups</a> is to get together on a regular basis to talk about certain aspects of the product. It's a great way to meet new people, and to learn a few things about a technology you like.Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-79975875460567094182013-03-06T21:02:00.000+01:002013-03-20T11:07:32.694+01:00Custom internationalized error messages in Spring MVC + JSR303A very common thing to do when building an application, is using JSR303 validation annotations on your domain classes. In a Spring MVC controller, those annotated fields will get validated when calling a ResuestMapping method with an @Valid parameter. You can then easily show the generated errors in your Spring MVC form.<br />
<div>
<br /></div>
<div>
So far so good. Only drawback is that Spring has some default messages. Which are clear, but usually not what you want in your frontend pages. Luckily, there's an easy way to override the defaults with custom messages!</div>
<div>
<br /></div>
<div>
<b>NOTE:</b> This small guide assumes you're using Spring MVC's Internationalization in a correct way, <a href="http://viralpatel.net/blogs/spring-3-mvc-internationalization-i18n-localization-tutorial-example/" target="_blank">as described here</a>. </div>
<div>
<br /></div>
<div>
Ok, so overriding the messages. Actually, it's fairly easy. If you want to override each and every message for <i>@NotEmpty</i>, you add 1 entry to your messages.properties file:</div>
<div>
<br /></div>
<div>
<code>NotEmpty = This is the new default message for all NotEmpty annotations</code></div>
<div>
<br /></div>
<div>
Easy huh? Now if you want to be more specific, you can override the message for (for example) every firstname that is <i>@NotEmpty</i>:<br />
<br />
<code>NotEmpty.firstname = This is the new default message for NotEmpty annotations on firstname-fields</code></div>
<br />
This will override the default message for every field named <b>firstname</b>. But you can even be more specific! You can define an error message for a specific field in a specific class. If you have an Employee class, with a firstname field that is annotated with @<i>NotEmpty</i>, you can specify a default message like this:<br />
<br />
<code>NotEmpty.employee.firstname = This is the new default message for the NotEmpty annotation on the firstname-field in our Employee class</code> <br />
<br />
There's one huge point of attention, though. The pattern of your message has to resemble the SPeL-pattern you'd use to access the field. Usually, the <i>@Valid</i> annotation will be on a command object. That means that in this case, our command object has to be named "employee" on the Model. If, however, you have named your command "command", you'll have to change the message key to this:<br />
<br />
<code>NotEmpty.command.firstname = This is the new default.</code><br />
<br />
It's a pitfall, and one you can lose a lot of time with!Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-18819994057424548062012-12-04T10:54:00.000+01:002012-12-04T10:54:42.692+01:00Liferay: beta languagesIf you have used the internationalization built in in Liferay, you might have noticed if you hover over the flags, the name of the languages appears. You also might have noticed, the name indicates the language is 'in beta'. If you want to get rid of this, you can write a hook (or extend a hook you already have).<br />
<br />
Of course, you need to know what page you have to adjust. The display of the language-portlet is located in <i>$LIFERAY_HOME$/tomcat-version/webapps/ROOT/html/taglib/ui/language/page.jsp</i>. Copy the page in your hook, and somewhere near the bottom, you'll find following code:<br />
<br />
<pre class="brush:java">if (LanguageUtil.isBetaLocale(locales[i]))
{
message = message + " - Beta";
}</pre>
<br />
Remove it, and the beta indication is gone!Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com2tag:blogger.com,1999:blog-1770340690826214423.post-72634485064659760042012-12-03T14:32:00.000+01:002012-12-03T16:11:27.175+01:00Special character encodingIf you have ever created a custom language bundle, you'll know special characters can be very annoying. When they're not displaying correctly, but instead showing a diamond with a question mark or a white rectangle, it's sometimes difficult and frustrating to find the origin of the problem.<br />
<br />
When you're building a website that has to come with a language with a lot of special characters (French, German, ...), you can run these encoding problems. In fact, there only has to be one of those special characters anywhere in your site, and it'll be messed up. When working with resource bundles (<b>.properties</b> files), I've found that these few steps often resolve a lot of issues, so try to follow these simple guidelines.<br />
<br />
<ul>
<li>Make sure your general encoding is set to UTF-8. In Eclipse, you do this in <i>Window -> Preferences -> General -> Workspace</i></li>
<li>Each file can have a seperate encoding as well. Check the properties of your <b>.properties</b> files. In Eclipse, you do this by <i>right-clicking</i>, then selecting <i>Properties</i>. Under <i>Resource</i>, you can set the encoding to UTF-8.</li>
</ul>
<div>
Redeploy your application with this correct settings, and your problems should dissolve! Bear in mind, though, that if you had an incorrect encoding first, switching to the correct encoding may break your file and replace the special characters by the 'not found' characters (diamond or rectangle). Check your file before deploying!</div>
Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-68507156547149075052012-10-25T10:05:00.000+02:002012-10-25T10:05:44.096+02:00Liferay: authorization of actions on dynamic data lists<br />
Another feature you might want to include in your dynamic data list template, is that the edit button is only shown to users of a certain role. This, again, requires some thinking and trying, but I have done it for you. What I did, was get all the roles for the current user (through the user id in the request's theme display).<br />
<blockquote class="tr_bq">
#set ($user_id = $request.theme-display.user-id)<br />
<br />
#set ($roles = $serviceLocator.findService("com.liferay.portal.service.RoleLocalService").getUserRoles($getterUtil.getLong($user_id)))</blockquote>
Now, we can loop the roles, and set a variable if the user has a certain role.<br />
<blockquote class="tr_bq">
#set ($can_edit = 'false')<br />
<br />
#foreach ($role in $roles)<br />
#if ($role.name == 'Administrator')<br />
#set ($can_edit = 'true')<br />
#end<br />
#end</blockquote>
Later in the template, we can than use the <i>$can_edit</i> variable to conditionally <a href="http://webapplicationdeveloper.blogspot.be/2012/10/liferay-dynamic-data-lists-record.html" target="_blank">display the edit link</a>.<br />
Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-5828178759454490342012-10-23T15:22:00.000+02:002013-02-01T13:01:55.638+01:00Liferay: dynamic data lists record actionsI'm still working with Liferay 6.1, and more specific their dynamic data lists. A question I've encountered a lot, and just ran into, is how to display the action buttons of a record in a custom list template. I haven't found the answer online, so I started to try some things myself.<br />
<br />
I figured the solution would be a lot like in <a href="http://webapplicationdeveloper.blogspot.be/2012/10/liferay-dynamic-data-list-detail.html" target="_blank">my previous post</a>: using the generated URL. I again switched back to the default list view, and copied the URL for the '<i>Edit</i>' action. Stripping it down, this is the result:<br />
<blockquote class="tr_bq">
/your_page?p_p_id=169_INSTANCE_ToH96dipcgdr&struts_action=%2Fdynamic_data_list_display%2Fedit_record&cmd=update&redirect=%2Fyour_page&recordId=$record.getRecordId()</blockquote>
Notice the <i>p_p_id</i> is copied from the URL (you can also get it from the <i>$request</i>), while the record id is dynamically fetched from the resultset's current record. Another important parameter is <b>redirect</b>. Provide it with the URL of the page you're going to display your list on. It will make sure the user will return to that page after saving or canceling the edit action. If you forget this, the user is stuck on the edit page.Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com3tag:blogger.com,1999:blog-1770340690826214423.post-91369019559957041502012-10-17T16:36:00.002+02:002012-10-25T10:06:02.718+02:00Liferay: dynamic data list detailI've been working with Liferay 6.1's dynamic data lists for the last few days. I like how easy it is to create a CRUD system for data lists. The out-of-the-box functionality to display lists using the Liferay defaults and a custom VM-template is amazing.<br />
<br />
To display a detail of a record, however, is a lot more painful. For some reason, there's no VM-template support there. So what I wanted to do, was the following:
<br />
<ul>
<li>Create a detail link in the list VM-template</li>
<li>Let the detail page display my own custom page</li>
</ul>
<div>
Not all that much asked, I'd think, yet this was <i>NOT</i> easy to achieve in Liferay. The documentation in this area is very limited, and basically only covers the creation of a list-template. So, first things first, I created my custom list-template using <a href="http://www.liferay.com/es/documentation/liferay-portal/6.1/user-guide/-/ai/make-it-pretty-creating-custom-displa-1" target="_blank">the Liferay documentation</a>, and my dynamic data list looked good.</div>
<br />
<div>
Of course, I wanted links in that list, to click through to the details of a record. This was the first difficulty I encountered. I couldn't find any clues or documentation on how to get the correct link. So what I did, was switching the list view back to 'default', and copied the link URL there. It looked really, really ugly.</div>
<br />
<div>
I then started to dissect that URL. I concluded that there's lot of parameters I didn't need, so I stripped it down to the bare minimum: the portlet ID, a struts action and a record ID. The portlet ID and struts action can be copied from the URL the default list provides, the record ID is dynamic and can be fetched using <b>$record.getRecordId()</b>. My URL looked like this:</div>
<br />
<blockquote class="tr_bq">
/your_page?p_p_id=169_INSTANCE_ToH96dipcgdr&struts_action=%2Fdynamic_data_list_display%2Fview_record&recordId=$record.getRecordId()</blockquote>
This of course redirects to the default detail page, which might be OK for adding and editing records, but not for displaying them in an enterprise application. I somehow had to either edit the detail page, or find a way to redirect the detail-link to another page.<br />
<br />
That was the second obstacle. Editing the detail-page wasn't really an option, since it would then be altered for <i>ALL</i> detail pages of all records, not just the ones I wanted to display at that time. With that idea out of the way, I had to find a way to make the detail URL redirect to a custom JSP. Therefor, I had to create a new struts action, and map it to a new JSP I also had to create.<br />
<br />
The easiest way to do that is using a <a href="http://www.liferay.com/documentation/liferay-portal/6.0/development/-/ai/hooks" target="_blank">hook</a>. In that hook, we need to do 3 things:<br />
<br />
<ul>
<li>Create an Action class (extending from BaseStrutsPortletAction)</li>
<li>Create a custom JSP</li>
<li>Map the Action class to a certain path</li>
</ul>
<div>
The last one is the easiest: simply add this to your liferay-hook.xml</div>
<pre class="brush:xml"><struts -action="-action">
<struts -action-path="-action-path">/dynamic_data_list_display/view_office</struts>
<struts -action-impl="-action-impl">be.c4j.hook.action.SomeAction</struts>
</struts>
</pre>
This means you have to change the <i>struts-action</i> parameter in your detail-url to <b>%2Fdynamic_data_list_display%2Fview_office</b>. Of course, we also need to define the SomeAction class.<br />
<br />
<pre class="brush:java">import com.liferay.portal.kernel.struts.BaseStrutsPortletAction;
import com.liferay.portal.kernel.util.ParamUtil;
import javax.portlet.PortletConfig;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
import com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalServiceUtil;
public class SomeAction extends BaseStrutsPortletAction {
@Override
public String render(PortletConfig portletConfig, RenderRequest renderRequest,
RenderResponse renderResponse) throws Exception {
long recordId = ParamUtil.getLong(renderRequest, "recordId");
DDLRecord record = DDLRecordLocalServiceUtil.getRecord(recordId);
renderRequest.setAttribute("ddlRecord", record);
return "/portlet/dynamic_data_lists/view_office.jsp";
}
}
</pre>
<br />
Now all you have to do is build the JSP. Make sure you place in the folder $customs_jsps$\html\portlet\dynamic_data_lists. In the JSP you can access the <i>ddlRecord</i> attribute.
<br />
<br />
<pre class="brush:java"><%
DDLRecord record = (DDLRecord)request.getAttribute("ddlRecord");
%>;
This is a field of our record<%= record.getFieldValue("fieldName") %>;
</pre>
<br />
If you know what to do, it isn't all that hard, but it took me a lot of time to figure this out. Liferay offers a lot of out-of-the-box functionality, but sometimes you have to go through a lot of trouble for adding just that little extra.Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-39402485989314820002012-10-04T19:35:00.000+02:002012-10-08T11:19:35.559+02:00Oracle Open World - thursdayLast day of the conference... Not a lot of sessions today (only 1 and the Java community keynote), but we've subscribed to a trip to Oracle HQ this afternoon. We're getting a tour in their usability labs.<br />
<br />
But first things first. I started my day with the Java community keynote. It was mainly about innovation, and some cool demos of robots (by Perrone Robotics) were given. In the end, <a href="http://en.wikipedia.org/wiki/James_Gosling" target="_blank">James Gosling</a> entered the stage and showed us what he is currently doing: Liquid Robotics. Medium-sized robots that roam the seas and gather data.<br />
<br />
Then I went to an ADF session by Eugene Fedorenko. He took us through the process of developing an ADF application. During his '<i>deep dive</i>', he showed us how to programatically create entities and view objects, end display them on the screen. I found it a bit odd to do everything programatically, instead of using the declarative strength of the framework, but I'm sure that in some cases this will turn out to be the best way.<br />
<br />
On to Redwood City then. Oracle took us on a tour in their usability labs. They showed us how their apps are tested and evaluated using some advanced eye-reading techniques. An interesting afternoon, as closure for a very interesting conference. I learned a lot, saw some very nice demos and met interesting people. All in the lovely setting of San Francisco.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgEZ2rb3Fsmp_qx4Tga_aOzIw4teK83Tk58u5XA-FIg2Iim0aoePlUL-dGZkIXHXheaph_H5ORm7tmA9pcF_NHemEUKQNKR01mqGQYrq3zHb4ZffCghlKzOfyM-AgTw1OuufWuvL8huQQ/s1600/DSC02300.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgEZ2rb3Fsmp_qx4Tga_aOzIw4teK83Tk58u5XA-FIg2Iim0aoePlUL-dGZkIXHXheaph_H5ORm7tmA9pcF_NHemEUKQNKR01mqGQYrq3zHb4ZffCghlKzOfyM-AgTw1OuufWuvL8huQQ/s320/DSC02300.JPG" width="320" /></a></div>
<br />Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0San Francisco, Californië 94103, Verenigde Staten37.7749295 -122.419415537.6745235 -122.577344 37.8753355 -122.261487tag:blogger.com,1999:blog-1770340690826214423.post-58822632821712781532012-10-03T23:32:00.002+02:002012-10-08T10:00:36.679+02:00Oracle Open World - wednesdayAnother day in San Francisco! Today's sessions are mainly about deveoping apps in the cloud, but there's also some ADF and an ADF Meetup tonight. I saw my early morning session about Java Heap and memory usage cancelled, so I used the extra time to go running in a San Francisco where the sun was just coming up. Lovely!<br />
<h2>
Develop apps with Oracle database cloud services (Rick Greenwald)</h2>
<div>
This session was presented to us by Rick Greenwald, director of Projectmanagement at Oracle Cloud. It didn't really tell me anything new. It was more of an APEX session than a cloud DB session. Rick gave a demo of an APEX application, running in the cloud.</div>
<div>
<br /></div>
<div>
One thing I noticed, though, was that the Oracle cloud DB only supports 1 schema. And that it's expensive. <a href="https://cloud.oracle.com/mycloud/f?p=service:database_pricing:0:::::" target="_blank">Pricing </a>is $175 a month (for 5GB storage, 50GB would be $2000 a month). If you consider it includes everything (license, server, support, ...), it's not all that much, but if you take into account you can get a 5 GB MySQL cloud database, $175 is quite a lot. There's also a data transfer limit of 6 times your storage. Rick however told us that they will be monitoring the traffic (to avoid DOS attacks), but won't undertake any immediate action upon exceeding.</div>
<div>
<br /></div>
<div>
Another issue is that when you want to access your database from outside Oracle cloud, you'll have to use RESTful services. SQLDeveloper has a cloud connector built in these days, so you can still easily connect to your database. But if you want to connect another application (not running in Oracle cloud) to your cloud database, you need to expose your queries to REST web services. We were shown this is quite an easy process, though, but you really don't want to do this for larger applications.</div>
<div>
<br /></div>
<div>
I think Oracle Cloud has a lot of potential, but also a lot of limitations. You'll be kinda forced to use a full Oracle stack if you want to have all the benefits. Of course, if you just intend to write an APEX application, one Oracle cloud database can work wonders.</div>
<h2>
Developing with cloud services (Chris Richardson)</h2>
<div>
Chris Richardson is the founder of Cloudfoundry. He presented a very nice session on using cloud services. He used an application he wrote as guidance through the session: VoteMeetEat.com. The concept is simple: you text the word 'register' to a certain number, you get a confirmation SMS with an URL, you subscribe to that URL and you're in the program. The idea is to find restaurants and friends nearby. Anyone can then vote on a restaurant of their choice, and a group of friends can meetup at the highest voted restaurant.<br />
<br />
To vote, you have to call a certain number, and based on your location it reads you the available restaurants. You vote by using your keypad. All participants receive a text message with the results. If you have to all write this by yourself, it would take months to get it done. And it would be a huge headache. So Chris takes advantage of cloud services, in this case for location, data and telephony.<br />
<br />
In the demo he gave, he showed the different services he used. As a database to store friends in, MongoDB was used. It has an integration with CloudFoundry, so it's easy to use. Then, to find the restaurants nearby, a 3rd party service named Factual was used. Based on the geolocation of your phone, the Factual API returns a list of restaurants, and their information.<br />
<br />
The most difficult part to setup and maintain yourself, though, is telephony. Setting up a database isn't all that difficult, but setting up your own telephony provider and maintaining it, doesn't sound like something you'd want to do yourself. And then we didn't even mention the complex protocols. So Chris has Twilio to do that for him. You talk HTTP to Twilio, Twilio handles all the complexity of the telephony. It's on a pay per use basis, so if your app is rather small, it's not all that expensive.<br />
<br />
The VoteMeetEat application is a very nice example of how cloud services can be used to make the life of the developer a lot easier. And to lower development , hardware and maintenance costs.</div>
Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0San Francisco, Californië 94103, Verenigde Staten37.7749295 -122.419415537.6745235 -122.577344 37.8753355 -122.261487tag:blogger.com,1999:blog-1770340690826214423.post-50524430064404023332012-10-02T19:22:00.000+02:002012-10-03T23:13:47.544+02:00Oracle Open World - tuesday<br />
This day, I have done a lot of sessions on something I've been waiting for for quite a while: <a href="http://www.oracle.com/technetwork/developer-tools/adf/overview/adf-mobile-096323.html" target="_blank">ADF Mobile</a>. I won't discuss each session seperately (since it's all on the same topic), but I'll just give my general view.<br />
<br />
First, it's worth noting that ADF Mobile really looks promising. The idea that you develop 1 application and then deploy it to different platforms, is really good. You build an app, then deploy it to Apple's App Store or Google's Play. Or both. Without having to deal with either Android specific stuff or Objective C. Pretty neat. Also, ADF Mobile makes sure your app is future proof. If Windows 8 turns out to be a huge hit, or any other OS that might appear in the future, ADF Mobile will have support for it.<br />
<br />
All of this is possible because of an HTML5-based user interface. Below that, ADF Mobile uses PhoneGap to acces the device specific services. Build once, deploy everywhere. I did an hands-on session today, where we built a simple ADF Mobile app and deployed it to both iOS and Android, and I must say it works pretty good. The look and feel is generally the same and all of the functionality you build in is available in both versions.<br />
<br />
Apart from that, I've seen quite a few demos on ADF Mobile. Or rather: demo. All presentations use the same demo app. I must admit, it looks definitely great, but seeing the same stuff over and over again gets dull after a while. Therefore I was very happy to see a real-world application demo by Infosys. They have built a mobile app using ADF Mobile for one of their customers. It's good to see the theory also appears to work in a real business usescase. The app also looked good, so I'm even more eager to get started with ADF Mobile myself now!Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0San Francisco, Californië 94103, Verenigde Staten37.7749295 -122.419415537.6745235 -122.577344 37.8753355 -122.261487tag:blogger.com,1999:blog-1770340690826214423.post-14014561163555948932012-10-01T18:00:00.000+02:002012-10-08T10:02:59.719+02:00Oracle Open World - monday<div>
This year, I have the privilege of going to one of the biggest conferences in the world: Oracle Open World. If you look at <a href="https://blogs.oracle.com/oracleopenworld/entry/oracle_openworld_by_the_numbers" target="_blank">the numbers</a>... they're pretty huge! During this week, I'll try to keep you posted on the most interesting sessions I followed. There'll be a short summary, and my personal thoughts and views.</div>
<br />
<h2>
Why should you switch to Java 7 (David Keenan, Staffan Friberg)</h2>
<h3>
Summary</h3>
The presentation was a summary of, as the title says, why you should switch to Java 7. I'll just sum them up again!<br />
<div>
<br /></div>
JCommands<br />
Garbage First<br />
Runtime compiler improvements<br />
Sockets Direct Protocol<br />
Performance benefits to<br />
<ul>
<li> Date</li>
<li> BigDecimal</li>
<li> Crypto</li>
<li> String to byte conversion</li>
<li> concurrency API</li>
<li> Hotspot JVM</li>
<li> PermGen</li>
<li> Internal strings</li>
<li> XML API</li>
</ul>
Backwards compatibility (source, binary, behavioural)<br />
Heap retuning<br />
<br />
<h3>
My thoughts</h3>
Not really a very innovating session, just a sum up of what's new in Java 7 and what's to come in Java 8. A good review, though, and makes you think of upgrading.<br />
<br />
<h2>
Future of development for Oracle Fusion (Chris Tonas)</h2>
<h3>
Summary</h3>
Chris gave a demo using ADF Faces. It was a typical ADF application with fancy graphs and components. Then he showed us the same app, but on an iPad. It had the same functionality, but HTML5 instead of Flash. It also had a slightly different layout and supported gestures and touch. The pagination in tables we so liked in ADF 10g has returned (in an im:proved way), to avoid scrollbars.<br />
<br />
He then talked about the iOS and Android SDK support in JDeveloper, and the visual preview of the app you're building. Apparantly, you build an ADF app once, and then deploy it to Android and/or iOS (and any other vendor Oracle decides to support). Pretty convenient! Further, Chris discussed offline support and gave an ADF Mobile demo. This time, it was a native iOS app, which I thought was pretty impressive.<br />
<br />
To end the Mobile part, Thomas Quilligan presented a real-life case. He is from Accenture, an ADF Mobile Beta Program Partner. It was nice to see the Oracle ADF Mobile technology being used in a real-life project.<br />
<br />
After that, we moved on to the Cloud part of the talk., with a strong focus on Developer Cloud Service. These are some of the out of the box services that the Developer Cloud offers:<br />
<ul>
<li style="text-align: left;">Source control</li>
<li style="text-align: left;">Maven support</li>
<li style="text-align: left;">Issue tracking</li>
<li style="text-align: left;">Continuous Integration (Hudson) </li>
<li style="text-align: left;">Wiki</li>
</ul>
<div>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEim3MBeEulC0fY9RN8ClE5NojAi_uZk6QnfmFlXuJx5jX_XUEj-Xek-64CSvnfAEzzBCHnUdEpP1wM4OEUAVjgb3L7oEvA8FCMEjKIMccD8MFwyWDc6yMaxjDD5KCxDOp4W3IwRUblltC0/s1600/DSC02295.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEim3MBeEulC0fY9RN8ClE5NojAi_uZk6QnfmFlXuJx5jX_XUEj-Xek-64CSvnfAEzzBCHnUdEpP1wM4OEUAVjgb3L7oEvA8FCMEjKIMccD8MFwyWDc6yMaxjDD5KCxDOp4W3IwRUblltC0/s320/DSC02295.JPG" width="320" /></a><br />
<br />
<br />
The demo of the Developer Cloud Service that followed, was very nice. It showed the full development lifecycle, all brought to the cloud, organized in neat dashboards.</div>
<br />
<br />
<br />
<br />
<br />
<br />
<h3>
My thoughts</h3>
<div>
This was a very nice presentation. The ADF Mobile still looks promising, and appears to be finally released soon. The cloud part really surprised me. I've been waiting for Oracle Cloud for quite a while now, but I didn't know they were going to offer something like the Developer Cloud. I really liked that. If it all integrates as well as in the demos, this will definitely be a product I'd want and like to use!<br />
<br />
<h2>
Oracle's public cloud strategy (Abhay Parasnis)</h2>
</div>
I'm writing an article about this session on <a href="http://www.cloudspring.com/" target="_blank">Cloudspring</a>. I'll update the link as soon as it gets published.<br />
<br />
<h2>
Classic mistakes with ADF (Frank Nimphius, Duncan Mills)</h2>
<div>
This was a nice light session about some of the most made errors with ADF. Driven by real examples and questions, Duncan and Frank guided us through. I'll add the slides as soon as they're available, since writing it all out seems a little pointless.</div>
<div>
<br /></div>
<div>
I'll just give a bit more details about one of the errors discussed. It's one we ran into as well, and Frank and Duncan categorized it as 'silent, but deadly' (as opposed to 'unforgiveable' and 'bear traps'). It's about using a bean that is not request scope, but that contains references to UI components. The problem here is that UI components only last as long as a request. They are therefore not serializable, and any bean with a scope higher than request, will want to serialize all it's variables.</div>
Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com2San Francisco, Californië 94103, Verenigde Staten37.7749295 -122.419415537.6745235 -122.577344 37.8753355 -122.261487tag:blogger.com,1999:blog-1770340690826214423.post-4612886366157161032012-09-25T12:24:00.000+02:002012-09-25T12:24:21.308+02:00Oracle ADF EssentialsOracle has released <a href="http://www.oracle.com/technetwork/developer-tools/adf/overview/adfessentials-1719844.html" target="_blank">ADF Essentials</a>: a free to develop and deploy core version of their Application Development Framework.<br />
<h4>
What is included in Oracle ADF Essentials?</h4>
According to the documentation, Oracle ADF Essentials includes the following Oracle ADF components: Oracle ADF Faces Rich Client Components, Oracle ADF Controller, Oracle ADF Model and Oracle ADF Business Components.<br />
<br />
The following functionality, however, is not included in Oracle ADF Essentials, and requires the full Oracle ADF version: Oracle ADF Mobile, Oracle ADF Desktop Integration, Oracle ADF Security, The Oracle ADF Web service data control, Oracle ADF remote taskflows, Oracle ADF Business Component’s Service Interfaces, Oracle ADF Data Controls for BI, Essbase and BAM, Integration with Oracle Fusion Middleware features such as MDS, OPSS, OWSM, Enterprise Manager and MBeans, High Availability and Clustering.<br />
<br />
All in all a good base to start from! We now await their cloud solution, so we can develop and deploy our ADF applications in the cloud.<br />
<br />Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com1tag:blogger.com,1999:blog-1770340690826214423.post-85906951324223697032012-09-25T09:36:00.001+02:002012-09-25T09:36:39.531+02:00Using Cloudbees behind a proxyAt work, we are sitting behind a proxy. This can be pretty annoying if you have to use services that require the internet, but don't rely on your internet settings. For example Maven, which can be configured using it's <i>settings.xml</i> file, or the Cloudbees SDK.<br />
<br />
That last one is a bit trickier to use behind a proxy. There is no obvious <i>settings.xml</i> or properties file where you can define your proxy server. The solution, however, is very simple. Go to your Cloudbees SDK root folder, and edit the <i>bees.bat </i>file. Change the JAVA_OPTS to the following:<br />
<blockquote class="tr_bq">
JAVA_OPTS=-Dbees.home=%BEES_HOME% -Dhttp.proxyHost=<your proxy host> -Dhttp.proxyPort=<your proxy port> -Xmx256m</blockquote>
Save the changes, and when you run the <i>bees</i> command from the console now, it will use your proxy settings. Easy as that!Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com3tag:blogger.com,1999:blog-1770340690826214423.post-58390790306841216152012-09-12T13:22:00.000+02:002012-09-12T13:22:25.423+02:00ADF analyzed by GartnerGartner has recently published their <a href="http://www.gartner.com/technology/reprints.do?id=1-1BU762S&ct=120827&st=sb" target="_blank">analysis of Oracle's Application Development Framework</a>. And while the general feelings towards ADF are rather hesitating, the Gartner conclusion is overall very positive. Of course, ADF is tightly coupled with Oracle's Fusion Middleware stack and JDeveloper (although an Eclipse plugin is available). But just because of those reasons, you can count on Oracle to continue developing and supporting ADF in the future.<br />
<br />
A special mention goes to the MetaData Services provided in Fusion Middleware. It's an engine that allows users to personalize their own web-experience. Much like portals intend to do, but then in 'a regular' web application. It allows runtime customization of the look-and-feel, per user, group of users or the entire application.<br />
<br />
Further, Gartner looks forward to the much anticipated <a href="http://www.oracle.com/technetwork/developer-tools/adf/overview/adf-mobile-096323.html" target="_blank">ADF Mobile</a>. They expect it to ship with the 12c release of ADF. As you could see <a href="http://webapplicationdeveloper.blogspot.be/2012/07/adf-sessions-at-oracle-open-world.html" target="_blank">earlier on my blog</a>, I'm attending OpenWorld this year, and I hope to see some more details about ADF Mobile there.<br />
<br />
So all in all a positive review of ADF. Let's hope customers also see the added value of the framework, and at least consider adapting it. Especially when an Oracle stack is already present, the step to start using ADF is not very big.Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com1tag:blogger.com,1999:blog-1770340690826214423.post-89457768979876389032012-08-16T10:51:00.000+02:002012-08-16T10:51:15.882+02:00Free Advanced ADF course - part 2As I <a href="http://webapplicationdeveloper.blogspot.be/2012/03/free-advanced-adf-course.html" target="_blank">mentioned earlier</a>, Oracle provides a free advanced ADF course. Today, Jürgen Kress <a href="https://blogs.oracle.com/emeapartnerweblogic/entry/learn_advanced_adf_online_for" target="_blank">announced on his blog</a> that part 2 is available! Here are the links to <a href="http://tinyurl.com/advadf-part1" target="_blank">part one</a> and <a href="http://tinyurl.com/advadf-part2" target="_blank">part two</a>.<br />
<br />
Good luck.Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-65717468887745299172012-07-23T08:58:00.000+02:002012-08-08T14:06:32.829+02:00Google DataStore with JPA and SpringI like Google App Engine. It's fast, reliable and free. It also comes with Google DataStore, a NoSQL solution to store data. The only problem is that it isn't that easy to use with the technology you want. We, for instance, wanted to use JPA and Spring. We've been struggling for a little while, but in the end, we managed to get all the right libraries. To make our life easier, we poured all those libraries in a Maven POM file, and made an archetype out of it. That way, we can just generate a new project from that archetype, and we're good to go!<br />
<br />
Follow these steps to get started (<i><b>You need Maven 3 to sucessfully run the app!</b>)</i><br />
<ul>
<li><a href="https://sites.google.com/site/stijnhaus/gae-wicket-archetype.7z" target="_blank">Download the archetype</a></li>
<li>Do a <i>mvn clean install</i> on the POM file</li>
<li>Generate the artifact using following code:</li>
</ul>
<div class="MsoNormal">
<blockquote class="tr_bq">
mvn archetype:generate -DarchetypeGroupId=be.c4j
-DarchetypeArtifactId=gae-wicket-archetype -DarchetypeVersion=1.0 -DgroupId=<b>be.c4j</b>
-DartifactId=<b>gaeproject</b> -DinteractiveMode=false</blockquote>
<ul>
<li>The parts in bold are what defines your projectname and default package</li>
<li>On the newly created project, do a <i>mvn gae:unpack </i></li>
<li>Now you can <i>mvn gae:run</i> your application</li>
<li>It's just a simple Wicket Hello World app, but it's a base to start from</li>
</ul>
<div>
This setup was made to prepare our <a href="http://www.contribute.be/sot" target="_blank">Summer of Technology</a> session. A lot of thanks go to Sebastian Van Sande for sorting out dependency issues and creating the archetype.</div>
<br />
<o:p></o:p></div>
<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com1tag:blogger.com,1999:blog-1770340690826214423.post-70832492543540807352012-07-18T13:50:00.000+02:002012-07-18T13:50:03.711+02:00Cloud IDEToday, I stumbled upon somtehing I've been searching for quite a while: an online IDE in the Cloud! No more need to install stuff on your PC, just develop anytime, anywhere you are. I discovered <a href="http://cloud-ide.com/" target="_blank">Cloud IDE</a>, where you can sign up for a free account. Moments later, your personal domain has been created and you can start developing!<br />
<br />
There are some very interesting options once you are logged in. You can link (a.o.) your <a href="http://www.cloudbees.com/" target="_blank">Cloudbees </a>and <a href="http://appengine.google.com/" target="_blank">Google App Engine</a> accounts. That way, you can easily create and deploy applications. There is a sample GWT project that you can import to Cloud IDE, and when your Google App Engine account has been linked, the new project is deployed within seconds. A lot of nice functionalities, all out of the box.<br />
<br />
Of course, there are also drawbacks. You need a relatively fast internet connection, but I guess that's not really an issue anymore these days. Further, the IDE isn't nearly as extended as Eclipse or IntelliJ. The 'develop in the cloud' concept is obviously still in its childhood, but it looks promising. There's GIT support, you can use Maven, create applications directly in your Cloud platforms, ... You can even collaborate on the same project with up to 5 users in the same domain.<br />
<br />
More features will be added, while gathering feedback from developers. I like the idea, but it's yet another IDE to get used to. I'm looking forward to playing around with it, and the ease of integration with PaaS providers is a big advantage for me. The Cloud is ever expanding!Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0tag:blogger.com,1999:blog-1770340690826214423.post-30992224620900477312012-07-16T09:35:00.003+02:002012-07-16T09:35:44.249+02:00ADF tip: RowIteratorAn ADF tip I can give you is the following: if you need a RowIterator multiple times, store it into an object. We've had an issue with getting it 2 times. Our application didn't give an error, would would appear to be busy forever, while not returning any results.<br />
<br />
This was our case:<br />
<blockquote class="tr_bq">
SomeVORowImpl someRow= (SomeVORowImpl)baseRow.getSomeVO().createRow();<br />
//Do something with row<br />
baseRow.getSomeVO().insertRow(someRow);</blockquote>
It would execute correctly (without errors), but the application would then hang. We've replaced the duplicate call to <i>baseRow.getSomeVO()</i> and stored it into a <b>RowIterator</b> object:<br />
<blockquote class="tr_bq">
RowIterator someVO = baseRow.getSomeVO();<br />
SomeVORowImpl someRow = (SomeVORowImpl)someVO.createRow();<br />
//Do something with row<br />
someVO.insertRow(someRow);</blockquote>
<div>
This did the trick. We haven't dug to the bottom of why this happened, but if we can reproduce this in a small test application, we might file a bug.<br />
<br />
<br />
<br /></div>Anonymoushttp://www.blogger.com/profile/12732896542700832051noreply@blogger.com0